the_content und is_main_query


15

Ich filtere den Inhalt mit dem the_contentFilter. 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, ziele ich nur is_main_query()auf die Hauptabfrage ab, aber sie funktioniert nicht. Änderungen werden einfach noch auf alle Abfragen durchgespielt. Was aber lustig ist, alle anderen bedingten Überprüfungen mögen is_single()und is_category()funktionieren, wenn ich auf bestimmte Seiten ziele, mit der Ausnahme, dass sich alle Änderungen auf jede andere benutzerdefinierte Abfrage auf dieser Seite auswirken, unabhängig davon, ob ich sie verwende is_main_query()oder nicht

Vermisse ich hier etwas? Wie wende ich meine Änderungen nur mit dem the_contentFilter 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;
}

Antworten:


11

Um ehrlich zu sein, ist die Funktion genau das, in_the_loop()was 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;
}

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

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 dies in_the_loop()zutrifft, bedeutet dies, dass sich das Hauptabfrageobjekt in einer Schleife befindet. In diesem Fall ist dies das gleiche Ergebnis wie beim Hinzufügen loop_startund Entfernen der Aktion loop_end, wie es die Antwort @ialocin geschrieben hat. Tatsächlich funktioniert es aus dem gleichen Grund und bekam meine +1).

Der @ ialocin-Ansatz bietet den Vorteil, dass Sie ein anderes Abfrageobjekt als das Hauptobjekt als Ziel angeben möchten, da in_the_loop()nur die Hauptabfrage möglich ist.


Bei keiner meiner Website-Suchen oder Online-Suchen bin ich auf dieses Ergebnis gestoßen. Ein verstecktes Juwel, das funktioniert. Jede Lösung nutzt is_main_query, glaube wirklich, niemand hat dies gründlich getestet. Vielen Dank für Ihre Eingabe, sehr geschätzt
Pieter Goosen

1
@PieterGoosen Froh, dass es funktioniert. Das ist eine sehr alte Funktion, die direkt aus Zeiten stammt, in denen is_main_queryes nichts gab.
gmazzap

Sie sehen, hier habe ich es verpasst, ich bin kein Oldtimer :-), trat Wordpress in 3.3 bei.
Pieter Goosen

2
@ GM würde es Ihnen etwas ausmachen, dies zu Ihrer Antwort hinzuzufügen. Dies ist eine nützliche Information für andere, die über diese Antwort stolpern könnten. Die meisten Leute, wie ich, lesen keine Kommentare :-)
Pieter Goosen

1
@PieterGoosen fertig :)
gmazzap

7

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

Beispielsweise kann die Hauptabfrage bei der pre_get_postsAktion zuverlässig erkannt werden , so dass dies funktionieren würde:

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 loop_endAktion ein guter Ort dafür sein sollte und als Gegenstück wir ihn verwenden können loop_start. 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' );
    }
}

Werde das morgen testen. Vielen Dank für Ihre ausführliche Erklärung.
Pieter Goosen

Es ist mir ein Vergnügen wie immer @PieterGoosen Keine Eile, aber mach es, weil ich es nicht habe - zumindest nicht genug.
Nicolai

1
Was passiert, wenn ein Shortcode in the_content () verwendet wird und der Shortcode eine andere Abfrage startet, die the_content () aufruft, das aktuelle Post-Objekt zurücksetzt und die Schleife fortgesetzt wird? Alle Filter werden angewendet. Ziemlich knifflig hier, nicht von der Glocke in_the_loop () gespeichert ... Deshalb schlage ich vor, eindeutige Filter immer zu entfernen, sobald sie fertig sind, wie von @Nicolai
Jonas Lundman,

5

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.


Tatsächlich ist es eine Enttäuschung, dass es keine eindeutigen Mittel gibt, um die Hauptabfrage mit the_contentFilter
Pieter Goosen,

Nun, das ist aber nicht wirklich überraschend. Wie bei jedem anderen Filter werden nur die Dinge gefiltert. Es kennt den Kontext, in dem es aufgerufen wird, nicht. Es kann sein, dass es nicht einmal aus einer richtigen Schleife heraus aufgerufen wird. Keine Möglichkeit, es zu sagen.
Otto
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.