对于主查询和自定义查询在此自定义主题中的工作方式有疑问吗?

时间:2014-07-27 作者:AndreaNobili

我是WordPress主题开发方面的新手,对PHP不太熟悉(我来自Java和C),在this custom theme

正如您在主页中所看到的,我首先显示了一个部分(名为Elifenza中的Articoli),其中包含了特色帖子(我使用了一个特定的标签实现了它),下面还有一个区域(名为Ultimi Articoli),其中包含了非特色帖子的最新帖子。

为此,我使用以下代码:

<section id="blog-posts">

<header class="header-sezione">
        <h2>Articoli in evidenza</h2>
</header>

<!--<?php query_posts(\'tag=featured\');?>-->

<?php
    $featured = new WP_Query(\'tag=featured\');

    if ($featured->have_posts()) : 
            while ($featured->have_posts()) : $featured->the_post();
            /*
             * Include the post format-specific template for the content. If you want to
             * use this in a child theme, then include a file called called content-___.php
             * (where ___ is the post format) and that will be used instead.
             */
                 get_template_part(\'content\', get_post_format());

             endwhile;
        wp_reset_postdata();
    else :
        // If no content, include the "No posts found" template.
        get_template_part(\'content\', \'none\');

    endif;
    ?>


<header class="header-sezione">
    <h2>Ultimi Articoli</h2>
</header>

<?php
// get the term using the slug and the tag taxonomy
$term = get_term_by( \'slug\', \'featured\', \'post_tag\' );
// pass the term_id to tag__not_in
query_posts( array( \'tag__not_in\' => array ( $term->term_id )));
?>

<?php
    if (have_posts()) :
        // Start the Loop.
        while (have_posts()) : the_post();

            /*
             * Include the post format-specific template for the content. If you want to
             * use this in a child theme, then include a file called called content-___.php
             * (where ___ is the post format) and that will be used instead.
             */
            get_template_part(\'content\', get_post_format());

        endwhile;
    else :
        // If no content, include the "No posts found" template.
        get_template_part(\'content\', \'none\');

    endif;
    ?>

</section>
它工作得很好,但我对这个解决方案的质量以及它的工作方式有一些怀疑。

要选择所有特色帖子,我使用这一行创建一个新的WP_Query 对象,该对象定义具有特定标记的查询featured:

$featured = new WP_Query(\'tag=featured\');
然后我使用其have_posts() 方法

因此,据我所知,这不是WordPress主查询,而是我创建的一个新查询。据我所知,当我想执行这种操作时,最好创建一个新查询(按原样),而不要使用主查询。

是真的,还是我错过了什么?如果这是真的,你能解释一下,为什么创建一个新的自定义查询而不修改Wordpress主查询更好?

好的,继续。我显示所有没有“特色”标签的帖子。要做到这一点,我使用以下代码段,相反,它修改了主查询:

    <?php
    // get the term using the slug and the tag taxonomy
    $term = get_term_by( \'slug\', \'featured\', \'post_tag\' );
    // pass the term_id to tag__not_in
    query_posts( array( \'tag__not_in\' => array ( $term->term_id )));
    ?>

    <?php
        if (have_posts()) :
            // Start the Loop.
            while (have_posts()) : the_post();
                get_template_part(\'content\', get_post_format());

            endwhile;
        else :
            // If no content, include the "No posts found" template.
            get_template_part(\'content\', \'none\');

        endif;
        ?>
所以我认为,这很可怕。这是真的吗?

UPDATE:

为了执行相同的操作,我找到了这个我添加到函数中的函数(在下面的伟大答案中)。php

function exclude_featured_tag( $query ) {
    if ( $query->is_home() && $query->is_main_query() ) {
        $query->set( \'tag__not_in\', \'array(ID OF THE FEATURED TAG)\' );
    }
}
add_action( \'pre_get_posts\', \'exclude_featured_tag\' );
此函数有一个钩子,该钩子在创建查询变量对象之后,但在运行实际查询之前调用。

因此,据我所知,它将一个查询对象作为输入参数,并通过选择不包括特定标记的所有帖子(在我的示例中是featured 标记柱)

那么,如何使用前面的查询(用于显示特色帖子的查询)和此功能来仅显示主题中的非特色帖子呢?还是必须创建新查询?

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

您实际的问题基本上是何时运行自定义查询以及何时使用主查询。让我们把它分成三部分

PART ONE

何时运行自定义查询(这不是最终列表)

创建自定义内容滑块

在页面中创建特色内容区域

第页的

  • 。如果需要显示帖子,请使用php模板

    如果您需要静态首页上的自定义内容,请点击

    显示相关、流行或信息帖子

    主查询范围之外的任何其他辅助或补充内容

    何时使用主查询。

    在上显示主要内容

    主页上的页面,以及在后端设置为博客页面的页面

    包括存档等模板的所有存档页面。php,类别。php,作者。php,分类法。php,标记。php和日期。php

  • UPDATE:在真实页面和静态首页上显示自定义内容(请参阅Using pre_get_posts on true pages and static front pages

  • PART TWO

    要选择所有特色帖子,我使用此行创建一个新的WP\\U查询对象,该对象定义了一个具有特定标签特色的查询:

    因此,据我所知,这不是WordPres主查询,而是我创建的一个新查询。据我所知,当我想执行此类操作时,最好创建一个新查询(按原样),而不要使用主查询

    对的这超出了主查询的范围。这是无法使用主查询创建的辅助或补充内容。你SHOULD ALWAYS 使用其中一个WP_Queryget_posts 创建自定义查询。

    NEVER USE query_posts 创建自定义查询,甚至任何其他查询。我的重点。

    Note: 此功能不适用于插件或主题。如后文所述,有更好、性能更好的选项来更改主查询。query\\u posts()是一种过于简单且有问题的方法,通过将页面的主查询替换为新的查询实例来修改它。它效率低下(重新运行SQL查询),并且在某些情况下会彻底失败(尤其是在处理POST分页时)。

    继续前进

    好的,接下来我将显示所有没有featured标记的帖子,为此,我使用此代码段,相反,它修改了主查询:

    query_posts( array( \'tag__not_in\' => array ( $term->term_id )));
    
    所以我觉得这很可怕。这是真的吗?

    这完全是错误的,不幸的是,你的说法是正确的。如前所述,NEVER 使用query_posts. 它运行一个全新的查询,这对性能不利,而且在大多数情况下,它会中断分页,而分页是主查询的一个组成部分,以便分页正常工作。

    这是您的主要内容,因此您应该将主查询与默认循环一起使用,它应该如下所示,这就是您所需要的

    <?php
        if (have_posts()) :
            // Start the Loop.
            while (have_posts()) : the_post();
    
                get_template_part(\'content\', get_post_format());
    
            endwhile;
        else :
            // If no content, include the "No posts found" template.
            get_template_part(\'content\', \'none\');
    
        endif;
    ?>
    
    您可以完全删除此部分,删除它,烧掉它,然后忘记它

    <?
    // get the term using the slug and the tag taxonomy
    $term = get_term_by( \'slug\', \'featured\', \'post_tag\' );
    // pass the term_id to tag__not_in
    query_posts( array( \'tag__not_in\' => array ( $term->term_id )));
    ?>
    
    好的,完成后,您将看到使用主查询和默认循环在主页中显示来自feature标记的帖子。

    从主页中删除此标记的正确方法是pre_get_posts. 这是proper way to alter the main query 还有你应该用的钩子always 用于更改主要内容循环。

    因此pre_get_posts 是正确的,这是您应该使用的功能。只有一件事,始终检查您是否不在管理页面上,因为pre_get_posts 也改变了后端。所以这是正确的代码functions.php 从主页中删除标记为特色的帖子

    add_action( \'pre_get_posts\', \'exclude_featured_tag\' );
    function exclude_featured_tag( $query ) 
    {
        if (    !is_admin() 
             && $query->is_home() 
             && $query->is_main_query() 
        ) {
            $query->set( \'tag__not_in\', [ID OF THE FEATURED TAG] );
        }
    }
    

    PART THREE

    将来有帮助的额外阅读材料

    结束

    相关推荐

    Getting page ID inside loop

    我有一个页面模板,它有一个循环来显示博客帖子。在回路内部get_template_part(\'content\', \'custom\') 函数包含显示博客文章内容的模板(content custom.php)。是否可以在其中获取当前页面IDcontent-custom.php 文件