Interogare *doar* pentru articolele lipicioase (sticky)
Am folosit următoarea interogare pentru a încerca să afișez doar articolele care sunt marcate ca sticky:
<?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(); ?>
În prezent nu am niciun articol setat ca sticky pe site. Ceea ce înseamnă că nu ar trebui să apară nimic în buclă. Cu toate acestea, am descoperit că afișa oricum 2 articole (chiar dacă nu erau sticky)
Apoi am trecut la un obiect WP_Query (așa cum mi s-a recomandat să evit query_posts()
în trecut)
<?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();
?>
Dar acum nu pare să funcționeze deloc, bucla pare să afișeze 2 articole, însă ambele sunt pagina care este vizualizată, în ciuda setării parametrului post_type

În prezent nu am postări setate ca lipicioase pe site. Ceea ce înseamnă că nu ar trebui să apară nimic în buclă.
Exact în acest punct greșești când transmiți un array gol la post__in
. WordPress are câteva bug-uri stupide care nu au soluții adecvate și care probabil vor rămâne active mult timp. Acesta este unul dintre ele.
Când transmitem un array valid cu ID-uri de postări la post__in
, obținem următoarea clauză SQL WHERE
(NOTĂ: Toate testele sunt făcute pe o pagină)
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\')
Acum, dacă nu avem postări lipicioase, transmitând astfel un array gol la post__in
, se generează greșit următorul SQL deoarece parametrul post__in
este văzut ca nefiind setat.
AND wp_posts.ID IN (59)
AND wp_posts.post_type = \'post\'
AND (wp_posts.post_status = \'publish\' OR wp_posts.post_status = \'private\')
Acesta este un eșec epic cu rezultate neașteptate. În funcție de parametrii transmiși, poți obține postări complet irelevante sau niciuna deloc.
De aceea ar trebui să validezi întotdeauna ceea ce transmiți la post__in
dacă valorile transmise sunt un array dinamic, pentru a evita acest eșec epic.
O altă notă care poate părea fără sens, dacă ai nevoie doar să interoghezi postările lipicioase, setează întotdeauna ignore_sticky_posts
la 1
(adevărat). Motivul este că, dacă ai nevoie să nu interoghezi toate postările lipicioase sau doar cele dintr-o anumită categorie, vei obține doar cele de care ai nevoie. Dacă nu ignori postările lipicioase, toate vor fi returnate indiferent de ce ai interogat (încă un bug stupid în opinia mea).
Poți rescrie codul astfel:
$stickies = get_option( 'sticky_posts' );
// Asigură-te că avem postări lipicioase pentru a evita rezultate neașteptate
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();
}
}

"Doar o altă notă care poate să nu aibă sens deloc: dacă trebuie doar să interogați postări lipicioase (sticky), setați întotdeauna ignore_sticky_posts la 1 (adevărat). Motivul este că, dacă aveți nevoie să nu interogați toate postările lipicioase sau doar cele dintr-o anumită categorie, veți obține exact cele de care aveți nevoie. Dacă nu ignorați postările lipicioase, toate vor fi returnate indiferent de ce ați interogat (încă un bug stupid, după părerea mea)."
Și chiar dacă faceți asta, post__not_in
devine oricum inutil.

Wow, acest lucru este extrem de util. Mulțumesc! Interogarea mea era pentru afișarea postărilor lipicioase în partea de sus a postărilor fiecărei categorii și părea să funcționeze bine până când am dat peste cazul în care nu existau postări lipicioase pe întreg site-ul. Sugestia ta de a folosi o condiție pentru get_option( 'sticky_posts’ )
a fost exact ceea ce aveam nevoie.
