Using Post Formats with your custom WordPress Post Types

Since versión 3.1, WordPress introduced a new theme feature called Post Formats that, basically, allows us to divide a regular WordPress Post Type in subsets based on the nature of the information that a post includes, ie, you can have regular posts, but you can also have posts that specifically contain a video, or an image, etc. In case of the Post Type post, most of the popular WP themes already includes support for styling its Post Formats but, what can we do for using Post Formats in case of our custom Post Types?

macarons

The proposed method is quite easy and it simply extends the habitually used technic for dealing with Post Formats inside WordPress templates, in other words, we’ll create a refined system for loading the content-{$post_format_slug}.php subtemplates.

The name structure for Post Format templates

In the basic technique for loading subtemplates for styling the different Post Formats, the WP theme has the common collection of WordPress main templates (index.php, category.php, archive.php…) and in addition, it has a collection of subtemplates (for example content.php, content-video.php, content-aside.php…) that are called by the WordPress main templates for displaying each one of the specific formatted contents. The basic structure of the code is like this.

<?php
// for example inside index.php, but in any of the WordPress main templates
if ( have_posts() ) { 
    while ( have_posts() ) : the_post(); { 
        ?>
	<div id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
		<?php get_template_part( 'content', get_post_format() ); ?>
	</div>
        <?php
    }
}
// Rest of the code for main template
?>

And as you see, the most relevant part of this example is the use of the function get_post_format() that allows to use a different subtemplate according to the Post Format of the current Post, ie, if our list of last posts with their Post Formats is like this:

Post ID   | Post format 
-------------------------
2345      | video
2340      | standard
2331      | audio
2330      | standard
2327      | aside
2322      | audio
2319      | standard
2340      | standard
....

The list of used templates and subtemplates for displaying the main page of the website would be like this

index.php
   header.php
      // here we begin the while ( have_posts() ) structure
           content-video.php
           content.php
           content-audio.php
           content.php
           content-aside.php
           content-audio.php
           content.php
           content.php
           ... etc.
      // here we end the while structure
   sidebar.php
   footer.php
//END OF FILE index.php

While the code structure while { ... } goes through the array of posts, for each post a different content-{$post-format].php subtemplate is loaded.

The solution

On the basis of this idea, a possible approach for selecting the adequate template in case of Post Types elements that in addition have Post Format and thinking in the former example of index.php, it is to modify the second parameter that the WP function get_template_part() reveives. Instead of simply to give it the get_post_format() function result, we can give it the Post Type value of the current Post concatenated with the Post Format. See the next abridged example.

// before the change, the code was
get_template_part ( 'content', get_post_format() );
// so the function receives
// get_template_part ( 'content', one of these possible results {'', 'video', 'audio', 'aside', ... } );

// after the change, the code will be like this
get_template_part ( 'content', $post->post_type . '-' . get_post_format() );
// so the function will receive, for example for a post type for books, something like
// get_template_part ( 'content', one of these possible results {'book-', 'book-video', 'book-audio', 'book-aside', ... } );

Well, this is the main idea (to concatenate post_type and post_format), but this change is not automatic thus, we’ll have to do some changes in our theme.

The new subtemplates

This change begins with creating a new set of subtemplates php files inside our theme whose names have this structure content-{$post_type_slug}-{$post_format}.php.

For example, in the case of a new Post Type for Books, we will create a new set of php subtemplates files whose names will be like content-book-.php, content-book-video.php, content-book-aside.php, etc.

And if we would have got another Post Type that uses Post Formats (for example News), we should have to write a new set of subtemplates like content-news-.php, content-news-video.php, content-news-audio.php, content-news-aside.php, etc.

Changing the WordPress theme templates

Then, for loading properly these new sets of subtemplates, as we saw briefly above, we have to change the basic structure of the habitual WordPress theme templates (index.php, category.php, archive.php…).

For example, in the case of the index.php file of the theme, the new code could be like this:

<?php
// for example inside index.php, but in any of the WordPress main templates
if ( have_posts() ) { 
    while ( have_posts() ) : the_post(); { 
        if ( $post->post_Type === 'post' ) {
             // here we'll use a conventional subtemplate content-{$post_format_slug}.php
             $post_type_plus_post_format = get_post_format();
        } else {
             // here we'll use a new subtemplate content-{$post->post_type}-{$post_format_slug}.php
             if ( ( get_post_format() != '' ) && ( get_post_format() != 'standard' ) )
                  $post_type_plus_post_format = $post->post_type . '-' . get_post_format();
             else
                  $post_type_plus_post_format = $post->post_type;
        }
        ?>
	<div id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
	     <?php get_template_part( 'content', $post_type_plus_post_format ); ?>
	</div><?php
    }
}
// Rest of the code for main template
?>

Of course, this code is just a first approach and it’s possible to improve it a lot but for the goal we pursue now, it’s more than enough.

For viewing the working of this solution, we could reexamine an extended example about the list of the lastest posts in website. For example, if we have a list of posts like.

Post ID   | Post Type | Post format 
-------------------------
2345      | post      | video
2340      | book      | standard
2331      | book      | audio
2330      | news      | standard
2327      | post      | aside
2322      | post      | audio
2319      | book      | quote
2317      | news      | video
2314      | news      | gallery
2311      | book      | standard
... etc.

The list of used templates and subtemplates for displaying the main page of the website would be like this

index.php
   header.php
      // here we begin the while ( have_posts() ) structure
           content-video.php
           content.php
           content-book.php
           content-book-audio.php
           content-news.php
           content-aside.php
           content-audio.php
           content-book-quote.php
           content-news-video.php
           content-news-gallery.php
           content-book.php
           ... etc.
      // here we end the while structure
   sidebar.php
   footer.php
//END OF FILE index.php

As you see, if this was a real example, in the main page of the website, each ‘type’ and each ‘format’ of a WordPress content will be displayed using its adequated subtemplate.

The WordPress single and archive templates

Until now, we are talking about WordPress templates that have not got a directe template extension that depends on the Post Type, ie, the case of index.php, tags.php and similar templates. In these cases you have to use a solution like the above explained one however, when we are talking about templates that have got a direct template extension

  • single.php >> single-$post_type.php
  • archive.php >> archive-$post_type.php

Then, if you want, you can simplify the code because you are not forced to use the general template but for the contrary, from the beginning a posttype named templates can be used. Instead of using archives.php, we can use archives-$posttype.php, so in these two cases, the code could be simplier.

I hope this example is usefull in your themes.

Have a nice WordPressing!

3 Comments on Using Post Formats with your custom WordPress Post Types

Leave a Reply to Joan Miquel Viadé Cancel Replay

   Mandatory field
You can use these HTML tags inside the commment.
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>