[wp-hackers] Knowing when you're in The Loop, and when you're not

Mark Jaquith mark.wordpress at txfx.net
Sat Jul 16 03:57:53 GMT 2005

Kaf Oseo wrote:

> I have a copyright mark plugin which bases it's output in part on the
> query type, so single posts, Pages and archive queries display the year
> for the current content, while elsewhere a range (first-last) is used.
> When the plugin function blog_copyright() is called within The Loop, for
> query types other than those listed I'd like it to be "Loop aware" and
> display the year of the current post, instead of a range.
> Testing on $post or something like get_the_author() works to a degree,
> but as these leak out beyond The Loop calling the function afterwards
> provides false positives. I had luck with have_posts(), but this fails
> in the last post of The Loop, and won't work if using a foreach() loop
> statement.
> I'm about to go the way of a parameter, but before taking such a drastic
> measure (...), is there some variable or mechanism I can test on that's
> only around while The Loop is in effect?

Hm... This is a tricky one.  The problem is that how the variables look 
for the duration of the final run through the loop is the same as how 
they look after the loop.

The only function that gets run after the last run of the loop is 
have_posts() (which is $wp_query->have_posts() ).

> function have_posts() {
>     if ($this->current_post + 1 < $this->post_count) {
>     return true;
>     }
>     return false;
>     }

If modified thusly, we would be able to tell when the post has expired:

> function have_posts() {
>     if ($this->current_post + 1 < $this->post_count) {
>     return true;
>     } elseif ($this->current_post + 1 == $this->post_count) {
>     $this->current_post++; // set the current_post to be one higher 
> than the post_count
>     return false;
>     }    
>     return false;
>     }

This way, when you reach the first case that fails (when the 
current_post + 1 is equal to the post_count), you push it one more.

Then, this function (within the class) could test for "in the loop"-ness

> function in_the_loop() {
>     if ($this->post_count && $this->current_post + 2 == 
> $this->post_count) {
>     return false; // loop has been run already
>     } elseif (!$this->current_post) {
>     return false; // loop hasn't started
>     } else {
>     return true; // in the loop
>     }
> }

and then of course, outside the class (like in functions.php):

> function in_the_loop() {
>     global $wp_query;
>     return $wp_query->in_the_loop();
> }


I may just not be seeing it, but I really can't think of another way to 
tell if you're in the loop or not.  Nothing is run at the very bottom of 
the loop, and the only thing different from the runthrough of the last 
loop iteration and the end is that have_posts() is run again, and it 
currently doesn't change anything... only observes.

Mark Jaquith
MCincubus @ #wordpress

More information about the wp-hackers mailing list