¿Es necesario usar wp_reset_query() en una llamada WP_Query?
Estoy usando el siguiente código para recuperar publicaciones:
<?php
$featuredPosts = new WP_Query();
$featuredPosts->query('showposts=5&cat=3');
while ($featuredPosts->have_posts()) : $featuredPosts->the_post(); ?>
<h1><a href="<?php the_permalink() ?>"><?php the_title(); ?></a></h1>
<div class="meta">
Por <?php the_author() ?>
</div>
<div class="storycontent">
<?php the_excerpt(); ?>
</div>
<?php endwhile; ?>
¿Necesito usar wp_reset_query()
? Si es así, ¿dónde debería colocarlo?

No es necesario para WP_Query
por sí mismo, pero sí es necesario (o al menos es una buena práctica) si utilizas funciones/métodos relacionados (como the_post()
o setup_postdata()
) para llenar variables globales con tus datos.
Básicamente, crear un nuevo objeto WP_Query
es simplemente una recuperación de datos, pero usarlo para ejecutar un bucle activo y hacer que los datos sean accesibles a las etiquetas de plantilla sí modifica el entorno, por lo que es bueno restablecer todo después.
En general, no es una penalización de rendimiento significativa llamarlo, por lo que es más fácil siempre llamarlo que decidir si deberías o no hacerlo, o olvidarte y tener algo misteriosamente roto.
Actualización
La función wp_reset_postdata()
parece ser una opción más adecuada. wp_reset_query()
restablece la variable global $wp_query
(que un objeto personalizado WP_Query
no afecta) y $post
(que sí podría afectar como se mencionó anteriormente). wp_reset_postdata()
solo restaura $post
, lo cual debería ser suficiente.

Hola @janoChen:
Respuesta simple: no.
A continuación se muestra el código PHP de la función wp_reset_query()
del archivo /wp-includes/query.php
en WordPress v3.0.4, así como las funciones llamadas posteriormente. Puedes ver que se trata principalmente de modificar variables globales.
Cuando usas new WP_Query($args)
estarás asignando el valor de retorno a una variable local, por lo que, a menos que estés haciendo algo tan complejo que ya sabrías la respuesta a esta pregunta, entonces no, no necesitas llamar a wp_reset_query()
:
function wp_reset_query() {
unset($GLOBALS['wp_query']);
$GLOBALS['wp_query'] =& $GLOBALS['wp_the_query'];
wp_reset_postdata();
}
function wp_reset_postdata() {
global $wp_query;
if ( !empty($wp_query->post) ) {
$GLOBALS['post'] = $wp_query->post;
setup_postdata($wp_query->post);
}
}
function setup_postdata($post) {
global $id, $authordata, $day, $currentmonth, $page, $pages, $multipage, $more, $numpages;
$id = (int) $post->ID;
$authordata = get_userdata($post->post_author);
$day = mysql2date('d.m.y', $post->post_date, false);
$currentmonth = mysql2date('m', $post->post_date, false);
$numpages = 1;
$page = get_query_var('page');
if ( !$page )
$page = 1;
if ( is_single() || is_page() || is_feed() )
$more = 1;
$content = $post->post_content;
if ( strpos( $content, '<!--nextpage-->' ) ) {
if ( $page > 1 )
$more = 1;
$multipage = 1;
$content = str_replace("\n<!--nextpage-->\n", '<!--nextpage-->', $content);
$content = str_replace("\n<!--nextpage-->", '<!--nextpage-->', $content);
$content = str_replace("<!--nextpage-->\n", '<!--nextpage-->', $content);
$pages = explode('<!--nextpage-->', $content);
$numpages = count($pages);
} else {
$pages = array( $post->post_content );
$multipage = 0;
}
do_action_ref_array('the_post', array(&$post));
return true;
}
-Mike

@janoChen - jeje. Definitivamente me ha estado presionando últimamente, ¡eso es seguro! Supongo que como dicen, la competencia mejora la raza (¡pero seguro que me impide hacer cualquier otra cosa productiva! '-)

Solo para otros que lean esto, dado que esta sigue siendo la respuesta aceptada (la respuesta de @Rarst debería ser la aceptada). Como el OP usa the_post()
en su código, las mejores prácticas dictan que debe usar wp_reset_postdata()
. wp_reset_query()
llama a wp_reset_postdata()
, por lo que eso funcionará, aunque lo otro que hace wp_reset_query()
- reiniciar la variable global $wp_query
- no es necesario, pero no es dañino en este caso. Así que la respuesta es en realidad SÍ

No. Si instancias tu propio objeto WP_Query, es tuyo para hacer lo que quieras con él. Sin embargo, si alteras la variable global $wp_query
, entonces estás en el espacio de nombres global afectando a cualquier script que esté usando concurrentemente esa variable. Y si haces algo para cambiar los datos en ella, también debes restablecerla después de que hayas terminado de usarla.

Si estás utilizando una consulta personalizada como esta:
$cat = new WP_query();
$cat->query("cat=19,20,-23&showposts=5&orderby=rand");
while ($cat->have_posts()) : $cat->the_post();
$data = get_post_meta( $post->ID, 'key', true );
$img_arrays []= $data['productimage'];
$lnk_arrays[] =get_permalink($post_ID);
endwhile;
wp_reset_query();
Entonces no tendrás problemas. De lo contrario, si en la misma página hay otro bucle, es probable que obtengas algunos resultados inesperados. No utilicé wp_reset_query() en el código anterior (que estaba ubicado en mi archivo header.php). Luego, cuando ingresaba a single.php, principalmente obtenía las páginas de detalles de otras categorías, lo cual era frustrante. Más tarde, me di cuenta de que había olvidado reiniciar la consulta al principio. Pronto, comenzó a funcionar perfectamente.
