函数文档

wp_reset_postdata()

💡 云策文档标注

概述

wp_reset_postdata() 函数用于在 WordPress 开发中,当使用辅助查询循环(如 WP_Query)后,恢复全局 $post 变量到主查询循环的当前文章,确保模板标签正确引用主查询内容。

关键要点

  • 主要用途:在辅助查询循环(如 new WP_Query)后调用,以恢复 $post 全局变量到主查询的当前文章,避免模板标签错误引用辅助查询数据。
  • 工作原理:通过调用全局 $wp_query 的 reset_postdata() 方法,将 $post 重置为主查询状态。
  • 使用场景:适用于主题模板或插件文件中,当使用 the_post() 方法遍历辅助查询时,必须在循环后调用 wp_reset_postdata() 以恢复主查询上下文。
  • 注意事项:仅在辅助查询成功返回文章时才调用 wp_reset_postdata(),否则可能错误重置先前查询的数据;在管理面板中可能存在已知 bug,导致功能异常,需注意兼容性问题。

代码示例

$args = array( 'posts_per_page' => 3 );
$sec_query = new WP_Query( $args );
if ( $sec_query->have_posts() ) :
    while ( $sec_query->have_posts() ) : $sec_query->the_post();
        // 输出文章内容
    endwhile;
    wp_reset_postdata(); // 恢复主查询
endif;

📄 原文内容

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

 3 );

// the query
$sec_query = new WP_Query( $args );
?>

have_posts() ) : ?>

<!-- start of the loop. the_post() sets the global $post variable -->
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 -->







<!-- reset global post variable. After this point, we are back to the Main Query object -->

Source

function wp_reset_postdata() {
	global $wp_query;

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

Changelog

Version Description
3.0.0 Introduced.

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.

     3 );
    
    // the query
    $the_query = new WP_Query( $args );
    ?>
    
    have_posts() ) : ?>
    
    	<!-- start of the secondary loop -->
    	have_posts() ) : $the_query->the_post(); ?>
    		
    		
    	
    	<!-- end of the secondary loop -->
    
    	<!-- put pagination functions here -->
    
    
    
    	<p></p>
    
    
    <!-- reset the main query loop -->
    

  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