据我所知,这是不可能的。如果您正在寻找一种优雅的方式,我建议您采用不同的方式:
只要可以,我不会在 Twig 中过滤帖子,而是在 PHP 中过滤帖子,然后再将帖子传递给模板。使用 Timber,您可以采用多种方式:
1.适配查询
为 WP_Query使用适当的参数,您通常可以只选择您需要的帖子。
$context['posts'] = Timber::get_posts( array(
'post_parent' => 0
) );
2.过滤查询结果
有时在 WP_Query 中使用大量参数会使您的查询变慢。出于性能原因,有时最好查询更多稍后使用 PHP 过滤的帖子。
$posts = Timber::get_posts();
$filtered = array();
foreach ( $posts as $post ) {
if ( $post->post_parent === 0 ) {
$filtered[] = $post;
}
}
$context['posts'] = $filtered;
或者
$posts = Timber::get_posts();
$posts = array_filter( $posts, function( $post ) {
return $post->post_parent === 0;
} );
$context['posts'] = $posts;
一个小警告:默认查询使用在设置 > 阅读 >博客页面最多显示的 WordPress 后端中定义的帖子数量。当您过滤返回的帖子时,您最终可能会收到比预期更少的帖子。
3.使用并覆盖默认参数
正如丹WP_Query
在评论中提到的那样,对于#1 ,如果一个在特殊页面上,则必须再次构建整个论点,例如存档页面。
要获取主查询使用的所有参数并用我们自己的参数覆盖它们以便稍后在 中使用它们Timber::get_posts()
,我们可以使用方便的wp_parse_args函数。我们将新参数作为第一个参数传递,主查询的查询变量作为要覆盖的默认参数。
global $wp_query;
// Set query args before posts are queried in get_context()
$args = wp_parse_args( array(
'post_type' => 'page',
'post_parent' => 0,
), $wp_query->query_vars );
$context = Timber::get_context();
$posts = Timber::get_posts( $args );
$context['posts'] = $posts;
4.使用pre_get_posts
动作钩子(WordPress方式)
调整主查询的默认 WordPress 方法是使用pre_get_posts
操作挂钩。虽然这可能是最干净的方式,但使用起来并不方便。
pre_get_posts
动作钩子需要在functions.php
. 如果您在任何模板文件(如 page.php 或 archive.php)中定义它,那就太迟了。这里的缺点是您必须使用条件($query->is_main_query()
等)来确保您所做的更改仅应用于有意义的地方。在查询中,您可以设置/重置要更改的查询变量。
// In your functions.php
add_action( 'pre_get_posts', function( $query ) {
if ( $query->is_main_query() && $query->is_front_page() ) {
$query->set( 'post_type', 'page' );
$query->set( 'post_parent', 0 );
}
} );
如果您可以在实际使用它们的模板文件中设置查询变量,则会方便得多。这就是为什么我更喜欢#3 而不是#4。我遇到了调试会话,其中我有一个奇怪的查询,直到我意识到有一个pre_get_posts
干扰。