it-swarm.com.de

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

Ich bin ziemlich neu in der Entwicklung von WordPress-Themes und ich bin nicht so begeistert von PHP (ich komme 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 empfohlenen 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, der nicht der empfohlene Beitrag ist.

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>

<?
// 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 es funktioniert.

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

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

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

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 hervorgehobene Tag haben, dazu verwende ich diesen Codeausschnitt, der im Gegenteil die Hauptabfrage modifiziert:

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

Ich finde das ziemlich schrecklich. Ist es wahr?

Um den gleichen Vorgang auszuführen, habe ich diese Funktion 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, wobei alle Posts mit Ausnahme eines bestimmten Tags ausgewählt werden (in meinem Fall die Posts mit featured Tags).

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

19
AndreaNobili

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

ERSTER TEIL

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 außerhalb des Geltungsbereichs der Hauptabfrage liegen

Wann soll die Hauptabfrage verwendet werden?.

So zeigen Sie den primären Inhalt an

  • Auf deiner Homepage und der Seite als Blogseite im Backend eingestellt

  • Alle Archivseiten, die Vorlagen wie archive.php, category.php, author.php, taxonomy.php, tag.php und date.php enthalten

  • UPDATE:Benutzerdefinierten Inhalt auf echten Seiten und einer statischen Startseite anzeigen (siehe Verwenden von pre_get_posts auf echten Seiten und statischen Startseite)

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 hierbei 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 WP_Query oder get_posts verwenden, um Ihre benutzerdefinierten Abfragen zu erstellen.

BENUTZEN SIE NIEMALS 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 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 bereits gesagt,NEVERuse 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 zu ändern und den Hook, den Sie immer verwenden sollten, um Änderungen an Ihrer primären Inhaltsschleife vorzunehmen.

Der Code mit pre_get_posts ist 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 pre_get_posts auch das Back-End verändert. Dies ist also der richtige Code für functions.php, um Beiträge mit dem Tag featured 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] );
    }
}

DRITTER TEIL

Zusätzliches Lesematerial, das in Zukunft hilfreich sein wird

31
Pieter Goosen