setup_postdata()
云策文档标注
概述
setup_postdata() 函数用于设置全局文章数据,以便在自定义查询结果中使用模板标签。它填充多个全局变量,但不更新 $post 全局变量,因此开发者需手动处理以避免潜在问题。
关键要点
- 函数参数:接受 WP_Post 实例、文章对象或文章 ID,为必需参数。
- 返回值:成功时返回 true。
- 功能:填充 $id、$authordata、$currentday、$currentmonth、$page、$pages、$multipage、$more、$numpages 等全局变量,支持模板标签在当前文章上下文中工作。
- 注意事项:不更新 $post 全局变量,需开发者手动赋值,否则可能导致与使用 $post 的钩子冲突。
- 相关函数:WP_Query::setup_postdata() 是其内部实现。
代码示例
// 示例:在自定义查询中使用 setup_postdata() 和 wp_reset_postdata()
$myposts = get_posts( array(
'numberposts' => 5,
'offset' => 1,
'category' => 1
) );
if ( $myposts ) :
foreach ( $myposts as $post ) :
setup_postdata( $post );
// 使用模板标签,如 the_title()
?>
<h2><?php the_title(); ?></h2>
<?php
endforeach;
wp_reset_postdata();
endif;注意事项
- 调用 setup_postdata() 后,必须手动将文章对象赋值给全局 $post 变量,以确保一致性。
- 使用 wp_reset_postdata() 重置全局变量,避免影响后续循环。
- 根据 WordPress 编码标准,覆盖全局变量可能引发警告,建议谨慎使用并遵循最佳实践。
原文内容
Set up global post data.
Parameters
Source
function setup_postdata( $post ) {
global $wp_query;
if ( ! empty( $wp_query ) && $wp_query instanceof WP_Query ) {
return $wp_query->setup_postdata( $post );
}
return false;
}
Skip to note 7 content
mslade
An important note about
setup_postdataand the$postglobal:setup_postdata( $new_post )sets various globals related to the current post but it does not update the$postglobal. This disjoint can cause problems both in WP internals and in plugins/themes.Therefore if you call
setup_postdata( $new_post ), you should also assign it to the global$postobject.Skip to note 8 content
Aurovrata Venet
<ul> 5, 'offset' => 1, 'category' => 1 ) ); if ( $myposts ) : foreach ( $myposts as $post ) : setup_postdata( $post ); ?> <li><a href="<?php the_permalink(); ?>"></a></li> endforeach; wp_reset_postdata(); endif; ?> </ul>Skip to note 9 content
Ahmad Karim
Example of using
setup_postdatain a custom query:global $wpdb, $post; $query = "SELECT * FROM `wp_posts` WHERE `post_type` = 'cpt_1' AND `post_status` = 'publish' AND `comment_count` > 0 LIMIT 5"; $result = $wpdb->get_results($query, OBJECT); if ( $result && count($result) > 0 ): echo '<ol>'; foreach ($result as $post): setup_postdata($post); echo '<li>'; the_title(); echo '</li>'; endforeach; echo '</ol>'; wp_reset_postdata(); endif;Skip to note 10 content
stratboy
Here’s a good simple working example that also assigns the global $post before passing it to
setup_postdata.// ... your custom query..., and then: global $post; // Call global $post variable foreach ( $your_posts as $current_post ) { $post = $current_post; // Set $post global variable to the current post object setup_postdata( $post ); // Set up "environment" for template tags // Use template tags normally the_title(); the_post_thumbnail( 'large' ); the_excerpt(); // Or the_content(), the_permalink(), etc. } wp_reset_postdata();$post, unless you know you need to.Skip to note 11 content
Codex
Example 1
<ul> 5, 'offset' => 1, 'category' => 1 ) ); if ( $myposts ) : foreach ( $myposts as $mypost ) : setup_postdata( $mypost ); ?> <li><a href="<?php the_permalink(); ?>"></a></li> endforeach; wp_reset_postdata(); endif; ?> </ul>Skip to note 12 content
Zane Matthew
Note, it is probably best not to use this function, although it is neat, it goes against WordPress’ own coding standards.
Issue reported here, back in 2017.
If you use this function, and run PHPCS with WordPress standards you’ll see this error:
24 | ERROR | [ ] Overriding WordPress globals is prohibited. Found assignment to $post