the_content e is_main_query


15

Sto filtrando il contenuto con il the_contentfiltro. Tutto funziona perfettamente, estratto che le mie modifiche vengono applicate anche alle query personalizzate. Le mie modifiche vengono visualizzate anche nella barra laterale se il widget utilizza una query personalizzata

Per contrastare ciò, sto usando is_main_query()come target solo la query principale, ma non funziona. Le modifiche vengono semplicemente applicate a tutte le query. Ciò che è divertente, però, piace a tutti gli altri controlli condizionali is_single()e is_category()funziona se scelgo come target pagine specifiche, tranne per il fatto che tutte le modifiche influiscono su qualsiasi altra query personalizzata su quella pagina, sia che io usi is_main_query()o meno

Mi sto perdendo qualcosa qui. Come posso applicare le mie modifiche alla query principale solo usando il the_contentfiltro

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

Risposte:


11

Ad essere onesti, la funzione in_the_loop()è ciò che stai cercando:

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

Quello che in_the_loopfa è verificare se globale per $wp_query(che è l'oggetto di query principale) del post corrente è -1 < $current_post < $post_count.

Ciò accade quando la query principale è in loop, perché prima che inizi il loop, il post corrente è -1 e dopo che il loop termina, il post corrente viene ripristinato nuovamente su -1.

Quindi, se in_the_loop()è vero, significa che l'oggetto di query principale è in loop, che è ciò di cui hai bisogno in questo caso (ed è lo stesso risultato dell'aggiunta dell'azione loop_starte della rimozione loop_end, come ha scritto la risposta @ialocin; in effetti funziona per lo stesso motivo, e ho ottenuto il mio +1).

Il vantaggio dell'approccio di @ ialocin è quando si desidera targetizzare un oggetto query diverso da quello principale, perché in_the_loop()funziona solo per la query principale.


In nessuna delle mie ricerche sul sito o ricerche online ho trovato questo. Una gemma nascosta che funziona. Ogni soluzione utilizza is_main_query, penso davvero che nessuno lo abbia testato a fondo. Grazie per il tuo contributo, davvero apprezzato
Pieter Goosen,

1
@PieterGoosen Sono contento che funzioni. Questa è una funzione molto antica, che arriva direttamente dai tempi in cui is_main_querynon era una cosa.
gmazzap

Vedi, è qui che mi sono perso, non sono un vecchio timer :-), mi sono unito a Wordpress in 3.3.
Pieter Goosen,

2
@GM ti dispiacerebbe aggiungere questo alla tua risposta. Queste sono informazioni utili ad altri che potrebbero inciampare in questa risposta. Molte persone, come me, non leggono commenti :-)
Pieter Goosen,

1
@PieterGoosen done :)
gmazzap

7

Questa è solo un'aggiunta alla risposta di @ Otto. Solo per renderlo un po 'meglio comprensibile. Fondamentalmente quello che sta dicendo @Otto, devi invertire la logica, ciò significa che se riesci a determinare in modo affidabile la query principale, puoi aggiungere - e rimuovere - il tuo aggancio nel the_contentfiltro.

Ad esempio, la query principale può essere riconosciuta in modo affidabile pre_get_postsall'azione, quindi funzionerebbe:

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

Dato che dovresti rimuovere il filtro quando non è più necessario, penso che l' loop_endazione dovrebbe essere un buon posto per questo e come sua controparte possiamo usare loop_start. Che sarebbe simile a questo:

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

Testerà questo domani. Grazie per la tua spiegazione dettagliata.
Pieter Goosen,

Il mio piacere come sempre @PieterGoosen Non c'è fretta, ma fallo, perché non l'ho fatto - almeno non abbastanza.
Nicolai,

1
Cosa succede se uno shortcode è in uso all'interno di the_content () e lo shortcode avvia un'altra query che chiama the_content (), reimposta l'oggetto post corrente e il ciclo continua? Verrà applicato tutto il filtro. Abbastanza difficile qui, non salvato dalla campana in_the_loop () ... Ecco perché suggerisco di rimuovere sempre filtri unici non appena hanno fatto, come avvicinato da @Nicolai
Jonas Lundman il

5

Stai usando in is_main_query()modo errato. La funzione globale is_main_query () restituisce true a meno che la variabile $ wp_query globale non sia stata ridefinita.

Probabilmente non esiste un modo affidabile al 100% per dire, dall'interno di un filtro the_content, se il loop corrente in cui ti trovi sia o meno la query principale. Il filtro del contenuto filtra solo il contenuto. Non ha alcuna forma di capacità di sapere per quale loop viene utilizzato.

Invece, dovresti aggiungere il filtro quando ne hai bisogno, quindi rimuoverlo quando non lo fai.


In realtà è deludente che non ci siano mezzi diretti per indirizzare la query principale con the_contentfiltro
Pieter Goosen,

Bene, questo non è davvero sorprendente però. Come qualsiasi altro filtro, filtra solo le cose. Non conosce il contesto circostante quando viene chiamato. Potrebbe anche non essere chiamato dall'interno di un Loop adeguato. Non c'è modo di dirlo.
Otto,
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.