¿Algunas dudas sobre cómo funciona la consulta principal y la consulta personalizada en este tema personalizado?

20

Soy bastante nuevo en el desarrollo de temas de WordPress y no estoy tan interesado en PHP (vine de Java y C #) y tengo la siguiente situación en este tema personalizado

Como puede ver en la página de inicio, primero muestro una sección (llamada Articoli en evidenza ) que contiene las publicaciones destacadas (la he implementado usando una etiqueta específica) y debajo hay otra área (llamada Ultimi Articoli ) que contiene la última publicación esa no es la publicación destacada.

Para hacerlo utilizo 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 bien, pero tengo algunas dudas sobre la calidad de esta solución y cómo funciona exactamente.

Para seleccionar todas las publicaciones destacadas , utilizo esta línea que crea un nuevo WP_Queryobjeto que define una consulta que tiene la etiqueta específica featured:

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

Luego repito el resultado de esta consulta usando su have_posts()método.

Entonces, por lo que tengo entendido, esta no es la consulta principal de WordPress, pero es una nueva consulta creada por mí. Por lo que entiendo, es mejor crear una nueva consulta (como se hizo) y no usar la consulta principal cuando quiero realizar este tipo de operación.

¿Es verdad o me estoy perdiendo algo? Si es cierto, ¿puede explicarme por qué es mejor crear una nueva consulta personalizada y no modificar la consulta principal de Wordpress?

Ok, continuando. Muestro todas las publicaciones que no tienen la etiqueta 'destacado'. Para hacer esto, uso este fragmento de código, que por el contrario, modifica la 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;
        ?>

Así que creo que esto es bastante horrible. ¿Es verdad?

ACTUALIZAR:

Para hacer la misma operación, encontré esta función (en la gran respuesta a continuación) que he agregado 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' );

Esta función tiene un enlace que se llama después de crear el objeto variable de consulta, pero antes de que se ejecute la consulta real.

Entonces, por lo que tengo entendido, toma un objeto de consulta como parámetro de entrada y lo modifica (en realidad lo filtra) seleccionando todas las publicaciones excluyendo una etiqueta específica (en mi caso, las featuredpublicaciones de etiqueta)

Entonces, ¿cómo puedo usar la consulta anterior (la que se usa para mostrar las publicaciones destacadas) con esta función para mostrar solo las publicaciones no destacadas en mi tema? ¿O tengo que crear una nueva consulta?

AndreaNobili
fuente

Respuestas:

33

Su pregunta real es básicamente cuándo ejecutar una consulta personalizada y cuándo hacer uso de la consulta principal. Vamos a dividirlo en tres partes.

PARTE UNO

Cuándo ejecutar una consulta personalizada (esta no es una lista definitiva)

  • Para crear controles deslizantes de contenido personalizado

  • Para crear un área de contenido destacado en una página

  • En las plantillas de page.php si necesita mostrar publicaciones

  • Si necesita contenido personalizado en una portada estática

  • Mostrar publicaciones relacionadas, populares o informativas

  • Cualquier otro contenido secundario o suplementario fuera del alcance de la consulta principal

Cuándo hacer uso de la consulta principal.

Para mostrar el contenido primario en

  • En su página de inicio y la página configurada como una página de blog en el backend

  • Todas las páginas de archivo que incluyen plantillas como archive.php, category.php, author.php, taxonomy.php, tag.php y date.php

  • ACTUALIZACIÓN: muestre contenido personalizado en páginas verdaderas y una página principal estática ( consulte Uso de pre_get_posts en páginas verdaderas y páginas principales estáticas )

LA SEGUNDA PARTE

Para seleccionar todas las publicaciones destacadas, uso esta línea que crea un nuevo objeto WP_Query que define una consulta con la etiqueta específica presentada:

Entonces, por lo que tengo entendido, esta no es la consulta principal de WordPres, pero es una nueva consulta creada por mí. Por lo que tengo entendido, es mejor crear una nueva consulta (como se hizo) y no usar la consulta principal cuando quiero realizar este tipo de operaciones

Correcto. Esto queda fuera del alcance de la consulta principal. Este es contenido secundario o complementario que no se puede crear con la consulta principal. Usted DEBE SIEMPRE utilizar WP_Queryo get_postscrear sus consultas personalizadas.

NUNCA USE query_posts para crear consultas personalizadas, o incluso cualquier otra consulta. Mi énfasis

Nota: Esta función no debe ser utilizada por complementos o temas. Como se explica más adelante, hay opciones mejores y más eficaces para alterar la consulta principal. query_posts () es una forma excesivamente simplista y problemática de modificar la consulta principal de una página al reemplazarla con una nueva instancia de la consulta. Es ineficiente (vuelve a ejecutar consultas SQL) y fallará directamente en algunas circunstancias (especialmente a menudo cuando se trata de paginación de publicaciones).

Hacia adelante

Ok, continúo mostrando todas las publicaciones que no tienen la etiqueta destacada, para hacer esto uso este fragmento de código que, por el contrario, modifica la consulta principal:

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

Así que creo que esto es bastante horrible. ¿Es verdad?

Todo eso está mal y su afirmación es lamentablemente cierta. Como se dijo antes, NUNCA use query_posts. Ejecuta una nueva consulta completa, que es mala para el rendimiento, y en la mayoría de los casos interrumpe la paginación, que es una parte integral de la consulta principal para que la paginación funcione correctamente.

Este es su contenido principal, por lo que debería usar la consulta principal con el bucle predeterminado, que debería tener este aspecto, y esto es todo lo que necesita

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

Puede deshacerse por completo de esta parte, eliminarla, grabarla y olvidarse de ella.

<?
// 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, una vez que hayas hecho eso, verás que las publicaciones de la etiqueta de función aparecen en tu página de inicio utilizando la consulta principal y el bucle predeterminado.

La forma correcta de eliminar esta etiqueta de la página de inicio es con pre_get_posts. Esta es la forma correcta de alterar la consulta principal y el enlace que siempre debe usar para realizar cambios en su ciclo de contenido principal.

Entonces, el código con pre_get_postses correcto y esta es la función que debe usar. Solo una cosa, siempre verifique que no esté en una página de administración porque también pre_get_postsaltera el back-end. Así que este es el código apropiado para usar functions.phppara eliminar publicaciones etiquetadas destacadas de la página de inicio

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 TRES

Material de lectura adicional que será útil en el futuro.

Pieter Goosen
fuente
El gusto es mio. Me alegra que lo hayas encontrado útil. Enjou :-)
Pieter Goosen
Wow, toda una respuesta! Sin embargo, me falta una pieza crítica de información: ¿cómo le digo a WP "esta es una página de publicaciones" además de la página de publicaciones principal? Digamos que quiero una lista de publicaciones con las categorías 10,11,12 y otra lista con las categorías 13,14,15. Veo cómo podría usar pre_get_posts para inyectar las categorías en la consulta principal, pero ¿cómo puedo decirle a WP que lo represente como una lista de publicaciones con la paginación adecuada? ¿Realmente tengo que seguir tu extensa respuesta aquí wordpress.stackexchange.com/a/215027/74134 porque es una página? ¿Seguramente WordPress permite de forma nativa múltiples listas de blogs en un sitio?
Mark Berry