用 new WP_Query 查了一组文章,想给它加分页——直接调 the_posts_pagination()?
不行。那个函数默认算的是主查询的页数,跟你的自定义查询没关系。
得自己算。
WP_Query 对象上有两个属性:
$q->max_num_pages:总共几页;$q->found_posts:总共几篇。分页要用的是第一个。比如每页 10 篇、共 35 篇,max_num_pages 就是 4。
分页链接里的“第几页”,从 URL 里读。用 get_query_var('paged'):
$paged = max( 1, (int) get_query_var( 'paged' ) );
注意 max(1, ...):首页时 get_query_var('paged') 返回 0,要兜底成 1,不然算出来是第 0 页。
$q = new WP_Query( array(
'posts_per_page' => 10,
'paged' => $paged,
) );
不传 paged,查出来的永远是第一页。
用 paginate_links():
if ( $q->max_num_pages > 1 ) {
echo paginate_links( array(
'total' => $q->max_num_pages,
'current' => $paged,
'base' => get_pagenum_link( 1 ) . '%_%',
'format' => 'page/%#%/',
) );
}
三个参数:
total:总页数(用 $q->max_num_pages);current:当前页(用 $paged);base + format:拼 URL 的规则,一般照抄就行。<?php
$paged = max( 1, (int) get_query_var( 'paged' ) );
$q = new WP_Query( array(
'posts_per_page' => 10,
'paged' => $paged,
'post_status' => 'publish',
) );
?>
<?php if ( $q->have_posts() ) : ?>
<ul>
<?php while ( $q->have_posts() ) : $q->the_post(); ?>
<li><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li>
<?php endwhile; ?>
</ul>
<?php
echo paginate_links( array(
'total' => $q->max_num_pages,
'current' => $paged,
'base' => get_pagenum_link( 1 ) . '%_%',
'format' => 'page/%#%/',
) );
?>
<?php endif; wp_reset_postdata(); ?>
自定义查询做分页,访问第 2 页时常常 404。原因是 WordPress 只按主查询判断“这一页存不存在”,你的自定义查询页数它不知道。
解决办法是在 pre_get_posts 里把主查询也改成一样(推荐),或者手动处理 404(复杂,不推荐)。
所以一般建议:能用主查询 + pre_get_posts 解决的,就别用自定义查询做分页。
一句话记住:自定义 WP_Query 分页,要自己传 paged、自己用 max_num_pages 算总页数、自己调 paginate_links;分页 404 就说明主查询没跟着改。
下一篇讲 wp_reset_postdata——什么时候必须调,不调会怎样。