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?
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!
[…] Using Post Formats with your custom WordPress Post Types […]
Hi do you actually have working example that you share
In most of the cases, yes. Absolutely. Just in this website, for example, there could be the eighty percent of the examples installed. Of course, there are little adaptations but, basicaly, all changes, additions, gadgets… implemented in this website appear as the examples of the posts.
Best regards,