Global rewind_posts
File: wp-includes/query.php
784: /**
785: * Rewind the loop posts.
786: *
787: * @since 1.5.0
788: *
789: * @global WP_Query $wp_query Global WP_Query instance.
790: */
791: function rewind_posts() {
792: global $wp_query;
793: $wp_query->rewind_posts();
794: }
and rewind_posts
from WP_Query
class.
File: wp-includes/class-wp-query.php
3144: * Rewind the posts and reset post index.
3145: *
3146: * @since 1.5.0
3147: * @access public
3148: */
3149: public function rewind_posts() {
3150: $this->current_post = -1;
3151: if ( $this->post_count > 0 ) {
3152: $this->post = $this->posts[0];
3153: }
3154: }
can help us understand we are actually in the context of $wp_query
object when we are rewinding using the global rewind_posts
.
The codex pointer you set:
// main loop
<?php if (have_posts()) : while (have_posts()) : the_post(); ?>
<?php the_content(); ?>
<?php endwhile; endif; ?>
// rewind
<?php rewind_posts(); ?>
// new loop
<?php while (have_posts()) : the_post(); ?>
<?php the_content(); ?>
<?php endwhile; ?>
suggests that this has to do something with the $the_post
method.
So, what is the nature of the_post()
?
File: /class-wp-query.php
3095: public function the_post() {
3096: global $post;
3097: $this->in_the_loop = true;
3098:
3099: if ( $this->current_post == -1 ) // loop has just started
3100: /**
3101: * Fires once the loop is started.
3102: *
3103: * @since 2.0.0
3104: *
3105: * @param WP_Query &$this The WP_Query instance (passed by reference).
3106: */
3107: do_action_ref_array( 'loop_start', array( &$this ) );
3108:
3109: $post = $this->next_post();
3110: $this->setup_postdata( $post );
3111: }
At least we can understand that there is a global $post
object being set each time we iterate the while
loop.
The key for understanding is the next_post()
method.
File: wp-includes/class-wp-query.php
3068: /**
3069: * Set up the next post and iterate current post index.
3070: *
3071: * @since 1.5.0
3072: * @access public
3073: *
3074: * @return WP_Post Next post.
3075: */
3076: public function next_post() {
3077:
3078: $this->current_post++;
3079:
3080: $this->post = $this->posts[$this->current_post];
3081: return $this->post;
3082: }
That method finally explains we increment the current post pointer:
$this->current_post++;
Note that in the expression above the whole variable $this->current_post
will be incremented.
($this->current_post)++;
This is equivalent to:
$this->current_post = $this->current_post + 1;
for those that hate to admit the syntax $this->current_post++;
is pretty cool to increment a variable.
To recap:
Since we called the_post()
and increased the $this->current_post
pointer we need now to set this pointer to -1, if we plan to loop again.
3149: public function rewind_posts() {
3150: $this->current_post = -1;
3151: if ( $this->post_count > 0 ) {
3152: $this->post = $this->posts[0];
3153: }
3154: }
Strange enought, but it works.