$post->ID non funziona

23 ago 2012, 18:07:09
Visualizzazioni: 33.8K
Voti: 4

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.

0
Tutte le risposte alla domanda 2
5

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.

23 ago 2012 18:17:29
Commenti

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

urok93 urok93
23 ago 2012 18:22:14

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.

Tom J Nowell Tom J Nowell
23 ago 2012 18:35:42

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.

Tom J Nowell Tom J Nowell
23 ago 2012 18:36:37

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

John_911 John_911
4 mar 2017 08:16:43

Se non sei d'accordo, ti suggerisco di scrivere un post sul blog o fare una nuova domanda, ma avrai bisogno di qualcosa di meglio del fatto che sia "più appropriato", le affermazioni devono essere supportate

Tom J Nowell Tom J Nowell
6 mar 2017 01:02:56
0

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.

23 ago 2012 18:53:44