Query solo post in evidenza

16 set 2015, 22:21:27
Visualizzazioni: 22.2K
Voti: 5

Ho usato la seguente query per cercare di mostrare solo i post contrassegnati come in evidenza:

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

Attualmente non ho nessun post impostato come in evidenza sul sito web. Questo dovrebbe significare che non dovrebbe apparire nulla nel loop. Tuttavia, ho scoperto che stava comunque mostrando 2 post (anche se non erano in evidenza)

Quindi sono passato a un oggetto WP_Query (come mi era stato consigliato di evitare query_posts() in passato)

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

?>

Ma ora non sembra funzionare affatto, il loop sembra mostrare 2 post, tuttavia entrambi sono la pagina che si sta visualizzando, nonostante io abbia impostato il parametro post_type

4
Commenti

@PieterGoosen questo non sembra risolvere il mio problema... anche se non capisco come ignorare i post sticky potrebbe aiutare?

User User
17 set 2015 00:13:51

I post sticky vengono automaticamente aggiunti alla query, quindi capisco perché Pieter abbia suggerito di ignorarli, visto che stai anche cercando esplicitamente i post sticky. Suggerisco di controllare $the_query->request dopo l'esecuzione per vedere l'SQL generato, è possibile che tu abbia qualche filtro mal indirizzato che interferisce.

Milo Milo
17 set 2015 00:33:59

@Milo ah capisco! Grazie. Ho provato e, anche se non sono un esperto di SQL, direi che la richiesta non assomiglia molto alla query che sto cercando di fare? (La posterò sotto questo commento)

User User
17 set 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 set 2015 16:45:54
Tutte le risposte alla domanda 1
2
16

Attualmente non ho post impostati come sticky nel sito web. Questo mi fa pensare che non dovrebbe apparire nulla nel loop.

Esattamente qui sbagli quando passi un array vuoto a post__in. WordPress ha alcuni bug piuttosto sciocchi che non hanno soluzioni corrette e probabilmente rimarranno attivi ancora per molto tempo. Questo è uno di quelli.

Quando passiamo un array valido di ID di post a post__in, otteniamo la seguente clausola SQL WHERE risultante (NOTA: Tutti i test sono stati fatti su una pagina)

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

Ora, se non abbiamo post sticky, passando quindi un array vuoto a post__in, viene generato erroneamente il seguente SQL perché il parametro post__in viene considerato come non impostato.

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

Questo è un fallimento epico con output inaspettato. A seconda dei parametri passati, ottieni post totalmente non correlati o nessun post.

Ecco perché dovresti sempre validare ciò che passi a post__in se i valori passati sono un array dinamico, per evitare questo fallimento epico.

Un'altra nota che potrebbe non avere molto senso: se hai bisogno di interrogare solo i post sticky, imposta sempre ignore_sticky_posts a 1 (vero). Il motivo è che, se vuoi interrogare solo alcuni sticky o solo quelli di una certa categoria, ottieni esattamente quelli che ti servono. Se non ignori i sticky, verranno restituiti tutti i sticky indipendentemente da ciò che hai chiesto (un altro bug sciocco secondo me).

Puoi riscrivere il tuo codice come segue

$stickies = get_option( 'sticky_posts' );
// Assicurati di avere sticky per evitare output inaspettati
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
Commenti

"Solo un'altra nota che potrebbe non avere alcun senso, se hai bisogno di interrogare solo i post sticky, imposta sempre ignore_sticky_posts a 1 (vero). Il motivo è che, se dovessi aver bisogno di non interrogare tutti i post sticky o solo quelli di una certa categoria, otterrai esattamente quelli che ti servono. Se non ignori i post sticky, verranno restituiti tutti i post sticky indipendentemente da ciò che hai interrogato (un altro bug sciocco secondo me)."

E anche se lo fai, post__not_in diventa comunque inutile.

lucian lucian
14 ago 2016 14:22:51

Wow, questo è estremamente utile. Grazie! La mia query era per mostrare i post sticky in cima ai post di ogni categoria e sembrava funzionare bene finché non mi sono imbattuto nel caso in cui non c'erano post sticky in tutto il sito. Il tuo suggerimento di usare un condizionale per get_option( 'sticky_posts’ ) era esattamente ciò di cui avevo bisogno.

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