设置了 offset 参数时,page-navi 函数失效的解决办法

遇到的问题
在 WordPress WP_Query 参数中,有两个参数用到了 MySQL 的 offset 语句,一个是 paged,一个是 offset,paged 是为了实现分页,offset 是为了跳过某些文章不显示,如果这两个同时出现,会怎么样呢?答案是,offset 可以用,分页失效。
需要同时用到这两个参数的情况很少,常见的一种情况是在索引(也就是 WordPress 中的分类或标签存档页面)需要跳过前一篇或者几篇文章不显示,当然,在索引页面,分页也是需要的。
解决办法
要实现这种效果,我们就需要对 WordPres 分页功能动一下手脚了,我们主要通过以下两个 WordPress 钩子实现这个功能。
pre_get_posts:在 WordPress 查询允许之前,调整 WordPress 查询参数,在这里,我们需要用这个钩子保证 offset 参数只应用在第一页,
found_posts:允许我们调整 WordPress 文章查询结果总数量
第一步是使用 pre_get_posts 同时处理 offset 和分页,这个钩子把WordPress查询对象传递到自定义功能中,在自定义功能中,我们可以对查询对象进行修改。在下面的例子中,我们需要在WordPress 博客存档页面跳过前10篇文章。

add_action('pre_get_posts', 'myprefix_query_offset', 1 );
    function myprefix_query_offset(&$query) {

    //开始之前,确定我们在正确的位置
    if ( ! $query->is_posts_page ) {
        return;
    }
    //首先,定义需要跳过的文章数量
    $offset = 10;
    //下一步,获取设置中每页现实文章的数量
    $ppp = get_option('posts_per_page');
    //下一步,检测和处理分页
    if ( $query->is_paged ) {
        //手动确定查询偏移量(偏移量 + 当前页数 (减1) x 每页文章数)
        $page_offset = $offset + ( ($query->query_vars['paged']-1) * $ppp );
        //应用调整后的偏移量
        $query->set('offset', $page_offset );
    } else {
        //如果是首页,只设置偏移量就可以了
        $query->set('offset',$offset);
    }
}

OK,两个参数可以同时使用了,但是还存在一个问题,WordPress 计算总文章数量的时候,不会把跳过的文章考虑进入,比如我们数据库里面有 25 篇文章,每页显示 10 篇,如果没有偏移,分页数为 3,这是正常的,设置了偏移量之后,正确的分页数 2,事实是,如果我们不做进一步处理,WordPress 现实出来了分页仍然是 3,这时候如果点一下第三页,不出意外肯定是404 页面,因为现实的内容总共才 15 篇,这一页根本不存在。这个问题修复起来也很简单,请看下面的代码。

add_filter('found_posts', 'myprefix_adjust_offset_pagination', 1, 2 );
function myprefix_adjust_offset_pagination($found_posts, $query) {

    //定义需要跳过的文章的数量
    $offset = 10;

    //确保我们修改的是正确的查询对象
    if ( $query->is_posts_page ) {
        //用找到的文章数量减去偏移的文章数量... 
        return $found_posts - $offset;
    }
}

应该是类似的需求很小,所以 WordPress开发团队忽略了这个 “bug”,以上是 WordPress 官方给去的解决方案,当然,解决问题的办法不止一种,如果你有更好的解决方案,欢迎在评论中提出。

声明:本站资源绿色无后门无广告,可放心下载。如无特殊说明或标注,均为本站原创发布,转载请注明出处!