这是一个非常有趣的问题(我已经提出了这个问题,特别是针对您的方法和研究)。这里的大曲线球是查询的第一页:
我们将需要以某种方式“欺骗” WP_Query
类以完全偏移一页的偏移量返回帖子,并获得正确的页数,以免丢失查询中的最后一页
让我们看一下下面的想法,然后尝试将所有内容放入代码中。但是,在此之前,我想在此提出一些注意事项
重要笔记:
灯泡创意:
我们将需要什么
为了使一切正常,我们将需要以下内容:
分页是WP_Query
非常简单的几行代码
if ( empty($q['nopaging']) && !$this->is_singular ) {
$page = absint($q['paged']);
if ( !$page )
$page = 1;
// If 'offset' is provided, it takes precedence over 'paged'.
if ( isset( $q['offset'] ) && is_numeric( $q['offset'] ) ) {
$q['offset'] = absint( $q['offset'] );
$pgstrt = $q['offset'] . ', ';
} else {
$pgstrt = absint( ( $page - 1 ) * $q['posts_per_page'] ) . ', ';
}
$limits = 'LIMIT ' . $pgstrt . $q['posts_per_page'];
}
基本上会发生什么,一旦明确设置了偏移量,该paged
参数就会被忽略。将LIMIT
根据偏移量重新计算SQL 子句的第一个参数,该参数将是生成的SQL查询中要跳过的帖子数。
从你的问题,显然当设置offset
到0
,偏移查询失败,这是奇怪的,如下面的检查应返回true
if ( isset( $q['offset'] ) && is_numeric( $q['offset'] ) )
0
是有效数字,应返回true。如果您的安装上没有安装此软件,则应调试该问题
回到当前的问题,我们将使用相同的逻辑来计算和设置偏移量,以获取第2页上的第1个帖子,然后从中对查询进行分页。对于第一页,我们将不会进行任何更改,因此假定位于第1页的帖子仍将照常显示在页面上,我们只需要稍后“隐藏”它们,以免在页面上显示它们。 1个
add_action( 'pre_get_posts', function ( $q )
{
if ( !is_admin() // Only target the front end, VERY VERY IMPORTANT
&& $q->is_main_query() // Only target the main query, VERY VERY IMPORTANT
&& $q->is_cateory( 'news' ) // Only target the news category
) {
$current_page = $q->get( 'paged' ); // Get the current page number
// We will only need to run this from page 2 onwards
if ( $current_page != 0 ) { // You can also use if ( is_paged() ) {
// Get the amount of posts per page
$posts_per_page = get_option( 'posts_per_page' );
// Recalculate our offset
$offset = ( ( $current_page - 1) * $posts_per_page ) - $posts_per_page; // This should work on page 2 where it returns 0
// Set our offset
$q->set( 'offset', $offset );
}
}
});
您应该在第2页的第1页上看到相同的帖子。如前所述,如果没有发生,is_numeric( 0 )
则返回false(不应返回),或者您还有另一个pre_get_posts
尝试设置偏移量的操作,或者正在使用posts_*
子句过滤器(更具体地说是post_limits
filter)。这将是您需要自己调试的东西。
下一个问题是纠正分页,因为正如我之前所说,您将缺页。为此,我们需要将的值添加get_option( 'posts_per_page' )
到查询中找到的帖子数量中,因为我们会将查询偏移该数量。通过这样做,我们有效地添加1
了该$max_num_pages
属性。
add_action( 'found_posts', function ( $found_posts, $q )
{
if ( !is_admin() // Only target the front end, VERY VERY IMPORTANT
&& $q->is_main_query() // Only target the main query, VERY VERY IMPORTANT
&& $q->is_cateory( 'news' ) // Only target the news category
) {
$found_posts = $found_posts + get_option( 'posts_per_page');
}
}, 10, 2 );
除第一页外,这应该对所有内容进行排序。
现在所有(特别是@ialocin- 黄色潜水艇)
这都应该进入 functions.php
add_action( 'pre_get_posts', function ( $q )
{
if ( !is_admin() // Only target the front end, VERY VERY IMPORTANT
&& $q->is_main_query() // Only target the main query, VERY VERY IMPORTANT
&& $q->is_cateory( 'news' ) // Only target the news category
) {
$current_page = $q->get( 'paged' ); // Get the current page number
// We will only need to run this from page 2 onwards
if ( $current_page != 0 ) { // You can also use if ( is_paged() ) {
// Get the amount of posts per page
$posts_per_page = get_option( 'posts_per_page' );
// Recalculate our offset
$offset = ( ( $current_page - 1) * $posts_per_page ) - $posts_per_page; // This should work on page 2 where it returns 0
// Set our offset
$q->set( 'offset', $offset );
}
}
});
add_filter( 'found_posts', function ( $found_posts, $q )
{
if ( !is_admin() // Only target the front end, VERY VERY IMPORTANT
&& $q->is_main_query() // Only target the main query, VERY VERY IMPORTANT
&& $q->is_cateory( 'news' ) // Only target the news category
) {
$found_posts = $found_posts + get_option( 'posts_per_page');
}
return $found_posts;
}, 10, 2 );
第一页选项
这里有一些选择:
选项1
我很可能会选择这个选项。您要在此处创建一个category-news.php
(如果尚未执行此操作)。这是将在news
查看类别时使用的模板。这个模板将非常简单
例
<?php
get_header()
if ( !is_paged() ) { // This is the first page
get_template_part( 'news', 'special' );
} else { // This is not the first page
get_template_part( 'news', 'loop' );
}
get_sidebar();
get_footer();
如您所见,我包括了两个模板部分,news-special.php
和news-loop.php
。现在,这两个自定义模板的基础是:
news-special.php
->此模板部分将是您要在首页上显示的任何内容。在此处添加所有自定义静态信息。注意不要在此模板中调用循环,因为这会显示第一页的帖子。
news-loop.php
->这是我们将调用循环的模板。本节如下所示:
global $wp_query;
while ( have_posts() ) {
the_post();
// Your template tags and markup
}
选项2
category_template
当您查看news
类别的第一页时,使用您的静态内容创建一个单独的模板,只需使用过滤器即可使用此模板。另外,请确保不要在此模板中调用默认循环。另外,请确保此处的命名约定不会与模板层次结构中的模板名称冲突
我希望这是有用的。随意发表有疑虑的评论
编辑
多亏了OP,该WP_Query
班级中确实存在一个错误,请检查追踪票#34060。我发布的代码来自Wordpress v4.4,该错误已在此版本中修复。
我回到了bug所在的v4.3的源代码,并且可以确定将0
其设置为value时忽略offset
了该代码,因为代码只需检查offset
参数是否为empty
。0
在PHP中被视为空。我不确定是否仅在v4.3或所有以前的版本中找到此行为(错误)(根据票证,此错误在v4.3中),但是有此错误的补丁程序可以检查在火车票上。就像我说的那样,此错误在v4.4中已得到修复
return $found_posts;
在found_posts操作中的if语句之后。谢谢!