web-dev-qa-db-fra.com

Requête * seulement * messages collants

J'utilise la requête suivante pour essayer de générer only posts marqués comme des notes persistantes:

<?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(); ?>

Je n'ai actuellement aucun article défini en tant que post-it sur le site. Ce qui me dit que rien ne devrait apparaître dans la boucle. Cependant, j’ai trouvé qu’il tirait de toute façon sur 2 posts (même s’ils n’étaient pas collants)

Alors je suis passé à un objet WP_Query (car on m'avait conseillé d'éviter query_posts() dans le passé)

<?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();

?>

Mais maintenant, cela ne semble pas fonctionner du tout, la boucle semble générer 2 messages. Cependant, la page affichée est la même, malgré le réglage du paramètre post_type

2
pealo86

Je n'ai actuellement aucun article défini en tant que post-it sur le site. Ce qui me dit que rien ne devrait apparaître dans la boucle.

Exactement où vous vous trompez lorsque vous passez un tableau vide à post__in. WordPress a quelques bugs stupides qui n'ont pas de solution de contournement appropriée et resteront probablement des bugs actifs pendant très longtemps. C'est l'un d'eux.

Lorsque nous passons un tableau valide d'ID de publications à post__in, nous obtenons la clause WHERE SQL résultante suivante ( NOTE: tous les tests sont effectués sur une page )

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\')

Maintenant, si nous n’avons pas de bloc-notes, transmettant ainsi un tableau vide à post__in, le code SQL suivant est généré de manière incorrecte, car le paramètre post__in est considéré comme non défini.

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

C'est un échec épique avec une sortie inattendue. En fonction des paramètres que vous avez définis, vous obtenez des messages totalement indépendants ou aucun message.

C'est pourquoi vous devriez toujours valider ce que vous passez à post__in si les valeurs transmises sont un tableau dynamique pour éviter cet échec épique.

Juste une autre note qui n’aurait aucun sens, si vous avez juste besoin d’interroger des posts persistants, définissez toujours ignore_sticky_posts sur 1 ( true ). La raison en est que, si vous ne souhaitez pas interroger tous les posts collants ou juste les collants d'une certaine catégorie, vous obtenez uniquement ceux dont vous avez besoin. Si vous n'ignorez pas les stickies, tous les stickies seront retournés indépendamment de ce que vous avez demandé ( encore un autre bug idiot à mon avis ).

Vous pouvez réécrire votre code comme suit

$stickies = get_option( 'sticky_posts' );
// Make sure we have stickies to avoid unexpected output
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();    
    }
}
6
Pieter Goosen