这是一个非常有趣的问题(我对这个问题投了赞成票,特别是针对你的方法和研究)。此处的大曲线球是查询的第一页:
无法将查询设置为返回0 第一页上的帖子
通过将每个页面的页面内容上移一页,您将失去最后一页,因为查询仍然只有相同数量的帖子,因此$max_num_pages 财产仍将保持不变
我们需要以某种方式“欺骗”WP_Query 类以正确返回偏移量为一页的帖子,并获得正确的页数,以避免查询中的最后一页丢失
让我们看看下面的想法,并尝试将所有内容都放在代码中。然而,在此之前,我想提出几点意见
重要提示:所有内容都未经测试,因此可能有问题。确保在启用调试的情况下在本地测试此功能
该代码至少需要PHP 5.3,低于5.3的任何版本都会导致致命错误。注意,如果您仍在使用PHP 5.5以下的任何版本,那么您早就应该升级了
根据您的具体需要,在您认为合适的情况下修改和滥用代码
灯泡理念:
WHAT WE WILL NEED
为了使一切顺利进行,我们需要以下方面:
当前正在查看的页码
在posts_per_page 阅读设置中的选项集
自定义offset
修改$found_posts 属性来更正$max_num_pages 所有物
分页是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 参数被忽略。SQL的第一个参数
LIMIT 子句将根据偏移量重新计算,并将是生成的SQL查询中要跳过的帖子数。
从你的问题来看,显然是在设置offset 到0, 偏移量查询失败,这很奇怪,因为下面的检查应该返回true
if ( isset( $q[\'offset\'] ) && is_numeric( $q[\'offset\'] ) )
0是有效数字,应返回true。如果在安装中没有这样做,则应调试该问题
为了回到手头的问题,我们将使用相同的逻辑来计算和设置偏移量,以获得第2页的第1篇文章,并从那里对查询进行分页。对于第一页,我们不会更改任何内容,因此假定在第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 过滤器)。这将是您需要自己调试的东西。下一个问题是更正分页,因为正如我前面所说的,您将缺一页。为此,我们需要增加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 );
这应该对所有内容进行排序,除了第一页。这些都应该functions.phpadd_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 );
首页选项这里有几个选项:OPTION 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 类,检查trac ticket #34060. 我发布的代码来自Wordpress v4。4,该错误在此版本中已修复。
我回到了v4的源代码。3,bug在哪里,我可以确认0 设置为值时忽略offset 因为代码只是检查offset 参数为empty. 0 在PHP中被视为空。我不确定这种行为(bug)是否只在v4中找到。3或在所有以前的版本中(根据票据,此错误在v4.3中),但此错误有一个补丁,您可以在trac票据中查看。正如我所说,这个bug肯定在v4中得到了修复。4.