Consultar solo entradas fijas

16 sept 2015, 22:21:27
Vistas: 22.2K
Votos: 5

He estado usando la siguiente consulta para intentar mostrar solamente las entradas que están marcadas como fijas:

<?php
    $args = array(
        'post_type' => 'post',
        'posts_per_page' => 2,
        'post__in' => get_option('sticky_posts')
    );
?>

<?php query_posts($args); ?>
<?php if(have_posts()) : ?>

    <?php get_template_part('loop', 'feed-top-stories' ); ?>

<?php endif; ?>
<?php wp_reset_query(); ?>

Actualmente no tengo ninguna entrada configurada como fija en el sitio web. Lo cual me indica que no debería aparecer nada en el bucle. Sin embargo, descubrí que estaba mostrando 2 entradas de todos modos (aunque no eran entradas fijas)

Entonces cambié a un objeto WP_Query (ya que me aconsejaron evitar query_posts() en el pasado)

<?php

    $args = array(
            'post_type' => 'post',
            'post__in' => get_option( 'sticky_posts' ),
            'posts_per_page' => 2
    );

    $the_query = new WP_Query($args);

    if ( $the_query->have_posts() ) : while ( $the_query->have_posts() ) : $the_query->the_post();

        get_template_part('loop', 'feed-top-stories' );

    endwhile; endif;

    wp_reset_postdata();

?>

Pero ahora parece que no está funcionando en absoluto, el bucle parece estar mostrando 2 entradas, sin embargo, ambas son la página que se está visualizando, a pesar de que establecí el parámetro post_type

4
Comentarios

@PieterGoosen eso no parece solucionar mi problema... aunque no veo cómo ignorar los posts fijos ayudaría?

User User
17 sept 2015 00:13:51

Los posts fijos se añaden automáticamente a la consulta, por lo que entiendo por qué Pieter sugirió ignorarlos, ya que también estás consultando explícitamente posts fijos. Sugiero revisar $the_query->request después de que se ejecute para ver el SQL generado, es posible que tengas algún filtro mal dirigido interfiriendo.

Milo Milo
17 sept 2015 00:33:59

@Milo ¡Ah, ya veo! Gracias. Lo he intentado y, aunque no soy un experto en SQL, diría que la solicitud no se parece mucho a la consulta que estoy tratando de hacer? (Lo publicaré debajo de este comentario)

User User
17 sept 2015 16:45:46

SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts WHERE 1=1 AND wp_posts.post_type = 'post' AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'private') ORDER BY wp_posts.post_date DESC LIMIT 0, 2

User User
17 sept 2015 16:45:54
Todas las respuestas a la pregunta 1
2
16

Actualmente no tengo publicaciones fijadas en el sitio web. Lo que me indica que no debería aparecer nada en el loop.

Exactamente ahí es donde te equivocas al pasar un array vacío a post__in. WordPress tiene algunos errores tontos que no tienen una solución adecuada y probablemente seguirán siendo errores activos durante mucho tiempo. Este es uno de ellos.

Cuando pasamos un array válido de IDs de publicaciones a post__in, obtenemos la siguiente cláusula SQL WHERE resultante (NOTA: Todas las pruebas se realizan en una página)

AND wp_posts.ID IN (59,45) 
AND wp_posts.post_type = \'post\' 
AND (wp_posts.post_status = \'publish\' OR wp_posts.post_status = \'private\')

Ahora, si no tenemos publicaciones fijadas, pasando así un array vacío a post__in, se genera incorrectamente el siguiente SQL porque el parámetro post__in se considera como no establecido.

AND wp_posts.ID IN (59) 
AND wp_posts.post_type = \'post\' 
AND (wp_posts.post_status = \'publish\' OR wp_posts.post_status = \'private\')

Este es un fallo épico con resultados inesperados. Dependiendo de los parámetros que pases, obtienes publicaciones totalmente no relacionadas o ninguna publicación en absoluto.

Por eso siempre debes validar lo que pasas a post__in si los valores pasados son un array dinámico para evitar este fallo épico.

Solo otra nota que puede no tener ningún sentido, si solo necesitas consultar publicaciones fijadas, siempre establece ignore_sticky_posts en 1 (verdadero). La razón de esto es que, si necesitas no consultar todas las publicaciones fijadas o solo las fijadas de una categoría determinada, obtienes solo las que necesitas. Si no ignoras las fijadas, se devolverán todas las fijadas independientemente de lo que hayas consultado (en mi opinión, otro error tonto).

Puedes reescribir tu código de la siguiente manera

$stickies = get_option( 'sticky_posts' );
// Asegurarnos de que tenemos publicaciones fijadas para evitar resultados inesperados
if ( $stickies ) {
    $args = [
        'post_type'           => 'post',
        'post__in'            => $stickies,
        'posts_per_page'      => 2,
        'ignore_sticky_posts' => 1
    ];
    $the_query = new WP_Query($args);

    if ( $the_query->have_posts() ) { 
        while ( $the_query->have_posts() ) { 
            $the_query->the_post();

            get_template_part('loop', 'feed-top-stories' );

        }    
        wp_reset_postdata();    
    }
}
8 feb 2016 20:31:36
Comentarios

"Solo otra nota que quizás no tenga mucho sentido, pero si necesitas consultar solo posts sticky, siempre establece ignore_sticky_posts en 1 (verdadero). La razón es que si necesitas no consultar todos los posts sticky o solo los de una categoría específica, obtendrás justo los que necesitas. Si no ignoras los sticky, se devolverán todos sin importar tu consulta (en mi opinión, otro error tonto más)."

E incluso si haces esto, el parámetro post__not_in sigue siendo inútil de todos modos.

lucian lucian
14 ago 2016 14:22:51

¡Guau, esto es súper útil! ¡Gracias! Mi consulta era para mostrar posts sticky al inicio de los posts de cada categoría y parecía funcionar bien hasta que me encontré con el caso donde no había ningún post sticky en todo el sitio. Tu sugerencia de usar un condicional con get_option( 'sticky_posts’ ) era justo lo que necesitaba.

Joel Farris Joel Farris
18 nov 2021 04:45:58