Post Formats in WordPress 3.1 – keeping your sanity

A major new feature in WordPress 3.1, which was released on February 23, 2011, is Post Formats. While maybe not game changing, it is a powerful feature that provides an elegant way to customize how a post looks in a standardized, portable way.

Many theme developers used categories or custom taxonomies to provide the same functionality, but in an ad-hoc way. Post formats are a replacement for hacking categories to customize the display of specific posts. It allows you to select a format from a predefined list.

In technical terms, post formats are a new taxonomy, a new box in the Post Edit screen, and a set of functions that expose the selected values to the theme.

Post formats are not customizable. The theme must specifically add support for them, and must activate specific formats, but new formats cannot be added. The reason for this is portability and standardization; Otto on WordPress has a great writeup about the reason behind this standardization.

To activate post formats in your theme, put this in functions.php:

add_theme_support( 'post-formats', array( 'aside', 'gallery' ) );

This function must be called before the init hook, “after_setup_theme” is a good hook to use, according to the Codex.

The second parameter is a list of post formats to activate. Each that you list will appear in the “Format” box in the post edit screen. You can only choose from the preselected list, any non-standard formats will be ignored; I know, I tried using “dog”, “cat”, “food”. Here is the list of acceptible formats:

  • aside
  • gallery
  • link
  • image
  • quote
  • status
  • video
  • audio
  • chat

The theme developer has the freedom to implement and style these formats as they please, but they are obviously geared toward specific, common uses, which adds to the standardization and portability we discussed earlier.

Exposing the post format

A lot of people have already written about how to implement the post formats in your code. Be careful about where you read it, check the date. There are a lot of posts that were published before WordPress 3.1 was released, so they may not have the most current information. In addition to the Codex page on post formats, here are some other resources that will help give you an idea of what the loop code can look like:
http://www.snilesh.com/resources/wordpress/wordpress-3-1-post-formats/
http://bavotasan.com/tutorials/wordpress-3-1-post-formats/

The following template tag functions are provided to detect and utilize the post format:

Each accepts post_id as a parameter, or can be used within The Loop without providing the post_id. The functions we will probably use the most are get_post_format and has_post_format. Either can be used within The Loop like any other template tag function.

while (have_posts()) {
the_post();
if ( has_post_format( 'video' )) {
echo 'this is the video format';
}
}

From here, it’s pretty straightforward; refer to the resources I referenced earlier for more examples. Your loop code would have to test for each post format and put special handling code in if blocks. Is that the best way to handle it? No, I have a better idea.

Keep your sanity using template parts

Do you use the loop template part? If not, you should. It allows you to put the code for your loop into its own file, keeping it separate and allowing clean re-use of the loop code across many different templates. Before this was an option, we would have identical code on several different template files, or we would just use include_once() to get our custom loop template.

The function get_template_part ($slug,$name) allows us to safely include a template file. This is often used to get the loop: get_template_part(‘loop’), which allows us to keep several different loop files: get_template_part(‘loop’,’page’) which gets loop-page.php or get_template_part(‘loop’,’post’) which gets loop-post.php. The parameters accepted are not limited to predefined template types, so we can use it within our loop template to grab a format sub-template:


while (have_posts()) {
the_post();

if (has_post_format(‘aside’)) {
get_template_part(‘formats’,’aside’);
} else if (has_post_format(‘gallery’)) {
get_template_part(‘formats’,’gallery’);
} else {
get_template_part(‘formats’,’standard’);
}
}

This setup will allow you to put your format-specific code in sub-templates:
formats-aside.php
formats-standard.php
formats-gallery.php

Another way to go about it, using the get_post_format() function, which will allow us to avoid the if/else blocks:


if ( have_posts() ) {
the_post();
$format = get_post_format();
if (! $format) {
$format = 'standard';
}
get_template_part('formats',$format);
}

I am a proponent of clean, reused and manageable code, so this method really appeals to me. One thing to look out for is if a post format is selected that you haven’t added a child template for. In this case, get_template_part() fails somewhat gracefully by not doing anything, but does not provide any way for you to determine if it was able to find the template, so be sure you have child templates for all the post formats you have enabled! The worst case scenario is that an unsupported format will result in a blank post, but there are ways to provide a fallback, such as using output buffering to assign the contents to a variable and testing to see if it’s empty.

Summary

Post formats provide a powerful way to customize how individual posts are displayed and formatted, in a standardized and portable way. It will allow blogs to visibly show differences in different types of posts, and really expands the flexibility of WordPress. There is already a lot of good information out there, but be sure it’s current as much of it was published before the feature was finalized. Using the child template setup, you can find a manageable way to organize your format code. Have fun, leave a comment if you have a question or something to say.

Leave a Reply