博客首页通常会显示文章标题和内容(全部或部分),所以一页不能显示太多文章,否则会造成页面加载速度很慢,电脑配置不高甚至会导致浏览器死掉。但一页显示较多文章更利于用户寻找感兴趣的内容,这就是文章列表的作用。

目标:制作下面这样的文章列表模板(基于twentyeleven主题),分页使用WP-PageNavi插件实现,实际效果可以看本站文章列表

文章列表模板

 

创建一个page模板

新建一个.php后缀的文件,放在twentyeleven主题目录下,命名为page-articlelist.php,然后开始编辑文件。

创建page模板的第一步是写模板声明

<?php
/**
 * Template Name: Article List
 *
 */

这样在编辑页面的页面属性-模板下拉列表中就会有一个名叫Article List的模板可供选择。

配置文件

把一些可能更改的参数写在开头,作为配置文件,方便以后修改

$order_by = 'comment_count'; 

/** 升序还是降序,DESC表示降序,ASC表示升序 */
$order = 'DESC';

/** 每页显示多少篇文章 */
$posts_per_page = 10;

/**
 * 只显示或不显示某些目录下的文章,目录ID用逗号分隔,排除目录前面加-
 * 例如排除目录29和30下的文章, $cat = '-29,-30';
 * 只显示目录29和30下的文章, $cat = '29, 30';
 */
$cat = '-59';

查询文章列表的php代码

我们创建文章目录,是通过一个WordPress页面实现的,既然是页面,就有页面标题、页面内容等,我们不仅要输出文章列表,还要输出这个页面的内容,这样可以在列表之前添加一些自定义数据。

/** 获取该页面的标题和内容 */
global $post;
$post_title = $post->post_title;
$post_content = apply_filters('the_content', $post->post_content);

直接使用全局变量$post获取页面的标题和内容,接下来调用WP Query,全局变量将发生改变。

在调用WP Query之前还要知道当前是第几页,因为我们要制作带分页的文章列表模板。

$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;

获取文章列表

/** 用WP_Query获取posts */
$post_list = new WP_Query(
	"posts_per_page=" . $posts_per_page .
	"&orderby=" . $order_by .
	"&order=" . $order .
	"&cat=" . $cat .
	"&paged=" . $paged
);

获取文章总数

在这里,获取文章总数很容易,我们已经用WP Query查询到所需要的数据,要获取文章总数只需要调用下面的代码

$total_posts = $post_list->found_posts;

显示文章列表

文章列表数据(包括分页信息)已经通过上面的代码获取完成,接下来就要显示HTML代码了。

主体结构如下所示,这个结构是根据twentyeleven模板来的,你需要根据自己的模板修改这个结构。

<div id="primary">

	<div id="content" role="main">
	
		<h1 class="entry-title">页面标题</h1>
		
		<div class="entry-content">页面内容</div>
		
		<div class="entry-content">
			显示文章列表
		</div>
		
		分页代码
	</div>
	
</div>

将显示文章列表的位置加入输出循环的php代码

<?php if ( $post_list->have_posts() ) : ?>
	<div class="entry-content">
		<ul class="article-list">
		<?php while ( $post_list->have_posts() ) : $post_list->the_post(); ?>
			<li>
				<!-- 带连接的文章标题 -->
				<span class="post-title">
					<a href="<?php the_permalink(); ?>" title="<?php the_title(); ?>" target="_blank"><?php the_title(); ?></a>
				</span>
				<!-- 显示评论数 -->							
				<span class="post-comment"><?php comments_number( '', '1条评论', '%条评论' ); ?></span>
				<!-- 显示发布日期 -->
				<span class="post-date"><?php echo esc_html( get_the_date() ); ?></span>
	
			</li>
		<?php endwhile; ?>
		</ul>
		
		<!-- 用wp_pagenavi插件分页 -->
		<?php if ( function_exists('wp_pagenavi') ) wp_pagenavi( array('query' => $post_list) );  ?>
		
	</div><!-- .entry-content -->
	<!-- 文章列表显示结束 -->
						
<?php endif; ?>

重设主循环

如果你还希望继续输出属于当前页面的内容,例如评论框,就需要恢复一下主循环,因为下面这句代码将主循环变量替换成WP Query的结果了

<?php while ( $post_list->have_posts() ) : $post_list->the_post(); ?>

重置循环的代码如下

wp_reset_postdata();

这样我们就有了下面这样的文章列表

文章列表

样式是主题默认的,不太好看,可以稍微修饰一下

添加自定义脚本和样式表

该页面使用的脚本和样式表并不会用在其它页面,所以没必要将样式加到style.css中,定义一些只在该页面加载的脚本和样式即可。要加入自定义样式和脚本,在get_header()函数之前添加

<?php
/**
 * Template Name: Article List
 *
 */

/** 如果你需要为该页面引入自定义的脚本的样式表,写在这里,不需要自定义样式就删除下面两行代码 */
wp_enqueue_script( 'articleList', get_template_directory_uri() . '/articlelist.js' );
wp_enqueue_style( 'articleList', get_template_directory_uri() . '/articlelist.css');

get_header(); 

这样我就加入了一个名为articlelist.js的脚本和articlelist.css的样式表,这两个文件创建好放在主题根目录下即可。

目前只需要样式表,脚本可以先去掉。在样式表中加入一些样式,就可以变成下面的样子。

最终版

源代码下载

如果你有兴趣可以下载模板源代码

WordPress文章列表模板(基于twentyeleven) 已下载 1767 次

33条留言

  1. 您好,在页面某块区域如何调用 文章列表。请多多指教,非常感谢!

    1. 把上面的代码改成shortcode,再将shortcode插入文章即可。
      shortcode的用法参考文档https://codex.wordpress.org/Shortcode_API

      本文介绍的代码部分是跟模板相关的,需要去掉,具体来说从new WP_Query开始到wp_reset_query()之间的代码是你需要的。

  2. 谢谢分享!
    在每5篇文章中间加一条横线分割,列表页看起来更美观,该怎样实现?求指教

  3. 我这样写代码,调用的是所有分类的文章,分页不生效,是什么原因,请高人指点,

  4. 你好!
    确实蛮好用的,但是为什么只有第一页和第二页可以正常打开,后面的都的页面都是显示未找到页面。

    1. 我使用时没这个问题,你可以先把固定链接调到默认看看问题是否解决。

  5. 谢谢了,碰了个问题在网上转了好一会儿了,看完文章后有所启发。。。。。。

  6. HI, sola, 能不能实现单击标题后出现下拉的 文章摘要,如果真的想详细阅读,再点 read more.. 才进入文章呢?

    1. 用jquery实现很简单啊,模版一般都会输出摘要吧,你用jquery把摘要隐藏了,给标题绑定click事件,点击的时候显示摘要就行了啊

      1. 弄了好久…不知道怎么隐藏摘要,在外部能用toggle()实现对某个标签隐藏,显示,但是wordpress里就不行了;
        Sola能不能留个邮箱不?求指教

        1. WordPress里的jquery要用jQuery来代替$符号,你用对了吗
          装firebug,用控制台看js报错

  7. 您好,所有教程里面的文件都下载不了:-)

    1. 不会吧,我网站页面www.solagirl.net/sitemap一直用着,显示分页啊

    1. 如果要显示所有页面,改一下WP Query的查询参数post_type即可,默认是post,页面的话就是page

      $post_list = new WP_Query(
          "posts_per_page=" . $posts_per_page .
          "post_type=page" .
          "&orderby=" . $order_by .
          "&order=" . $order .
          "&cat=" . $cat .
          "&paged=" . $paged
      );
        1. 当然可以了,你可以参考一下WP Query文档,指定post__not_in参数就可以排除页面或者文章

  8. 下载链接失效。如方便,请提供,谢谢。

    1. 多谢提醒,貌似不小心把下载插件给禁用了,现在好了

  9. 《WordPress模板自带分页的文章列表》。是不是标题错了!

    1. 错了吗?没觉得啊,意思就是WordPress模板——带分页的文章列表

    2. 仔细读了一下你改的标题,你不会以为我说话大舌头吧:)

  10. 若想统计文章总数,但排除某分类文章数量,又该如何呢?

    1. 有三种方法

      1. 用WP Query

      $total_posts = new WP_Query( "posts_per_page=-1&cat=-59,-58,-4");
      echo 'Total posts:'. $total_posts->post_count;
      wp_reset_postdata();

      -59,-58,-4就是要排除的分类ID,前加负号,用逗号分隔

      2. 用get_posts

      $total_posts = get_posts('posts_per_page=-1&cat=-59,-58,-4');
      echo 'Total posts:'. count($total_posts);

      ID使用方法同上

      3. 用$wpdb执行自定义查询

      global $wpdb;
      //$exclude_ids定义要排除的分类ID,用逗号分隔
      $exclude_ids = '59,58,4';
      $sql = <<<SQL
      SELECT   COUNT(*) 
      FROM  {$wpdb->posts} 
      WHERE 1=1
      	AND post_type = 'post'
      	AND ( post_status = 'publish' OR post_status = 'private') 
      	AND {$wpdb->posts}.ID NOT IN (
      	  SELECT object_id
      	  FROM $wpdb->term_relationships
      	  WHERE term_taxonomy_id IN (
      	  	SELECT term_taxonomy_id 
      		FROM $wpdb->term_taxonomy
      		WHERE taxonomy = 'category'
      		AND ( term_id IN( {$exclude_ids} ) OR parent IN ( {$exclude_ids} ) )
      	  )
      	)
      SQL;
      $numposts = $wpdb->get_var($sql);
      echo 'Total posts:'. $numposts;

      对比

      前两种方法虽然函数不同但其实都调用了WP Query,文章越多消耗的内存越大,如果文章非常多前两种方法会很耗资源。

      第三种方法直接执行了自定义的SQL语句,基本不消耗什么内存,速度较快

        1. 对了,忘了告诉你,如果你是在文章列表中排除了某些分类,那获取文章总数有更简单的方法,直接这样就可以

          $total_posts = $post_list->found_posts;

          WP Query在查询的时候会顺带查询总数,如果已经查询了带分页的文章列表,用这种方法比第三种更好

  11. 此文早些出炉就会免掉很多麻烦了,嗯,话说你的文章列表的文章热度效果不错,具体如何实现的呢?

    1. 文章热度读取的是wp postviews插件的数据

评论功能已关闭