it-swarm.com.de

the_content und is_main_query

Ich filtere den Inhalt mit dem the_content Filter. Alles funktioniert einwandfrei, auszugsweise werden meine Änderungen auch auf benutzerdefinierte Abfragen angewendet. Meine Änderungen werden auch in der Seitenleiste angezeigt, wenn das Widget eine benutzerdefinierte Abfrage verwendet

Um dem entgegenzuwirken, benutze ich is_main_query(), um nur die Hauptabfrage anzusprechen, aber es funktioniert nicht. Änderungen werden einfach noch auf alle Abfragen durchgespielt. Was jedoch lustig ist, alle anderen bedingten Prüfungen wie is_single() und is_category() funktionieren, wenn ich auf bestimmte Seiten abstelle, mit der Ausnahme, dass sich alle Änderungen auf jede andere benutzerdefinierte Abfrage auf dieser Seite auswirken, unabhängig davon, ob ich is_main_query() verwende oder nicht

Vermisse ich hier etwas? Wie wende ich meine Änderungen nur mit dem Filter the_content auf die Hauptabfrage an?

add_filter('the_content', 'custom_content');

function custom_content($content){

    if(is_main_query()){ // << THIS IS NOT WORKING
        // My custom content that I add to the_content()    
    }
    return $content;
}
13
Pieter Goosen

Um ehrlich zu sein, ist die Funktion in_the_loop() genau das, wonach Sie suchen:

add_filter( 'the_content', 'custom_content' );

function custom_content( $content ) {
    if ( in_the_loop() ) {
        // My custom content that I add to the_content()    
    }
    return $content;
}

in_the_loop prüft, ob global für $wp_query (das ist das Hauptabfrageobjekt) des aktuellen Beitrags -1 < $current_post < $post_count ist.

Dies geschieht, wenn die Hauptabfrage eine Schleife durchläuft, da der aktuelle Beitrag vor dem Start der Schleife -1 ist und der aktuelle Beitrag nach dem Ende der Schleife wieder auf -1 zurückgesetzt wird.

Wenn in_the_loop() true ist, bedeutet dies, dass das Hauptabfrageobjekt eine Schleife ausführt. Dies ist in diesem Fall erforderlich (und das gleiche Ergebnis, wenn die Aktion für loop_start hinzugefügt und für loop_end entfernt wird, wie in der Antwort @ialocin geschrieben wurde; in Tatsache, es funktioniert aus dem gleichen Grund und bekam meine +1).

Der @ ialocin-Ansatz hat den Vorteil, dass Sie ein anderes Abfrageobjekt als das Hauptobjekt als Ziel angeben möchten, da in_the_loop() nur für die Hauptabfrage funktioniert.

11
gmazzap

Dies ist nur eine Ergänzung zu @ Ottos Antwort. Nur um es ein bisschen verständlicher zu machen. Grundsätzlich muss @Otto die Logik umkehren, das heißt: Wenn Sie die Hauptabfrage zuverlässig ermitteln können, können Sie Ihre Einbindung in den the_content-Filter hinzufügen und entfernen.

Beispielsweise kann die Hauptabfrage bei der Aktion pre_get_posts zuverlässig erkannt werden. Dies würde also funktionieren:

function wpse162747_the_content_filter_callback( $content ) {
    return $content . 'with something appended';
}

add_action( 'pre_get_posts', 'wpse162747_pre_get_posts_callback' );
function wpse162747_pre_get_posts_callback( $query ) {
    if ( $query->is_main_query() ) {
        add_filter( 'the_content', 'wpse162747_the_content_filter_callback' );
    }
}

Da Sie den Filter entfernen sollen, wenn er nicht mehr benötigt wird, denke ich, dass die Aktion loop_end ein guter Ort dafür sein sollte, und als Gegenstück können wir loop_start verwenden. Welches würde so aussehen:

add_action( 'loop_start', 'wpse162747_loop_start_callback' );
function wpse162747_loop_start_callback( $query ) {
    if ( $query->is_main_query() ) {
        add_filter( 'the_content', 'wpse162747_the_content_filter_callback' );
    }
}

add_action( 'loop_end', 'wpse162747_loop_end_callback' );
function wpse162747_loop_end_callback( $query ) {
    if ( $query->is_main_query() ) {
        remove_filter( 'the_content', 'wpse162747_the_content_filter_callback' );
    }
}
7
Nicolai

Sie verwenden is_main_query() falsch. Die globale Funktion is_main_query () gibt true zurück, sofern die globale Variable $ wp_query nicht neu definiert wurde.

Es gibt wahrscheinlich keine hundertprozentig zuverlässige Möglichkeit, innerhalb eines the_content-Filters festzustellen, ob die aktuelle Schleife, in der Sie sich befinden, die Hauptabfrage ist oder nicht. Der Inhaltsfilter filtert nur den Inhalt. Es gibt keine Möglichkeit zu wissen, für welche Schleife es verwendet wird.

Fügen Sie stattdessen Ihren Filter hinzu, wenn Sie ihn benötigen, und entfernen Sie ihn, wenn Sie ihn nicht benötigen.

5
Otto