将参数添加到默认查询

时间:2015-06-25 作者:evu

我正在使用ACF创建索引的“特色”帖子部分。php和我很难从主查询中排除该帖子。

        <?php 

        $tmp = $posts;

        $isPaged = (get_query_var(\'paged\') == 0) ? false : true;

        $posts = get_posts(array(
            \'numberposts\'   => 1,
            \'post_type\'     => \'post\',
            \'meta_key\'      => \'featured_post\',
            \'meta_value\'    => true
        ));

        if( !$isPaged && !is_archive() && $posts ): ?>

            <?php foreach( $posts as $post ): setup_postdata( $post ) ?>

                <?php $excludeID = $post->ID; ?>

                ... html stuff ...

            <?php endforeach; ?>

            <?php wp_reset_postdata(); ?>

        <?php endif; ?>
然后我有$excludeID 我需要过滤掉帖子的ID,但我不知道如何添加posts_not_in 到主查询。如果这是一个自定义查询,我不会有任何问题,但如果可能的话,我想将其保留为默认查询。我试着用pre_get_posts 但我尝试的方式显然不是正确的方式,因为存在内存错误。

有类似的事情吗pre_get_posts 我可以用之前的主查询吗?

我不能只使用pre\\u get筛选出特色帖子,因为我只希望它显示最近的特色帖子,而其他所有帖子都会在主查询中正常显示。我也不能if post id == $excludeID 因为它会弄乱每页的帖子。我相信这是可能的,只是我还没有遇到过:)

谢谢

1 个回复
最合适的回答,由SO网友:Pieter Goosen 整理而成

我认为这里最干净的方法就是运行一个自定义查询,获取ID,然后使用post__not_in. 您还可以在函数中运行查询,然后在您的特色部分和中调用该函数pre_get_posts. 还有另一种方法,使用全局函数将ID从自定义查询传递到主查询,但您应该never 走这条路。你必须不惜一切代价避免创建globals,它们是邪恶的

请注意全局变量和变量,避免使用$posts, $post$wp_query 作为变量并向其分配自定义值。这三个是Wordpress使用的全局变量,其中包含主查询对象和主查询中的post对象。将任何其他自定义值赋给它会打断这些全局值。您唯一应该使用这些全局变量的时间是get_posts() 具有setup_postdata(). setup_postdata() 仅适用于$post 全局,任何其他全局名称都不起作用。这就是为什么你应该使用wp_reset_postdata() 在您的foreach 使用时循环setup_postdata() 重置$post 全局到主查询中的最后一篇文章

示例:

$q = get_posts( \'posts_per_page=1\' );
if ( $q ) {
    foreach ( $q as $post ) {
       setup_postdata( $post );
       // Run loop as normal with template tags
    }
    wp_reset_postdata();
}
现在,让我们看看眼前的真正问题。我们在这里要做的是创建一个函数,我们可以在我们的特色部分中使用它pre_get_posts.

以下代码未经测试,需要PHP 5.4以上版本。请根据需要随意修改)

function get_featured_custom_post( $main_query = false )
{
    /*
     * For the purpose of performance, I have created a variable called $main_query with a value of false
     * When we run this function in pre_get_posts, we just need the post id, nothing more. For this, our argumaents will change
     * The default is meant to return the complete post object, that is for the featured section
     */
    if ( $main_query == true ) {
        $fields = [\'fields\' => \'ids\'];
    } else { 
        $fields = [\'fields\' => \'all\'];
    }

    // Build our query arguments
    $defaults = [ 
        \'numberposts\'   => 1,
        \'post_type\'     => \'post\',
        \'meta_key\'      => \'featured_post\',
        \'meta_value\'    => true
    ];
    $args = wp_parse_args( $defaults, $fields ); 

    $q = get_posts( $args );

    return $q;
}
我们功能的价值get_featured_custom_post 将保存一个具有特征帖子id的数组或完整的帖子对象。现在,让我们使用它

在中pre_get_posts

add_action( \'pre_get_posts\', function ( $q ) 
{
    if (     $q->is_home() // Targets the home page only
         && $q->is_main_query() // Targts the main query only
    ) {
        // Get the post to exclude, remeber, we need id only, so set $main_query to true
        $exclude = get_featured_custom_post( true );
        if ( $exclude ) // Only set post__not_in if we have a post to exclude, otherwise the result might be unexpected
            $q->set( \'post__not_in\', (array) $exclude );
    }
});
在我们的特色部分中,我们可以使用以下功能

$q = get_featured_custom_post(); // We need the complete post object, so leave $main_query at default which is false
if ( $q ) {
    foreach ( $q as $post ) {
       setup_postdata( $post );
       // Run loop as normal with template tags
    }
    wp_reset_postdata();
}

结束

相关推荐

使用新的WP-Query()从循环中过滤后期格式;

嗨,我目前正在为我的博客构建一个主题。下面的代码指向最新的帖子(特色帖子)。因为这将有一个不同的风格比所有其他职位。然而我想过滤掉帖子格式:链接使用我在循环中定义的WP查询,因为它给我带来了更多的灵活性。我该怎么做呢? <?php $featured = new WP_Query(); $featured->query(\'showposts=1\'); ?> <?php while ($featured->have_post