$post->ID non funziona
Ho il seguente codice e mentre get_the_ID() funziona, $post->ID non funziona, perché?
$the_query = new WP_Query( array(
'post_type' => 'custompost',
) );
while ( $the_query->have_posts() ) : $the_query->the_post();
echo $post->ID;
endwhile;
Per far funzionare $post->ID, devi dichiarare la variabile $post come globale all'interno del loop. Ecco il codice corretto:
$the_query = new WP_Query( array(
'post_type' => 'custompost',
) );
while ( $the_query->have_posts() ) : $the_query->the_post();
global $post;
echo $post->ID;
endwhile;
In alternativa, puoi usare la funzione get_the_ID() che è il metodo consigliato per ottenere l'ID del post corrente nel loop di WordPress.

Il tuo loop WP_Query è incompleto. Non stai verificando se sono stati trovati post prima di eseguire il loop, né stai mostrando un messaggio nel caso non ne siano stati trovati, e non stai effettuando la pulizia dopo l'uso. Inoltre, stai utilizzando la sintassi 'alternativa' che rompe il matching delle parentesi negli IDE, rendendo il tuo lavoro più difficile.
Prova ad aggiungere global $post;
in questo modo:
global $post;
$the_query = new WP_Query( array(
'post_type' => 'custompost'
) );
if($the_query->have_posts()){
while ( $the_query->have_posts() ) {
$the_query->the_post();
echo $post->ID;
}
wp_reset_postdata();
}else {
echo 'Nessun post trovato';
}
Quando scrivi query è importante essere coerenti e fare le cose nel modo giusto. Quindi ti consiglio di leggere queste slide di Andrew Nacin, uno sviluppatore del core di WordPress presso Automattic:
http://www.slideshare.net/andrewnacin/you-dont-know-query-wordcamp-netherlands-2012
Questo materiale ti spiegherà quando ogni tipo di query è appropriato, come dovrebbero essere utilizzate e perché.
Nel codice sopra, ho aggiunto un'istruzione if per verificare se sono stati restituiti dei post, e ho aggiunto wp_reset_postdata che ti permetterà di continuare a utilizzare la query principale ripulendo dopo il loop personalizzato.

Grazie, il global ha funzionato alla perfezione. Come funziona esattamente? E cosa fa precisamente wp_reset_postdata()? È sempre necessario?

Immagino che $post
fosse semplicemente fuori dallo scope. Per quanto riguarda wp_reset_postdata()
, quando inizi a eseguire il tuo loop, la variabile $post viene modificata, quindi wp_reset_postdata() funziona come un'operazione di annullamento, permettendoti di utilizzare più loop all'interno della tua query principale senza interromperla.

Dovresti dare un'occhiata a queste slide: http://www.slideshare.net/andrewnacin/you-dont-know-query-wordcamp-netherlands-2012 Sono una serie di slide incredibilmente utili sulle query realizzate da Nacin, uno degli sviluppatori core, che spiega tutto nel dettaglio.

Sono d'accordo con tutto tranne che con il commento sulla sintassi "alternativa". La maggior parte delle volte produrremo HTML all'interno del ciclo while, quindi la sintassi "alternativa" è solitamente più appropriata. Link alla documentazione sulla sintassi alternativa nel caso qualcuno fosse interessato - http://php.net/manual/en/control-structures.alternative-syntax.php

Il trucco, come identificato da Tom Nowell, è aggiungere un riferimento a global $post
.
Quando esegui the_query->the_post()
, WordPress carica il primo risultato della query in un oggetto globale $post
. Questo è il modo in cui configura tutto per i normali tag del template:
the_title()
the_content()
the_excerpt
()- ecc...
Come puoi vedere, non passiamo nulla a queste funzioni. Le chiamiamo semplicemente. Ognuna di queste funzioni farà riferimento internamente all'oggetto globale $post
per analizzare, preparare e stampare l'output desiderato.
All'interno del tuo loop, chiami the_post()
correttamente per popolare i dati, ma non hai un riferimento ai dati stessi all'interno dello scope del tuo loop. Se volessi evitare di fare riferimento all'oggetto globale $post
, potresti invece usare get_the_ID()
.
Come gli altri tag del template menzionati sopra, get_the_ID()
recupera i dati internamente dall'oggetto globale $post
, quindi non devi farlo tu stesso.
Ma se vuoi farlo tu stesso, aggiungi semplicemente un riferimento globale prima di provare a usare $post
:
$the_query = new WP_Query( array(
'post_type' => 'custompost',
) );
while ( $the_query->have_posts() ) : $the_query->the_post();
global $post; // Aggiungi questa riga e sei a posto
echo $post->ID;
endwhile;
Cos'è wp_reset_postdata()
?
Se stai costruendo loop multipli (ad esempio, hai un loop principale di post ma chiami un loop secondario al suo interno), puoi chiamare wp_reset_postdata()
per ripristinare lo stato.
In pratica, the_post()
imposterà l'oggetto globale $post
con i dati della query richiesta. the_query->the_post()
sovrascriverà $post
con i dati di the_query
. wp_reset_postdata()
ripristinerà $post
alla query originale.
Quindi, se stai usando loop annidati o multipli, wp_reset_postdata()
è un modo per tornare al loop e all'oggetto $post
che avevi disponibile prima di chiamare il tuo the_query->the_post()
secondario.
