Einige Zweifel, wie die Hauptabfrage und die benutzerdefinierte Abfrage in diesem benutzerdefinierten Thema funktionieren?

20

Ich bin ziemlich neu in der Entwicklung von WordPress-Themes und ich bin nicht so in PHP (ich kam aus Java und C #) und habe die folgende Situation in diesem benutzerdefinierten Theme

Wie Sie auf der Homepage sehen können, zeige ich zuerst einen Abschnitt (mit dem Namen Articoli in evidenza ), der die vorgestellten Beiträge enthält (ich habe ihn mit einem bestimmten Tag implementiert), und darunter befindet sich ein weiterer Bereich (mit dem Namen Ultimi Articoli ), der den neuesten Beitrag enthält Das sind nicht die vorgestellten Post.

Dazu benutze ich diesen Code:

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

Es funktioniert gut, aber ich habe einige Zweifel an der Qualität dieser Lösung und wie genau sie funktioniert.

Um alle vorgestellten Beiträge auszuwählen , verwende ich diese Zeile, die ein neues WP_QueryObjekt erstellt, das eine Abfrage mit dem spezifischen Tag definiert featured:

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

Dann iteriere ich dieses Abfrageergebnis mit seiner have_posts()Methode.

Soweit ich weiß, handelt es sich nicht um die WordPress-Hauptabfrage, sondern um eine neue Abfrage, die von mir erstellt wurde. Soweit ich weiß, ist es besser, eine neue Abfrage zu erstellen (wie getan) und nicht die Hauptabfrage zu verwenden, wenn ich diese Art von Operation ausführen möchte.

Ist es wahr oder fehle ich etwas? Wenn es wahr ist, können Sie mir erklären, warum es besser ist, eine neue benutzerdefinierte Abfrage zu erstellen und die Wordpress-Hauptabfrage nicht zu ändern?

Ok, mach weiter. Ich zeige alle Beiträge, die nicht das Tag "Hervorgehoben" haben. Dazu verwende ich diesen Codeausschnitt, der im Gegenteil die Hauptabfrage modifiziert:

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

Also ich denke, das ist ziemlich schrecklich. Ist es wahr?

AKTUALISIEREN:

Um den gleichen Vorgang auszuführen, habe ich diese Funktion (in der großartigen Antwort unten) gefunden, die ich zu functions.php hinzugefügt habe

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' );

Diese Funktion verfügt über einen Hook, der aufgerufen wird, nachdem das Abfragevariablenobjekt erstellt wurde, aber bevor die eigentliche Abfrage ausgeführt wird.

Soweit ich weiß, wird ein Abfrageobjekt als Eingabeparameter verwendet und geändert (tatsächlich gefiltert), indem alle Posts mit Ausnahme eines bestimmten Tags (in meinem Fall die featuredTag-Posts) ausgewählt werden.

Wie kann ich die vorherige Abfrage (die zum Anzeigen der vorgestellten Beiträge verwendet wurde) mit dieser Funktion verwenden, um nur die nicht vorgestellten Beiträge in meinem Thema anzuzeigen? Oder muss ich eine neue Abfrage erstellen?

AndreaNobili
quelle

Antworten:

33

Ihre eigentliche Frage ist im Grunde, wann Sie eine benutzerdefinierte Abfrage ausführen und wann Sie die Hauptabfrage verwenden müssen. Lassen Sie es uns in drei Teile zerlegen

TEIL EINS

Wann wird eine benutzerdefinierte Abfrage ausgeführt? (Dies ist keine endgültige Liste.)

  • So erstellen Sie benutzerdefinierte Inhaltsregler

  • So erstellen Sie einen vorgestellten Inhaltsbereich auf einer Seite

  • Auf page.php Vorlagen, wenn Sie Beiträge anzeigen müssen

  • Wenn Sie benutzerdefinierten Inhalt auf einer statischen Startseite benötigen

  • Zeigen Sie verwandte, beliebte oder informative Beiträge an

  • Alle anderen sekundären oder ergänzenden Inhalte, die nicht in den Geltungsbereich der Hauptabfrage fallen

Wann soll die Hauptabfrage verwendet werden?

So zeigen Sie den primären Inhalt an

ZWEITER TEIL

Um alle vorgestellten Beiträge auszuwählen, verwende ich diese Zeile, um ein neues WP_Query-Objekt zu erstellen, das eine Abfrage mit dem bestimmten vorgestellten Tag definiert:

Soweit ich weiß, handelt es sich nicht um die WordPres-Hauptabfrage, sondern um eine neue, von mir erstellte Abfrage. Soweit ich weiß, ist es besser, eine neue Abfrage zu erstellen (wie getan) und nicht die Hauptabfrage zu verwenden, wenn ich diese Art von Operationen ausführen möchte

Richtig. Dies liegt außerhalb des Bereichs für die Hauptabfrage. Dies ist ein sekundärer oder zusätzlicher Inhalt, der nicht mit der Hauptabfrage erstellt werden kann. Sie sollten immer entweder verwenden WP_Queryoder get_postsIhre benutzerdefinierten Abfragen zu erstellen.

NIEMALS BENUTZEN query_posts , um benutzerdefinierte Abfragen oder sogar andere Abfragen zu erstellen. Mein Schwerpunkt.

Hinweis: Diese Funktion ist nicht für Plugins oder Themes vorgesehen. Wie später erläutert, gibt es bessere, leistungsfähigere Optionen zum Ändern der Hauptabfrage. Mit query_posts () kann die Hauptabfrage einer Seite übermäßig vereinfacht und problematisch geändert werden, indem sie durch eine neue Instanz der Abfrage ersetzt wird. Es ist ineffizient (führt SQL-Abfragen erneut aus) und schlägt unter bestimmten Umständen (besonders häufig bei der Bearbeitung von Seitenumbrüchen) fehl.

Weitermachen

Ok, jetzt zeige ich alle Posts an, die nicht den empfohlenen Tag haben. Dazu verwende ich diesen Code-Snippet, der im Gegenteil die Hauptabfrage modifiziert:

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

Ich finde das ziemlich schrecklich. Ist es wahr?

Das ist alles falsch und Ihre Aussage ist leider wahr. Wie gesagt, NIEMALS verwenden query_posts. Es wird eine vollständig neue Abfrage ausgeführt, die für die Leistung schlecht ist. In den meisten Fällen wird die Paginierung unterbrochen, die ein wesentlicher Bestandteil der Hauptabfrage ist, damit die Paginierung ordnungsgemäß funktioniert.

Dies ist Ihr primärer Inhalt, daher sollten Sie die Hauptabfrage mit der Standardschleife verwenden, die so aussehen sollte, und dies ist alles, was Sie benötigen

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

Sie können dieses Teil komplett entfernen, löschen, brennen und vergessen

<?
// 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, sobald Sie das getan haben, werden Sie sehen, dass Beiträge aus dem Feature-Tag auf Ihrer Homepage unter Verwendung der Hauptabfrage und der Standardschleife angezeigt werden.

Die korrekte Entfernung dieses Tags von der Homepage erfolgt mit pre_get_posts. Dies ist der richtige Weg, um die Hauptabfrage und den Hook zu ändern, den Sie immer verwenden sollten, um Änderungen an Ihrer primären Inhaltsschleife vorzunehmen.

Der Code mit pre_get_postsist also korrekt und dies ist die Funktion, die Sie verwenden sollten. Nur eine Sache, stellen Sie immer sicher, dass Sie nicht auf einer Admin-Seite sind, da dies auch pre_get_postsdas Back-End verändert. Dies ist also der richtige Code functions.php, um Beiträge mit dem Tag " Hervorgehoben" von der Startseite zu entfernen

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

TEIL DREI

Zusätzliches Lesematerial, das in Zukunft hilfreich sein wird

Pieter Goosen
quelle
Gern geschehen. Froh, dass Sie es nützlich fanden. Enjou :-)
Pieter Goosen
Wow, eine ziemliche Antwort! Ich vermisse jedoch eine wichtige Information: Wie sage ich WP "Dies ist eine Postseite" neben der Hauptseite der Posts? Angenommen, ich möchte eine Liste von Posts mit den Kategorien 10,11,12 und eine andere Liste mit den Kategorien 13,14,15. Ich sehe, wie ich pre_get_posts verwenden kann, um die Kategorien in die Hauptabfrage einzufügen, aber wie kann ich WP anweisen, diese als Liste von Posts mit korrekter Paginierung zu rendern? Muss ich folgen , um Ihre umfangreiche Antwort hier wirklich wordpress.stackexchange.com/a/215027/74134 , weil es eine Seite ist? Sicherlich erlaubt WordPress nativ mehrere Blog-Listen in einer Site?
Mark Berry