Have you ever downloaded a WordPress theme with sloppy code?
There’s probably a good chance you have. Either more than 90% of themes have sloppy code or by some astronomically improbable chance, I only ever happen to download themes with sloppy code. I’m hoping to open the eyes of at least a small percentage of theme authors and help usher in a new era of neater code.
I’m going to break down the basics of the WordPress Loop in this post and help you write cleaner themes. I’ll explain each line of code along the way and point out references to the outside information.
I know. I know. A post about The Loop doesn’t sound too exciting, but maybe this is just what we need — a journey back to the basics. Take a look at the example file to see what The Loop should look like. The important thing here is not to focus on the code but to notice how the code is formatted. See the plentiful whitespace? I’d like to see more of that in themes.
- Example Loop (use to follow along with the post)
More seasoned theme authors might have slightly different methods for displaying content than in this guide. This should serve as a reference, or a starting point, for using correct WordPress template tags and proper code formatting.
What is The Loop?
The Loop is what makes WordPress go. It’s how all of the WordPress magic happens. It’s the most important thing. Everything else is secondary.
To be more specific, it cycles through posts, allowing us to display them in any manner we want.
The first step: Opening The Loop
Before we display our posts, we have to open The Loop. Most theme authors know how to get this right, which at least shows potential.
<?php if(have_posts()) : while(have_posts()) : the_post(); ?>
Notice that before the loop starts, we are actually checking if there are any posts. The
if(have_posts()) checks if there are any posts available. If there are posts, we should loop through them.
while(have_posts()) begins the loop. It will begin a continuous cycle, looping through each post available for display.
the_post() calls up information about the post that we’ll be using and sets the global
That’s quite a lot for one line of code, right? It’s pretty important stuff.
Displaying the post
This next step is all about a simple line of code that is commonly referred to as the post div. We want to wrap all of our post content into one
div to kind of hold it all together.
<div id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
the_ID() gives us the ID of the post. Each post has a unique ID.
post_class() is a WordPress 2.7+ function that provides post-specific classes for use in your stylesheet. This is a neat feature because you can display posts with specific tags, categories, and so on differently than other posts.
The post title
There are a few different ways you could code the post title, but I’ll show you my favorite method.
<?php the_title('<h2 class="entry-title"><a href="' . get_permalink() . '" title="' . the_title_attribute('echo=0') . '" rel="bookmark">', '</a></h2>'); ?>
the_title() is the WordPress template tag for showing the post title. Pretty simple, right? It takes up to three optional parameters:
before (before the title),
after (after the title), and
display (whether to display or return it for use in a function).
get_permalink() template tag gives us the post URL. It’s the permanent link to the post.
the_title_attribute() is a template tag I don’t see often enough. Anytime you put a post title in the
title attribute of a hyperlink, don’t use
the_title_attribute(). This takes care of those pesky posts with things such as quotation marks, leaving us with valid XHTML.
Alternately, you can use
single_post_title() for displaying a post title in the
Byline is a term often used in journalism that denotes the writer of a story. Blogs are essentially like newspapers or magazines in this way. You could also go as far as adding a dateline, but I like to add my post author, post time, and edit link all within the byline paragraph before the post text.
<p class="byline"> <span class="author vcard"><?php the_author_posts_link(); ?></span> <span class="sep">|</span> <abbr class="published" title="<?php the_time(__('l, F jS, Y, g:i a', 'example')); ?>"><?php the_time(__('F j, Y', 'example')); ?></abbr> <?php edit_post_link(__('Edit', 'example'), ' <span class="sep">|</span> <span class="edit">', '</span> '); ?> </p>
The first template tag we see in this block of code is
the_author_posts_link(). This displays a link to the author’s archive page. Alternately, you could use
the_author if you only want to display the author’s display name.
the_time() displays when the post was published. There are several formats you can use for this to get just the right look. You may be wondering why there are two instances of
the_time() in my code. The first is set in an
title attribute. I’ve done this so that when a reader hovers over the time display, they’ll see an expanded version with more details.
edit_post_link() displays a link to edit the post to only logged-in users that have the capability to edit posts. Otherwise, the link is not shown. Clicking on it will take you to the edit post screen in the WordPress dashboard.
- Author template tags
- Date and time formatting
Displaying the post content
There are two different methods for displaying post content. You can display the entire post or an excerpt. The first method I’ll show you is of displaying the entire post. You should use always use this in
page.php. Most themes will use this method in
index.php as well.
<div class="entry-content"> <?php the_content(__('Continue reading', 'example')); ?> <?php wp_link_pages('before=<p class="pages">' . __('Pages:','example') . '&after=</p>'); ?> </div>
Note that I’m wrapping the post content in its own
div here. This gives us better separation and more styling options.
the_content() displays the entire post. It doesn’t get much simpler than that. Continue reading is the text shown in the link when the post author cuts off the post with the
wp_link_pages() is a piece of code that’s not added to enough themes. This is a vital piece of code! When an author uses the
<!--nextpage--> quicktag to break his or her posts into more than one page, we need to display the links to each page.
If you only want to display the excerpt of the post, follow along. Displaying the excerpt is useful for any archive-based template files, such as
<div class="entry-summary"> <?php the_excerpt(); ?> </div>
This will display either the first 55 words of a post or the text entered into the Excerpt textarea when on the Write Post panel in the WordPress dashboard.
- Advanced post editing (i.e. writing excerpts)
- WordPress definition of excerpt
- Customizing the read more
- Write Post Subpanel: Quicktags (
Showing the post metadata
After showing the post content, I generally display the post metadata, which is additional information about the post. I like to put the category, tags, and comments link in this section. You can combine this with the byline and/or mix and match the two however you want.
<p class="entry-meta"> <span class="categories"><?php _e('Posted in', 'example'); ?> <?php the_category(', '); ?></span> <?php the_tags('<span class="tags"> <span class="sep">|</span> ' . __('Tagged', 'example') . ' ', ', ', '</span>'); ?> <span class="sep">|</span> <?php comments_popup_link(__('Leave a response', 'example'), __('1 Response', 'example'), __('% Responses', 'example'), 'comments-link', __('Comments closed', 'example')); ?> </p>
the_category() shows your post categories. I’m using a comma as the separator in the code above. You can use anything you like there to separate multiple categories.
the_tags() displays all of your post tags. Notice how it looks a bit different than the display of the categories though — everything is tucked neatly away inside of
the_tags(). Doing it this way assures that the tags or any additional text you add will only display if the user tags the post. This keeps users that don’t use tags from getting frustrated with seeing Tagged followed by nothing.
The last part of the post metadata that we’ll show is a link to the comments of the post. The template tag for this is
comments_popup_link(). It’s important to use this because it serves two purposes: links to a pop-up window for users that are using pop-up comments or links to the post comments for users that aren’t using pop-up comments. Note that this won’t work on
page.php because you’ll already be on the page with the comments list.
Closing The Loop
The tough part is over. Now we must close this thing off to make it all work correctly. We must also display a message in case no posts were found.
</div> <?php endwhile; ?> <?php else : ?> <p class="no-posts"><?php _e('Sorry, no posts matched your criteria', 'example'); ?></p> <?php endif; ?>
The more observant of you may have noticed the several instances of text with the word
example in it, like these lines:
__('Pages:','example') _e('Sorry, no posts matched your criteria', 'example')
This process is referred to as localization, which makes your WordPress theme ready for translation. I’ll cover this in a later post in more detail. Making your theme ready to use in any language should be something to consider.
Start writing cleaner loops
Now that I’ve shown you the proper template tags and have pointed out loads of resources, I expect you theme authors to start making cleaner themes.
Think about your theme users. I know most of us theme developers don’t like for users to muddle in our code, but the honest truth is that end users tinker with the code. Of course, there are countless ways to do things without diving into the templates, but they’ll continue doing it anyway. The best thing we can do for them is make the code as readable as possible.
Clean code also helps others learn from what you’ve done. Why not help a new theme designer looking at your theme code by making things a little neater?