WordPress: taking control over the Loop

As web developers, we all know the importance of gaining a full control over the WordPress Loop. Basically, a WordPress Loop is nothing more than a while PHP loop. As such, we can use all the tricks and techniques we normally use on other similar loops. In this article, I'll cover some of these techniques in details.

Using counters

We can initialize a counter just outside the Loop to keep track of the current post we're working on:

<?php
$i = 0;
while(have_posts()) {
	the_post();
	$i++;
	$even_odd = ($i % 2 == 0) ? 'even' : 'odd';
?>
<div class="post <?php echo $even_odd; ?>">

</div>
<?php
}
?>

In this case, we simply add a CSS class to all even and odd posts. This is only a basic usage of counters. A more advanced use involves some if tests during the Loop's execution.

For example, suppose that you want to display only the first post in full and an unordered list containing only the title and the link of subsequent posts. Here's how you can do.

<?php
$i = 0;
while(have_posts()) {
   	
   		the_post();
   		
   		$i++;
   		
   		if($i == 1) { // First post ?>
   		
   			<div id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
   		
   				<h2 class="entry-title"><a href="<?php the_permalink(); ?>" title="<?php the_title();?>" rel="bookmark"><?php the_title(); ?></a></h2>
   			
   				<div class="entry-content"><?php the_content();?></div>
   			
   			</div>
   			<h2>Other posts</h2>
   			
   			<ul>
   		<?php
   		} else {?>
   		
   		
   		    <li><a href="<?php the_permalink(); ?>" title="<?php the_title();?>" rel="bookmark"><?php the_title(); ?></a></li>
   		    
   		    
   		    <?php if($i == 5) { // Last post ?>
   		    
   		    </ul>
   		
   			
   		
   		
   		<?php
   		
   		    }
   		
   		}
   	
   	}

?>

Our Loop contains six posts per page. Our first test checks whether the counter is equal to 1, so that we're sure we're on the very first post. Then our second test, instead, checks whether the counter is on the last post, so that we can close our unordered list.

Taming the More jump

Suppose that you've regularly used the <--more--> separator on all your posts. Now you want to display the entire content of the first post on your home page, followed by an unordered list of post links.

Unfortunately, the More jump prevents your posts from being displayed in full, showing only the portion of content up to the "More" link. This problem can be easily solved if we use the global $more variable.

This variable tells WordPress how the More jump should be handled. By default, this variable is set on 0, meaning that the post content should be truncated. A value of -1, instead, instructs WordPress to display the post content in full.

Here's how you can do:

<?php

   $i = 0;
   global $more; 
   $more = -1;
   
   	while(have_posts()) {
   	
   		the_post();
   		
   		$i++;
   		
   		if($i == 1) {?>
   		
   			<div id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
   		
   			<h2 class="entry-title"><a href="<?php the_permalink(); ?>" title="<?php the_title();?>" rel="bookmark"><?php the_title(); ?></a></h2>
   			
   			<div class="entry-content">
   			    
				<?php 
				if ($more == -1) {
				
				the_content(); 
				
				}
				
				$more = 0;
				?>
			</div>

   		
   			</div>
   			
   			<h2>Other posts</h2>
   			
   			<ul>

   		
   		
   		<?php
   		} else {?>
   		
   		
   		    <li><a href="<?php the_permalink(); ?>" title="<?php the_title();?>" rel="bookmark"><?php the_title(); ?></a></li>
   		    
   		    
   		    <?php if($i == 5) {?>
   		    
   		    </ul>
   		
   			
   		
   		
   		<?php
   		
   		    }
   		
   		}
   	
   	}

?>

After calling the_content(), we reset the $more variable to 0 so that the More jump will work as expected on all other posts.

Back to top