随着网站内文章的数量越来越多,一个页面已经不能显示所有的文章,那么增加分页就是一个很实用的功能。文本就来研究以下如何通过代码的方式实现分页的功能。

函数介绍

如果你有兴趣,可以打开wp-includes文件夹下的link-template.php文件,里面定义了很多和链接有关的功能函数。我们主要使用以下几个函数:

get_pagenum_link

原型:get_pagenum_link($pagenum = 1)

获取指定页面($pagenum)的链接地址

previous_posts

输出或返回前一页的链接地址,如果当前是第一页,则输出或返回第一页的链接地址

原型:previous_posts( $echo = true )

该函数通过$echo决定是直接输出还是返回一个字符串,默认是直接输出。

以下两种方法的效果是一样的:

方法一:<a href=”<?php echo previous_posts(false); ?>”>上一页</a>

方法二:<a href=”<?php previous_posts(); ?>”>上一页</a>

next_posts

显示或返回下一页的链接地址,需要指定最大页面数。

原型:next_posts( $max_page = 0, $echo = true )

$max_page指定最大页面数,一般可通过$wp_query->max_num_pages获取。$echo的作用和previous_posts中echo的作用是一样的,决定是否直接输出字符串。

分页原理

以我们最常见的分页形式为例:有第一页和最后一页、上一页和下一页、中间是分页的页标,并尽量让当前页标处于中间。显示的页标个数可以根据需要设定,比如为show_pages(显示页标的个数)。

当前页面和最大页面数也很容易获取

//获取最大页面数
 $max_num_pages = $wp_query->max_num_pages;

 //获取当前页面标号
 $current = get_query_var('paged');

通过当前页面标号、最大页面数以及显示页标的个数,来计算起始页标(start)和结束页标(end)。

确定起始页和结束页

为了方便说明,我们用show_pages代表显示页标的个数、current代表当前页标号、start代表起始页标号、end代表结束页标号、max_num_pages代表最大页面数量。

一般情况下,为了使当前页标居中,我们可以让 start = current – show_pages / 2,如果计算出来的start < 1,那么就设置start = 1。

知道了起始页标,结束页标就很容易得出:

end = start + show_pages – 1

但是我们需要考虑到如果结束页标超过了最大页面数怎么办?

如果 end > max_num_pages ,则 end = max_num_pages

这样基本可以说起始页标和结束页标都已经确定了,但是还存在一个问题,如果当前页标是最后一页或最后几页的话,显示的页标数量就不会达到指定的页标显示数量。比如当前是最后一页,根据上面的算法就只能显示指定页标数的一半。为了解决这个问题,我们还需要对起始页标重新分配

既 如果end > max_num_pages 那么 end = max_num_pages,start = end – show_pages

最后再加个判断确保起始页不小于1

如果 start < 1 那么 start = 1

至此,起始页和结束页就确定好了。

输出整个分页模块

接下来就是对整个分页模块的输出,模块的最终样式需要结合CSS来完成,我们在输出的过程中需要注意分配class名。以下是整个输出的逻辑过程:

  1. 判断如果起始页标大于1,就显示“第一页”
  2. 判断如果当前页标大于1,就显示“上一页”
  3. 循环输出从起始页标到结束页标
  4. 判断如果当前页标小于最大页面数,就显示“下一页”
  5. 判断如果结束页标小于最大页面数,就显示“最后一页”

以下是我整个函数的源代码,并丰富了一些功能。在使用的过程中,你需要把下面这段代码复制到你当前正在使用的主题文件夹下的functions.php文件中,然后在需要输出分页模块的地方调用<?php dm_the_pagination(); ?>.

<?php
/*
 * 输出分页模块
 *
 * 作者:DDBug
 * 主页:http://domety.com
 *
 * 参数说明:
 * @ show_pages ,显示分布的数量,默认为10
 * @ first ,第一页的链接文本内容,默认为“第一页”
 * @ last , 最后一页的链接文本内容,默认为“最后一页”
 * @ pre , 上一页的链接文本内容,默认为“上一页”
 * @ next , 下一页的链接文本内容,默认为“下一页”
 * @ before_num , 每个页标号前的内容,默认为空
 * @ after_num , 每个页标号后的内容,默认为空
 * @ class , 整个分布模块的CSS样式类名,默认为"page-numbers"
 * @ current_class , 当前页标号的CSS样式类名,默认为"current"
 * @ 返回:无返回值,输出以下格式的内容:
 *  <ul>
 *   <li><a href="" title=""> 1 </a></li>
 *   <li><a href="" title="">...</a></li>
 *   <li><a href="" title=""> $current </a></li>
 *   <li><a href="" title="">...</a></li>
 *  </ul>
 *
 * 函数调用示例:
 *  dm_the_pagination("show_pages=5&before_num=[&after_num=]");
 * 将显示5个页标,显示的链接文本形式如下:
 *  第一页  上一页 [1] [2] [3] [4] [5] 下一页  最后一页
 */

 function dm_the_pagination($args = ''){
  global $wp_query;
 $default = array('show_pages' => 10,
  'first' => '第一页',
  'last' => '最后一页',
  'pre' => '上一页',
  'next' => '下一页',
  'before_num' => '',
  'after_num' => '',
  'class' => 'page-numbers',
  'current_class' => 'current');
 $r = wp_parse_args($args,$default);
 extract($r);

 /*
  * 计算起始页面和结束页面的页标
  */
 //获取最大页面数
 $max_num_pages = $wp_query->max_num_pages;

 //获取当前页面标号
 $current = get_query_var('paged');

 //一般情况下,为了使当前页标居中,起始页标=当前页标号-页标显示数量的一半
 $start = $current - intval($show_pages * 0.5);
 if( empty($current) || 0 == $current )
  $current = 1;
 if( $start < 1 )
  $start = 1;
 $end = $start + $show_pages - 1;
 if( $end > $max_num_pages ){
  $end = $max_num_pages;
  $start = $end - $show_pages + 1;
  if( $start < 1 )
   $start = 1;
 }

 /*
  * 输出各个页标
  */
 $output = '';

 // 如果起始页标大于1,就显示第一页的链接
 if( $start > 1)
  $output .= '<li><a href="'.esc_url(get_pagenum_link(1)).'" title="第一页">'.$first.'</a></li>';
 
 // 如果当前页面标号大于1,就显示上一页的链接
 if( $current > 1 )
  $output .= '<li><a href="'.previous_posts(false).'" title="上一页">'.$pre.'</a></li>';

 // 循环输出指定数目的页标链接
 for($i = $start; $i <= $end; ++ $i){
  $num_text = $before_num.$i.$after_num;
  if( $i == $current )
   $output .= '<li><a href="'.esc_url(get_pagenum_link($i)).'" title="第'.$i.'页">'.$num_text.'</a></li>';
  else
   $output .= '<li><a href="'.esc_url(get_pagenum_link($i)).'" title="第'.$i.'页">'.$num_text.'</a></li>';
 }

 // 如果当前页面标号小于总页面数,就显示下一页的链接
 if( $current < $max_num_pages )
  $output .= '<li><a href="'.next_posts($max_num_pages,false).'" title="下一页">'.$next.'</a></li>';
 
 // 如果结束页标号小于总页面数,就显示最后一页的链接
 if( $end < $max_num_pages )
  $output .= '<li><a href="'.esc_url(get_pagenum_link($max_num_pages)).'" title="最后一页">'.$last.'</a></li>';

 $output = '<ul>'.$output.'</ul>';

 echo $output;
 }

?>

下面是CSS样式示范

.page-numbers {
 float:right;
 padding:5px;
}
.page-numbers li{
 display:inline;
 padding:2px 5px;
}
.page-numbers li a{
 padding: 2px 5px;
 border:1px solid;
}
.page-numbers .current a{
 color:red;
}

其实wordpress已经提供了一个类似功能的paginate_links函数(wp-includes\general-template.php文件中定义),不过对于自定义的固定链接,使用起来还有点不方便,待俺再做研究之后再和大家分享。