/ coding

WordPress: Omitting a horizontal rule after the last post

Related:Element+Element in CSS

The Strips WordPress theme that I’m building has a horizontal rule (<hr>) between each post on the main blog page. The <hr> is simply a centered black line that takes up half of the available width.

Having this <hr> separator between posts is fairly common on blogs. It’s not always a black line; some blogs use images or fancier decorative horizontal rules.

When coding this into a WordPress theme, you would add the <hr> tag into The Loop and the result would be something like this, repeated again and again:

  1. Title
  2. Thumbnail
  3. Excerpt
  4. <hr>

The issue here is that the <hr> is inserted after every post, even after the last one. This probably isn’t desirable because it’s the last post; there’s not another post coming to separate it from.

Even if there is a footer following the last post, it is likely to be so visually distinct from a post that having the separator is redundant.

Let’s get rid of it.


The problem in code

For the loop I described above, here’s what the code might look like:

<?php while ( have_posts()) : the_post(); ?>
	<article>
		<?php the_title() ?>
		<?php the_post_thumbnail(‘blog-thumb’); ?>
		<?php the_excerpt() ?>
		<hr>
	</article>		
<?php endwhile ?>

Again, this code has the problem of adding a <hr> after the final post, in addition to all of the other posts.

We need to insert a way for WordPress to check if a post is the last post. If it is the last post, we will tell WordPress not to add the <hr> tag.

Final post test: a solution in code

We create an if statement using <a href="“http://codex.wordpress.org/Class_Reference/WP_Query”">wp_query</a>:

<?php if( ($wp_query->current_post + 1) < ($wp_query->post_count) ) : ?>
	<!-- insert hr unless it’s the last post. -->
	<hr>
<?php endif ?>

The if statement above compares the number of the current post (current_post) in The Loop with the total number of posts to be shown on the page (post_count).

Based on this if statement, if the current post is not the final post shown on the page, a <hr> tag is added. Conversely, if it is the final post, the <hr> will not be added.

The full code

Here is The Loop with the final post test included.

<?php while ( have_posts()) : the_post(); ?>
	<article>
		<?php the_title() ?>
		<?php the_post_thumbnail(‘blog-thumb’); ?>
		<?php the_excerpt() ?>

		<!-- final post test -->
		<?php if( ($wp_query->current_post + 1) < ($wp_query->post_count) ) : ?>
			<!-- insert hr unless it’s the last post. -->
			<hr>
		<?php endif ?>

	</article>		
<?php endwhile ?>

Of course, you could use the final post test to do anything. Just change out the <hr> for whatever else you might like to add after all posts except for the last one.

Why the +1?

If you followed along in the code, you’re probably wondering about the + 1 in the if statement.

Here’s an educated guess:

  • post_count is a normal number: 0 if there are no posts shown; 5 if there are 5 posts.
  • current_post is a value from an array, which starts at 0; 0 for the first post, 1 for the second post.

Hence the need to add 1 to current_post when comparing.

I have a strong hunch this explanation is correct. Please correct me if I’m wrong.

Doing the opposite

You could also add something after the last post only using this same final post check. Just change the < to a == in the if statement:

<?php if( ($wp_query->current_post + 1) <strong>==</strong> ($wp_query->post_count) ) : ?>
	<!-- insert hr only if it’s the last post. -->
	<hr>
<?php endif ?>

But I’m not sure why this would be necessary. If something only needs to occur after the last post, I would simply add it after The Loop ends:

<?php while ( have_posts()) : the_post(); ?>
	<article>
		<?php the_title() ?>
		<?php the_post_thumbnail(‘blog-thumb’); ?>
		<?php the_excerpt() ?>
	</article>		
<?php endwhile ?>
<strong><hr></strong>