Qualche dubbio sul funzionamento della query principale e della query personalizzata in questo tema personalizzato?


20

Sono abbastanza nuovo nello sviluppo del tema WordPress e non sono così interessato a PHP (vengo da Java e C #) e ho la seguente situazione in questo tema personalizzato

Come puoi vedere nella homepage, per prima cosa mostro una sezione (chiamata Articoli in evidenza ) contenente i post in evidenza (l'ho implementata usando un tag specifico) e sotto di essa c'è un'altra area (chiamata Ultimi Articoli ) che contiene l'ultimo post che non sono i post in primo piano.

Per farlo uso questo codice:

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

Funziona bene, ma ho alcuni dubbi sulla qualità di questa soluzione e su come funziona esattamente.

Per selezionare tutti i post in primo piano , utilizzo questa riga che crea un nuovo WP_Queryoggetto che definisce una query con il tag specifico featured:

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

Quindi eseguo l'iterazione su questo risultato della query usando il suo have_posts() metodo.

Quindi, da quello che ho capito, questa non è la query principale di WordPress, ma è una nuova query creata da me. Da quello che ho capito, è meglio creare una nuova query (come fatto) e non usare la query principale quando voglio eseguire questo tipo di operazione.

È vero o mi sto perdendo qualcosa? Se è vero, puoi spiegarmi, perché è meglio creare una nuova query personalizzata e non modificare la query principale di Wordpress?

Ok, continua. Mostro tutti i post che non hanno il tag "in primo piano". Per fare ciò, uso questo frammento di codice, che al contrario modifica la query principale:

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

Quindi penso che sia piuttosto orribile. È vero?

AGGIORNARE:

Per fare la stessa operazione ho trovato questa funzione (nella grande risposta di seguito) che ho aggiunto 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' );

Questa funzione ha un hook chiamato dopo la creazione dell'oggetto variabile query, ma prima dell'esecuzione della query effettiva.

Quindi, da quello che ho capito, prende un oggetto query come parametro di input e lo modifica (effettivamente filtra) selezionando tutti i post escludendo un tag specifico (nel mio caso il featured post dei tag)

Quindi, come posso utilizzare la query precedente (quella utilizzata per mostrare i post in primo piano) con questa funzione per mostrare solo i post non in primo piano nel mio tema? O devo creare una nuova query?

Risposte:


33

La vera domanda è fondamentalmente quando eseguire una query personalizzata e quando utilizzare la query principale. Consente di scomporlo in tre parti

PRIMA PARTE

Quando eseguire una query personalizzata (questo non è un elenco definitivo)

  • Per creare cursori di contenuto personalizzati

  • Per creare un'area di contenuto in primo piano in una pagina

  • Sui template page.php se devi visualizzare post

  • Se hai bisogno di contenuti personalizzati su una prima pagina statica

  • Visualizza post correlati, popolari o informativi

  • Qualsiasi altro contenuto secondario o supplementare al di fuori dell'ambito della query principale

Quando utilizzare la query principale.

Per visualizzare il contenuto principale su

  • Sulla tua home page e sulla pagina impostata come pagina blog nel back-end

  • Tutte le pagine di archivio che includono modelli come archive.php, category.php, author.php, taxonomy.php, tag.php e date.php

  • AGGIORNAMENTO: visualizza contenuti personalizzati su pagine vere e una prima pagina statica ( vedi Uso di pre_get_posts su pagine vere e prime pagine statiche )

SECONDA PARTE

Per selezionare tutti i post in evidenza, utilizzo questa riga per creare un nuovo oggetto WP_Query che definisce una query con il tag specifico in evidenza:

Quindi, da quello che ho capito, questa non è la query principale di WordPres ma è una nuova query creata da me. Da quello che ho capito è meglio creare una nuova query (come fatto) e non usare la query principale quando voglio eseguire questo tipo di operazioni

Corretta. Questo non rientra nell'ambito della query principale. Questo è un contenuto secondario o supplementare che non può essere creato con la query principale. Si dovrebbe sempre utilizzare WP_Queryo get_postsper creare le vostre query personalizzate.

NON UTILIZZARE MAI query_posts per creare query personalizzate o anche qualsiasi altra query. La mia enfasi.

Nota: questa funzione non è pensata per essere utilizzata da plugin o temi. Come spiegato più avanti, ci sono opzioni migliori e più performanti per modificare la query principale. query_posts () è un modo eccessivamente semplicistico e problematico per modificare la query principale di una pagina sostituendola con una nuova istanza della query. È inefficiente (esegue nuovamente le query SQL) e fallirà completamente in alcune circostanze (soprattutto quando si ha a che fare con l'impaginazione dei post).

Andare avanti

Ok, continuando a mostrare tutti i post che non hanno il tag in evidenza, per fare ciò uso questo frammento di codice che al contrario modifica la query principale:

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

Quindi penso che sia piuttosto orribile. È vero?

È tutto sbagliato e la tua affermazione è purtroppo vera. Come detto prima, MAI usarequery_posts . Esegue una nuova query completa, che è dannosa per le prestazioni, e nella maggior parte dei casi interrompe l'impaginazione che è parte integrante della query principale affinché l'impaginazione funzioni correttamente.

Questo è il tuo contenuto principale, quindi dovresti utilizzare la query principale con il ciclo predefinito, che dovrebbe assomigliare a questo, e questo è tutto ciò di cui hai bisogno

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

Puoi eliminare completamente questa parte, eliminarla, masterizzarla e dimenticartene

<?
// 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 volta fatto, vedrai che i post dal tag funzione appariranno nella tua home page usando la query principale e il ciclo predefinito.

Il modo corretto di rimuovere questo tag dalla homepage è con pre_get_posts. Questo è il modo corretto di modificare la query principale e l'hook che dovresti sempre usare per apportare modifiche al tuo ciclo di contenuti principale.

Quindi, il codice con pre_get_postsè corretto e questa è la funzione che dovresti usare. Solo una cosa, controlla sempre di non essere su una pagina di amministrazione perché pre_get_postsaltera anche il back-end. Quindi questo è il codice corretto da utilizzare functions.phpper rimuovere i post taggati presenti nella homepage

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 TERZA

Materiale di lettura extra che sarà utile in futuro


Il piacere è tutto mio. Mi fa piacere che l'abbia trovato utile. Enjou :-)
Pieter Goosen il

Caspita, una bella risposta! Mi manca però un'informazione critica: come faccio a dire a WP "questa è una pagina di post" oltre alla pagina di post principale? Diciamo che voglio un elenco di post con le categorie 10,11,12 e un altro elenco con le categorie 13,14,15. Vedo come potrei usare pre_get_posts per iniettare le categorie nella query principale, ma come posso dire a WP di renderlo come un elenco di post con un'impaginazione adeguata? Devo davvero seguire la tua ampia risposta qui wordpress.stackexchange.com/a/215027/74134 perché è una Pagina? Sicuramente WordPress consente nativamente più elenchi di blog in un sito?
Mark Berry,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.