$post->ID no funciona

23 ago 2012, 18:07:09
Vistas: 33.8K
Votos: 4

Tengo el siguiente código y mientras get_the_ID() funciona, $post->ID no funciona, ¿por qué?

    $the_query = new WP_Query( array(
        'post_type' => 'custompost',
    ) );

    while ( $the_query->have_posts() ) : $the_query->the_post();
        echo $post->ID;
    endwhile;
0
Todas las respuestas a la pregunta 2
5

Tu bucle WP_Query está incompleto. No estás verificando si se encontraron publicaciones antes de iterar, ni mostrando un mensaje cuando no se encuentran resultados, ni limpiando después. Además, estás usando la sintaxis 'alternativa' que rompe el emparejamiento de llaves en los IDEs, haciendo tu vida más difícil.

Intenta añadir global $post; así:

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 'No se encontraron publicaciones';
}

Al escribir consultas es importante ser consistente y hacer las cosas correctamente. Por eso recomiendo leer estas diapositivas de Andrew Nacin, un desarrollador del núcleo de WordPress en Automattic:

http://www.slideshare.net/andrewnacin/you-dont-know-query-wordcamp-netherlands-2012

Esto te dirá cuándo es apropiado cada tipo de consulta, cómo deben usarse y por qué.

En el código anterior, añadí una declaración if para verificar si se devolvieron publicaciones, y agregué wp_reset_postdata que te permitirá seguir usando la consulta principal limpiando después del bucle personalizado.

23 ago 2012 18:17:29
Comentarios

Gracias, el global funcionó entonces, ¿cómo funciona eso? ¿Y qué hace exactamente wp_reset_postdata()? ¿Siempre es necesario?

urok93 urok93
23 ago 2012 18:22:14

Supongo que $post simplemente estaba fuera del alcance, en cuanto a wp_reset_postdata(), cuando comienzas a ejecutar tu bucle, la variable $post se modifica, por lo que wp_reset_postdata() es como un deshacer de eso, permitiéndote usar múltiples bucles dentro de tu consulta principal sin romperla.

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

Deberías ver estas diapositivas: http://www.slideshare.net/andrewnacin/you-dont-know-query-wordcamp-netherlands-2012 Es un conjunto de diapositivas increíblemente útil sobre cómo hacer consultas por Nacin, uno de los desarrolladores principales, lo explica todo

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

Estoy de acuerdo con todo excepto con el comentario sobre la sintaxis "alternativa". La mayoría de las veces vamos a estar generando HTML dentro del bucle while, por lo que la sintaxis "alternativa" suele ser más apropiada. Enlace a la documentación de sintaxis alternativa por si alguien está interesado - http://php.net/manual/en/control-structures.alternative-syntax.php

John_911 John_911
4 mar 2017 08:16:43

Si no estás de acuerdo, te sugiero que escribas un artículo en un blog o hagas una nueva pregunta, pero necesitarás algo mejor que decir que es 'más apropiado', las afirmaciones necesitan estar respaldadas

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

El truco, como identificó Tom Nowell, es agregar una referencia a global $post.

Cuando ejecutas the_query->the_post(), WordPress carga el primer resultado de la consulta en un objeto global $post. Así es como configura todo para las etiquetas de plantilla habituales:

  • the_title()
  • the_content()
  • the_excerpt()
  • etc ...

Notarás que no pasamos ningún parámetro a estas funciones. Simplemente las llamamos. Cada una de estas funciones hará referencia internamente al objeto global $post para analizar, preparar e imprimir la salida deseada.

Dentro de tu bucle, llamas a the_post() correctamente para poblar los datos, pero no tienes una referencia a los datos dentro del alcance de tu bucle. Si quisieras evitar hacer referencia al objeto global $post, podrías usar get_the_ID() en su lugar.

Al igual que las otras etiquetas de plantilla mencionadas anteriormente, get_the_ID() obtiene los datos del objeto global $post internamente, por lo que no tienes que hacerlo tú mismo.

Pero si quieres hacerlo tú mismo, simplemente agrega una referencia global antes de intentar usar $post:

$the_query = new WP_Query( array(
    'post_type' => 'custompost',
) );

while ( $the_query->have_posts() ) : $the_query->the_post();
    global $post;  // Agrega esta línea y estarás listo
    echo $post->ID;
endwhile;

¿Qué es wp_reset_postdata()?

Si estás construyendo múltiples bucles (es decir, tienes un bucle principal de publicaciones pero llamas a un bucle secundario dentro de él), puedes llamar a wp_reset_postdata() para restablecer las cosas.

Básicamente, the_post() establecerá el objeto global $post para que contenga los datos de la consulta solicitada. the_query->the_post() sobrescribirá $post con los datos de the_query. wp_reset_postdata() restablecerá $post a la consulta original.

Así que si estás usando bucles anidados o múltiples, wp_reset_postdata() es una forma de volver al bucle y al objeto $post que tenías disponible antes de llamar a tu the_query->the_post() secundario.

23 ago 2012 18:53:44