Algumas dúvidas sobre como a consulta principal e a consulta personalizada funcionam nesse tema personalizado?

20

Sou bastante novo no desenvolvimento de temas para WordPress e não gosto muito de PHP (vim de Java e C #) e tenho a seguinte situação neste tema personalizado

Como você pode ver na página inicial, primeiro mostro uma seção (denominada Articoli in evidenza ) contendo as postagens em destaque (eu a implementei usando uma tag específica) e abaixo dela existe outra área (denominada Ultimi Articoli ) que contém a post mais recente essa não é a postagem em destaque.

Para fazer isso, eu uso este código:

<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>

Funciona bem, mas tenho algumas dúvidas sobre a qualidade desta solução e como exatamente ela funciona.

Para selecionar todas as postagens em destaque , eu uso esta linha que cria um novo WP_Queryobjeto que define uma consulta com a tag específica featured:

$featured = new WP_Query('tag=featured');

Então, eu itero neste resultado da consulta usando seu have_posts()método

Portanto, pelo que entendi, essa não é a consulta principal do WordPress, mas é uma nova consulta criada por mim. Pelo que entendi, é melhor criar uma nova consulta (como concluída) e não usar a consulta principal quando desejar executar esse tipo de operação.

É verdade ou estou faltando alguma coisa? Se for verdade, você pode me explicar, por que é melhor criar uma nova consulta personalizada e não modificar a consulta principal do Wordpress?

Ok, continuando. Eu mostro todas as postagens que não têm a tag 'em destaque'. Para fazer isso, eu uso esse trecho de código, que, pelo contrário, modifica a consulta principal:

    <?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;
        ?>

Então eu acho que isso é horrível. É verdade?

ATUALIZAR:

Para fazer a mesma operação, encontrei esta função (na grande resposta abaixo) que adicionei a functions.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' );

Essa função possui um gancho chamado após a criação do objeto variável de consulta, mas antes da execução da consulta real.

Então, pelo que entendi, ele pega um objeto de consulta como parâmetro de entrada e o modifica (na verdade filtra) selecionando todas as postagens, exceto uma tag específica (no meu caso, a featuredtag posta)

Então, como posso usar a consulta anterior (aquela usada para mostrar as postagens em destaque) com esta função para mostrar apenas as postagens não em destaque no meu tema? Ou tenho que criar uma nova consulta?

AndreaNobili
fonte

Respostas:

33

Sua pergunta real é basicamente quando executar uma consulta personalizada e quando usar a consulta principal. Vamos dividi-lo em três partes

PARTE UM

Quando executar uma consulta personalizada (Esta não é uma lista definitiva)

  • Para criar controles deslizantes de conteúdo personalizados

  • Para criar uma área de conteúdo em destaque em uma página

  • Nos modelos page.php, se você precisar exibir postagens

  • Se você precisar de conteúdo personalizado em uma primeira página estática

  • Exibir postagens relacionadas, populares ou informativas

  • Qualquer outro conteúdo secundário ou suplementar fora do escopo da consulta principal

Quando fazer uso da consulta principal.

Para exibir o conteúdo principal em

  • Na sua página inicial e na página definida como uma página de blog no back-end

  • Todas as páginas de arquivo que incluem modelos como archive.php, category.php, author.php, taxonomy.php, tag.php e date.php

  • UPDATE: exibe conteúdo personalizado em páginas verdadeiras e em uma página estática ( consulte Usando pre_get_posts em páginas verdadeiras e páginas estáticas )

PARTE DOIS

Para selecionar todas as postagens em destaque, utilizo esta linha que cria um novo objeto WP_Query que define uma consulta com a tag específica em destaque:

Portanto, pelo que entendi, essa não é a consulta principal do WordPres, mas é uma nova consulta criada por mim. Pelo que entendi, é melhor criar uma nova consulta (como concluída) e não usar a consulta principal quando desejar executar esse tipo de operação

Corrigir. Isso fica fora do escopo da consulta principal. Este é um conteúdo secundário ou suplementar que não pode ser criado com a consulta principal. Você sempre deve usar WP_Queryou get_postspara criar suas consultas personalizadas.

NUNCA USE query_posts para criar consultas personalizadas ou mesmo qualquer outra consulta. Minha ênfase.

Nota: Esta função não deve ser usada por plugins ou temas. Como explicado mais adiante, existem opções melhores e com melhor desempenho para alterar a consulta principal. query_posts () é uma maneira excessivamente simplista e problemática de modificar a consulta principal de uma página, substituindo-a por uma nova instância da consulta. É ineficiente (executa novamente as consultas SQL) e falhará completamente em algumas circunstâncias (especialmente frequentemente ao lidar com paginação de postagens).

Se movendo

Ok, continuando, mostro todas as postagens que não possuem a tag em destaque. Para fazer isso, utilizo esse trecho de código que, pelo contrário, modifica a consulta principal:

query_posts( array( 'tag__not_in' => array ( $term->term_id )));

Então eu acho que isso é horrível. É verdade?

Está tudo errado e sua afirmação é infelizmente verdadeira. Como dito antes, NUNCA use query_posts. Ele executa uma nova consulta completa, que é ruim para o desempenho, e na maioria dos casos quebra a paginação, que é parte integrante da consulta principal para que a paginação funcione corretamente.

Esse é o seu conteúdo principal; portanto, você deve usar a consulta principal com o loop padrão, que deve se parecer com isso e é tudo o que você precisa

<?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;
?>

Você pode se livrar completamente dessa parte, excluí-la, gravá-la e esquecê-la

<?
// 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 )));
?>

OK, depois de fazer isso, você verá que as postagens da tag do recurso aparecem em sua página inicial usando a consulta principal e o loop padrão.

A maneira correta de remover esta tag da página inicial é com pre_get_posts. Essa é a maneira correta de alterar a consulta principal e o gancho que você deve sempre usar para fazer alterações no loop de conteúdo principal.

Portanto, o código com pre_get_postsestá correto e esta é a função que você deve usar. Apenas uma coisa, sempre verifique se você não está em uma página de administrador, porque também pre_get_postsaltera o back-end. Portanto, este é o código adequado functions.phppara remover as postagens marcadas em destaque na página inicial

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] );
    }
}

PARTE TRÊS

Material de leitura extra que será útil no futuro

Pieter Goosen
fonte
O prazer é meu. Que bom que você achou útil. Enjou :-)
Pieter Goosen
Uau, uma resposta e tanto! No entanto, estou perdendo uma informação crítica: como digo ao WP "esta é uma página de postagens" além da página principal de postagens? Digamos que eu queira uma lista de posts com as categorias 10,11,12 e outra lista com as categorias 13,14,15. Vejo como eu poderia usar pre_get_posts para injetar as categorias na consulta principal, mas como posso dizer ao WP para processá-lo como uma lista de postagens com paginação adequada? Eu realmente tenho que seguir sua resposta extensa aqui wordpress.stackexchange.com/a/215027/74134 porque é uma página? Certamente o WordPress permite nativamente várias listas de blogs em um site?
Mark Berry