wp_reset_postdata()

After looping through a separate query, this function restores the $post global to the current post in the main query.

More Information

Use this function to restore the context of the template tags from a secondary query loop back to the main query loop.

Differences between the main query loop and secondary query loops are:

  • the main query loop is based on the URL request and is initialised before theme templates are processed
  • secondary query loops are queries (using new WP_Query) in theme template or plugin files

A secondary query loop using $sec_query = new WP_Query() and $sec_query->the_post() affects the global $post variable. The global $post variable is used by template tags by default. wp_reset_postdata() restores the global $post variable to the current post in the main query (contained in the global $wp_query variable as opposed to the $sec_query variable), so that the template tags refer to the main query loop by default again.

Example

<?php $args = array( 'posts_per_page' => 3 ); // the query $sec_query = new WP_Query( $args ); ?> <?php if ( $sec_query->have_posts() ) : ?> <!-- start of the loop. the_post() sets the global $post variable --> <?php while ( $sec_query->have_posts() ) : $sec_query->the_post(); ?> <!-- template tags will return values from the post in the $sec_query object <?php the_title(); ?> <?php the_excerpt(); ?> <?php endwhile; ?><!-- end of the loop --> <?php else: ?> <?php _e( 'Sorry, no posts matched your criteria.' ); ?> <?php endif; ?> <!-- reset global post variable. After this point, we are back to the Main Query object --> <?php wp_reset_postdata(); ?>

Source

function wp_reset_postdata() {	global $wp_query;	if ( isset( $wp_query ) ) {	$wp_query->reset_postdata();	} } 

Changelog

VersionDescription
3.0.0Introduced.

User Contributed Notes

  1. Skip to note 4 content

    Example of secondary loop and reset

    Note: If you use the_post() with your query, you need to run wp_reset_postdata() afterwards to have template tags use the main query’s current post again.

    <?php // example args $args = array( 'posts_per_page' => 3 ); // the query $the_query = new WP_Query( $args ); ?> <?php if ( $the_query->have_posts() ) : ?>	<!-- start of the secondary loop -->	<?php while ( $the_query->have_posts() ) : $the_query->the_post(); ?>	<?php the_title(); ?>	<?php the_excerpt(); ?>	<?php endwhile; ?>	<!-- end of the secondary loop -->	<!-- put pagination functions here --> <?php else: ?>	<p><?php _e( 'Sorry, no posts matched your criteria.' ); ?></p> <?php endif; ?> <!-- reset the main query loop --> <?php wp_reset_postdata(); ?>
  2. Skip to note 5 content

    WARNING, only reset the post data if the query is successful…

    $query = array( //some post query parameters ); $post_results = get_posts($query); if(!empty($post_results)){ //do something with your query results //invoke post data reset here wp_reset_postdata(); } //if you invoke it after the check and the result did not return any posts, it will reset the post data from a previous query wp_reset_postdata(); // WRONG
  3. Skip to note 6 content

    As I have just learned, there is a long-standing bug (reported 12 years ago) that results in wp_reset_postdata() not working properly in the admin panel.

    In my case, metabox values were not saved on a specific page with a custom WP_Query even though I was calling wp_reset_postdata() afterwards. The error message I had (visible through the browser console -> network tab) was:
    400: A post ID mismatch has been detected.

    I hope that this comment saves someone a few hours digging…

    More info & working workaround:
    Can’t wp_reset_postdata after custom WP_Query in an admin edit page

You must log in before being able to contribute a note or feedback.