Justin Tadlock

Using WP_Query properties instead of an iterator

Screenshot of complex WordPress post loop

Sometimes, when running through a post loop, theme authors need to do something special, depending on the current post in the loop or the total post count. For example, displaying ad space between the first and second post. Or, as in the screenshot above, displaying posts with drastically different markup and output.

This tutorial will cover the basics of using some of the WP_Query properties to handle this.

The common method

One of the techniques I often see is the use of the $i iterator, which is common in programming. Here’s an example:

<?php $loop = new WP_Query(); ?>

<?php $i = 0; ?>

<?php while ( $loop->have_posts() ) : $loop->the_post(); ?>

        <?php if ( 1 === $i ) :?>

                <!-- Output something -->

        <?php endif; ?>

        <?php ++$i; ?>

<?php endwhile; ?>

Core WordPress already has you covered. $i isn’t necessary.

Using the post count

WP_Query objects keep track of the current post in the loop. This is the current_post property. The thing to keep in mind is that the first post will be 0. This shouldn’t come as a surprise to anyone familiar with how loops work though.

Here’s an example of the earlier code rewritten to use current_post.

<?php $loop = new WP_Query(); ?>

<?php while ( $loop->have_posts() ) : $loop->the_post(); ?>

        <?php if ( 1 === $loop->current_post ) :?>

                <!-- Output something -->

        <?php endif; ?>

<?php endwhile; ?>

Getting more complex

In the screenshot at the top of this post, you’ll see that I have two sections:

  • A single post displaying the title, image, and excerpt.
  • A list of 5 posts next to it.

This is all done with a single query. However, the markup needed to change drastically after the first post.

<?php $loop = new WP_Query(); ?>

<?php while ( $loop->have_posts() ) : $loop->the_post(); ?>

    <?php if ( 0 == $loop->current_post ) : // If first post, show title, excerpt, and image. ?>

        <div class="post">

            <h3 class="entry-title"><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h3>

            <?php the_post_thumbnail(); ?>

            <div class="entry-summary">
                <?php the_excerpt(); ?>
            </div>

        </div>

    <?php else : // If not the first post, add the entry titles as list items. ?>

        <?php if ( 1 == $loop->current_post ) : ?>
            <ul class="post-list">
        <?php endif; ?>

        <li>
            <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
            <time <?php hybrid_attr( 'entry-published' ); ?>><?php echo get_the_date(); ?></time>
        </li>

    <?php endif; ?>

<?php endwhile; ?>

<?php if ( 1 < $loop->post_count ) : ?>
    </ul>
<?php endif; ?>

I used post_count there at the end to check the total post count. If it was greater than 1 (the number needed before making the list), I output the closing </ul>.

More cool things

There are probably even more advanced examples that people can do. I just wanted to share the basic foundation you can use to cut back on a little code.

Also, the main query variable is global $wp_query if you want to play around with it. If you’re ever looking for wild afternoon, var_dump() that on a page.