总的来说,我同意Howdy\\u McGee的观点,即除非绝对必要,否则应该避免覆盖主查询-通常情况下,使用类似\'pre_get_posts\'
钩子是解决这种情况的更好的方法。
手动覆盖全局$wp_query
如果不非常小心,可能会导致各种意外行为,包括破坏分页等。从本质上讲,这是一种与经常受到批评的query_posts()
函数,其中the WordPress Code Reference notes:
此函数将完全覆盖主查询,不供插件或主题使用。它修改主查询的过于简单的方法可能会有问题,应该尽可能避免。在大多数情况下,有更好、更高性能的选项来修改主查询,例如通过WP\\u查询中的“pre\\u get\\u posts”操作。
然而,在这种情况下,如果您需要:
同时访问主查询和辅助查询的不同内容和/或conditional tags
一种通用实现,类似于可重用的模板部分,可应用于主查询或任何自定义查询,然后一种解决方案是存储“上下文”WP_Query
实例,并调用WP_Query
\'s在该变量上的条件方法,而不是使用其全局可用的条件标记函数对应项(它们总是显式引用主查询,global $wp_query
).例如,如果您希望“上下文查询变量”引用自定义帖子类型的单一模板和存档模板中的自定义二次查询,my-custom-post-type
, 但在其他情况下,请参考主查询,您可以执行以下操作:
Theme\'s functions.php
file, or a plugin file:
function wpse_232115_get_contextual_query() {
global $wp_query;
static $contextual_query;
// A convenient means to check numerous conditionals without a bunch of \'||\' operations,
// i.e "if( $i_need_a_custom_query )"
if( in_array( true,
[
is_singular( \'my-custom-post-type\' ),
is_post_type_archive( \'my-custom-post-type\' )
]
) ) {
// Create the contextual query instance, if it doesn\'t yet exist
if( ! isset( $contextual_query ) ) {
$query_args = [
//...
];
$contextual_query = new WP_Query( $query_args );
}
return $contextual_query;
}
return $wp_query;
}
"Generic" template-part files:
$query = wpse_232115_get_contextual_query();
// Contextual Query loop (loops through your custom query when \'my-custom-post-type\'s
// are being displayed, the main $wp_query otherwise.
if ( $query->have_posts() ) : while ( $query->have_posts() ) : $query->the_post();
// Tags dependent on The Loop will refer to the contextual query if The Loop
// was set up with the "$query->" prefix, as above. Without it, they always
// refer to the main query.
the_title();
// The global conditional tags always refer to the main query
if( is_singular() ) {
//... Do stuff is the main query result is_singular();
}
// Conditional methods on the $query object reference describe either
// the main query, or a custom query depending on the context.
if( $query->is_archive() ) {
//... Do stuff if the $query query result is an archive
}
// End the loop
endwhile; endif;
我不确定这是否是最好的解决方案,但这是我解决问题的方式。