The WordPress LoopIf you’ve already gone through the first two parts of this series, you are well on your way to putting together a WordPress theme. It might seem a little daunting at first, but reading through these tutorials one by one and taking the time to understand it all will give you everything you need to create a WordPress theme to share with the community.

The WordPress loop is where all the magic happens. Understanding how it works will definitely make things a lot easier, because if you can’t wrap your head around the loop, it might just throw you for one (my wife loves a good pun so I wanted to add that in for her). I actually didn’t discuss the loop in my WordCamp presentation because I thought it was a topic all in itself. So this one is kind of a bonus.

The WordPress Loop

You’ve probably gone through a tutorial and reached a point where it told you to “add it to the loop,” and you thought to yourself, “What the hell’s a loop?” In WordPress, the loop is the database call that checks for posts and displays them if they exist. Certain functions will only work within the loop because they require certain variables to be set and those variables only exist within the loop, where all the post information is stored.

If you open up the single.php file from a theme, you’ll see something like this:

<?php if (have_posts()) : while (have_posts()) : the_post(); ?>
	<div class="post" id="post-<?php the_ID(); ?>">
		<h1><?php the_title(); ?></h1>
		<div class="thedate"><?php the_time(get_option('date_format')); ?></div>
		<div class="entry">
			<?php the_content(); ?>
			<?php the_tags('<p class="tags"><small>Tags: '), ', ', '</small></p>'); ?>
			<p class="postmetadata alt">
				<small>
					<?php _e('This entry was posted on ').the_time(get_option('date_format'))._e(' at ').the_time()._e(' and is filed under ').the_category(', '); echo '. '; _e('You can follow any responses to this entry through the ').post_comments_feed_link('RSS 2.0')._e(' feed.'); ?>
				</small>
			</p>
		</div>
		<?php wp_link_pages(array('before' => '<p><strong>'.__('Pages').'</strong> ', 'after' => '</p>', 'next_or_number' => 'number')); ?>
	</div>
	<?php comments_template(); ?>
<?php endwhile; else: ?>
<p><?php _e("Sorry, no posts matched your criteria."); ?></p>
<?php endif; ?>

That is an example of a typical loop in a WordPress theme. It works by querying the database to fetch all the post’s stored information. That information becomes accessible by using WordPress functions within the loop to display certain elements wherever you want. On the single post page, only one post is queried. On category pages, multiple posts are queried and looped through.

Breaking down the loop to its basic elements would look something like this:

<?php if (have_posts()) : while (have_posts()) : the_post(); ?>
     Do something here.
<?php endwhile; else: ?>
     Sorry, no posts matched your criteria.
<?php endif; ?>

All it means is this: IF you have posts, continue. WHILE you still have posts, loop through them all, then stop. ELSE there are no posts, display a message saying there are no posts. The actual loop is within the WHILE statement, since that is actually where it will loop through all the post and fetch their data.

As you can see, the loop is pretty important, and that’s why you’ll find it in all of the following basic template files:

  • archive.php (used for categories, tags and archives)
  • index.php (what you want to appear on your front page)
  • page.php (how your pages will be displayed)
  • search.php (how your search page will be displayed)
  • single.php (how your posts will be displayed)

The easiest way to develop these basic template files is to copy them over from a theme like TwentyTen, and customize them to work with your theme. This is not considered stealing, by the way, since the WordPress community is open source. That means the code is there for you to use and modify as you see fit. If you don’t modify it at all though, you better give credit where credit is due.

The Loop in WordPress 3.0

With the release of WordPress 3.0, a new file was introduced that allows you to store your loop(s) in one place. Using the new loop.php file is not a requirement, but it does make things a lot easier. If you take a look at the single.php above once again, you’ll see how it looks with the loop included in the file. Now see how we can simplify it by using the new loop.php file:

<?php get_template_part( 'loop', 'single' ); ?>

Now we can add our loop into loop.php and it would look something like this:

<?php if (!have_posts()) : ?>
	<p><?php _e("Sorry, no posts matched your criteria."); ?></p>
<?php endif; ?>

<?php while (have_posts()) : the_post(); ?>
	<div class="post" id="post-<?php the_ID(); ?>">
		<h1><?php the_title(); ?></h1>
		<div class="thedate"><?php the_time(get_option('date_format')); ?></div>
		<div class="entry">
			<?php the_content(); ?>
			<?php the_tags('<p class="tags"><small>Tags: '), ', ', '</small></p>'); ?>
			<p class="postmetadata alt">
				<small>
					<?php _e('This entry was posted on ').the_time(get_option('date_format'))._e(' at ').the_time()._e(' and is filed under ').the_category(', '); echo '. '; _e('You can follow any responses to this entry through the ').post_comments_feed_link('RSS 2.0')._e(' feed.'); ?>
				</small>
			</p>
		</div>
		<?php wp_link_pages(array('before' => '<p><strong>'.__('Pages').'</strong> ', 'after' => '</p>', 'next_or_number' => 'number')); ?>
	</div>
	<?php comments_template(); ?>
<?php endwhile; ?>

It might seem like you’ve just divided your code into two files, which you have, but now that loop can also be accessed by other template files. The advantage is plain to see: one loop can control your whole theme. Especially if you want to get fancy and use conditional tags to let your loop know what to display and when to display it. Adding a conditional tag to the content function would allow you to show the content only on single post pages, and the excerpt on all other pages:

<?php if(is_single()) the_content(); else the_excerpt(); ?>

Call the loop in your index.php file using:

<?php get_template_part( 'loop', 'index' ); ?>

On your index page you will get the excerpt instead of the content. You can go as far as you want with conditional tags in your main loop. This will make it easier to modify your code and control how your post elements will be displayed within your theme. Take a look at loop.php in TwentyTen to see how much you can do with just one loop.

Multiple Loops

There may come a time when you want to have multiple loops in one template file. This might be a necessity for your theme if you’re developing a grid style layout for your front page, or want to have a listing of recent posts somewhere. You should never have two regular loops running on the same page because it will cause problems. That’s why WordPress has the wp_query() function.

wp_query() allows you to have as many loops as you wish on a single page, since each of those loops will be self-contained with a custom query, using custom variables. The easiest way of explaining it is by showing it.

<?php
$featuredPosts = new WP_Query();
$featuredPosts->query('posts_per_page=5&cat=1');
while ($featuredPosts->have_posts()) : $featuredPosts->the_post();
     // add stuff here
endwhile;
?>

That’s a self-contained custom loop that will not conflict with your main loop. If by chance, things do get a little funky, you can always reset the page’s main loop query by using:

<?php wp_reset_query(); ?>

You can find more information on the custom loop query in the codex at http://codex.wordpress.org/Function_Reference/WP_Query.

What’s New with 3.0

WordPress 3.0 introduced some new features that make it easier for theme developers to add amazing functionality to their themes without much effort. Check back tomorrow for more on that subject.

Part 1: Guidelines for Developing a WordPress Theme
Part 2: Basic Template Files
Part 3: Understand The WordPress Loop
Part 4: Adding Theme Options
Part 5: Making Money

Fruit Loops image by Webking, provided by Pixmac, and modified slightly by c.bavota.