为什么在pre_get_posts钩子中的is_main_query()在主循环中时不返回true()

我的主题内有一个index.php模板, 带有一个简单的while循环来显示帖子, 如下所示:

< section class="c-section overflow-hidden pt-0"> < div class="o-wrapper"> < ?php if ( have_posts() ) : $i=0; ?> < div class="row col-gutters pt-6"> < ?php while ( have_posts() ) : the_post(); ?> < div class="col-md-6 mb-3"> < ?php $thumb_id = get_post_thumbnail_id(); $cardDate = get_the_date(); $cardTitle = get_the_title(); $cardExcerpt = get_excerpt(); $cardLink = get_the_permalink(); $cardExternal = get_field('external_article'); $cardExternalLink = get_field('external_article_link'); $cardExternalSource = get_field('external_article_source'); include(locate_template('_components/card-newsroom.php')); $i++; ?> < /div> < ?php endwhile; ?> < /div> < ?php endif; ?> < /div> < /section>

我正在尝试使用functions.php中的pre_get_posts来修改显示的帖子数量, 并删除某种类型的帖子。
function remove_news_posts( $query ) { if ( $query-> is_main_query() & & !is_front_page() & & !is_page() & & !is_page_template() & & !is_search() & & !is_feed() & & !is_tax() & & !is_admin()) :$query-> set( 'meta_query', array( 'relation' => 'AND', array( 'key' => 'external_article', 'value' => 0, 'compare' => 'LIKE', ) )); $query-> set( 'posts_per_page', '6'); }add_action( 'pre_get_posts', 'remove_news_posts', 1000 );

但是-这不起作用。每页的帖子数不是6, 元查询也不影响显示的帖子。我有一个几乎相同的category.php模板, 并且pre_get_posts()过滤器确实可以在其中工作。如果我从pre_get_posts if语句中删除$ query-> is_main_query(), 它将正常工作。但这也会影响我不希望受到影响的其他查询(如侧边栏)。
当我希望is_main_query()返回true时, 为什么它不返回true?
#1因为在你的对帐单中检查是否不在首页上!
【为什么在pre_get_posts钩子中的is_main_query()在主循环中时不返回true()】你可以替换为:
if ( $query-> is_main_query() & & (is_home() || is_archive())){ ....

#2我终于想通了!有两件事发生:
  1. 模板层次结构。我的index.php文件实际上应该是home.php, 这是帖子索引页面的正确模板。参见此处:https://developer.wordpress.org/themes/basics/template-hierarchy/
  2. 一个过滤系统使用的是query_posts(), 它也修改了主查询。根据官方的WordPress文档, 不建议使用query_posts():” 此函数将完全覆盖主查询, 并且不打算由插件或主题使用。其过于简单的修改主查询的方法可能会出现问题, 应尽可能避免。” (请参阅https://developer.wordpress.org/reference/functions/query_posts/)
希望这会对外面的人有所帮助。干杯!

    推荐阅读