Query solo post in evidenza
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

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

"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.

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.
