the_content and is_main_query

12

Estoy filtrando el contenido con el filtro the_content . Todo funciona a la perfección, extracto de que mis cambios también se aplican a consultas personalizadas. Mis cambios aparecen también en la barra lateral si el widget utiliza una consulta personalizada

Para contrarrestar eso, estoy usando is_main_query() para apuntar solo a la consulta principal, pero no está funcionando. Los cambios simplemente se aplican a todas las consultas a lo largo. Sin embargo, lo que es divertido es que todas las demás comprobaciones condicionales como is_single() y is_category() funcionan si me dirijo a páginas específicas, excepto que todos los cambios afectan a cualquier otra consulta personalizada en esa página, ya sea que use is_main_query() o no

Estoy perdiendo algo aquí. ¿Cómo aplico mis cambios a la consulta principal solo utilizando el filtro the_content

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;
}
    
pregunta Pieter Goosen 27.09.2014 - 16:41

3 respuestas

11

Para ser honesto, la función in_the_loop() es lo que está buscando:

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

Lo que hace in_the_loop es verificar si global para $wp_query (que es el objeto de consulta principal) de la publicación actual es -1 < $current_post < $post_count .

Esto sucede cuando la consulta principal está en bucle, porque antes de que comience el bucle, la publicación actual es -1, y después de que el bucle finalice, la publicación actual se restablece nuevamente a -1.

Entonces, si in_the_loop() es verdadero, significa que el objeto de consulta principal está en bucle, que es lo que necesita en este caso (y es el mismo resultado de agregar la acción en loop_start y eliminar en loop_end , como escribió la respuesta que escribió @ialocin; de hecho, funciona por el mismo motivo y obtuvo mi +1).

El beneficio de la aproximación de @ ialocin es cuando desea apuntar a un objeto de consulta diferente al principal, porque in_the_loop() solo funciona para la consulta principal.

    
respondido por el gmazzap 28.09.2014 - 05:33
7

Esto es simplemente una adición a la respuesta de @ Otto. Solo para hacerlo un poco mejor comprensible. Básicamente, lo que está diciendo @Otto, tiene que revertir la lógica, eso significa: si puede determinar de manera confiable la consulta principal, entonces puede agregar, y eliminar, su conexión al filtro the_content .

Por ejemplo, la consulta principal se puede reconocer de manera confiable en la acción pre_get_posts , por lo que esto funcionaría:

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

Como se supone que debes eliminar el filtro cuando ya no se necesita, estoy pensando que la acción loop_end debería ser un buen lugar para eso y como su contraparte podemos usar loop_start . Que se vería así:

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' );
    }
}
    
respondido por el Nicolai 27.09.2014 - 18:11
5

Estás usando is_main_query() incorrectamente. La función global is_main_query () devuelve true a menos que la variable global $ wp_query haya sido redefinida.

Probablemente no haya una forma 100% confiable de decir, desde dentro de un filtro the_content, si el Loop actual es la consulta principal o no. El filtro de contenido simplemente filtra el contenido. No tiene ninguna forma de saber para qué bucle se está utilizando.

En su lugar, debes agregar tu filtro cuando lo necesites y luego eliminarlo cuando no lo hagas.

    
respondido por el Otto 27.09.2014 - 16:50

Lea otras preguntas en las etiquetas