有很多关于如何更改主查询或添加辅助循环的好资源……
但我实际上想完全用一个不同的查询完全替换主查询。
我劫持了我的一个页面,本质上是作为类别页面提供服务。 (请注意,为了做到这一点,我正在从“页面”更改为“发布”。)但是当我通过这样做改变主查询时:
function front_page_announcements( $query ) {
if ( $query->query_vars['page_id'] == 84 && $query->is_main_query() && !$query->is_admin ) {
$query->set("category_name", "special-announcement");
$query->set("page_id", NULL);
}
}
add_action( 'pre_get_posts', 'front_page_announcements' );
我最终得到了数据库中的每一页(不是帖子)。 我真正想要的是每个帖子(而不是页面)的类别 ID 为 3
, 或者 special-announcement
就我而言。
我不想对数据库进行不必要的调用,所以看起来 pre_get_posts
动作挂钩是我想要的,但我无法弄清楚。 即使只是设定 $query = new WP_Query('cat=3')
似乎不起作用。
什么时候 'pre_get_posts'
被解雇后,WordPress 已经完成了很多事情,比如设置所有查询变量(还有你不发送的查询)和设置所有条件属性(所有 is_*
特性)。 所以,如果你想 完全地 替换查询你应该重置所有的东西并设置你自己的。
事实上,即使您的代码有效,WordPress 也会使用 page.php
作为模板。
然而,有一个更简单的方法:行动 前 WordPress 做所有的事情。
一个好的地方是 'request'
过滤器钩子,那时 WordPress 已经从 url 创建了查询变量,并将将该变量传递给 WP_Query
,并且您可以在发送之前拦截和更改查询参数。
该动作由 WP
类,并传递要设置的查询变量(参见代码)。
add_filter( 'request', function( array $query_vars ) {
// triggered also in admin pages
if ( is_admin() )
return $query_vars;
// you should check also for page slug, because when pretty permalink are active
// WordPress use 'pagename' query vars, not 'page_id'
$id = isset($query_vars['page_id']) && (int) $query_vars['page_id'] === 84;
// remember to replace "slug" with real page slug
$name = isset($query_vars['pagename']) && $query_vars['pagename'] === 'slug';
if ( ( $id || $name) && ! isset($query_vars['error']) ) {
$query_vars = array('category_name' => 'special-announcement');
}
return $query_vars;
});
代替 'slug'
与你的页面真正的 slug,然后让 WordPress 完成它的工作。
请注意,我没有检查主查询,因为 'request'
仅针对主查询触发。
如果你想使用特定的模板,你应该使用过滤器 template_include
否则 'category.php'
(或根据模板层次结构的正确模板)将被使用。
