Justin Tadlock

Post format support for custom post types

When building the Custom Content Portfolio plugin, I needed to add post format support to my portfolio project post type. Generally speaking, this is a pretty easy thing to do. However, I wanted to limit the possible formats to only those that made sense for portfolios.

This tutorial will walk you through the process of what I done to handle that scenario.

Adding post format support

Adding support is as simple as adding one line of code to your supports array when calling register_post_type().

'post-formats'

Here’s what that’d look like in the code:

register_post_type(
		'portfolio_project',
		array(
		   'supports' => array(
			  'title',
			  'editor',
			  'post-formats'
		   )
		)
);

That’s all you need if you want to support all post formats for a custom post type.

Limiting post formats

If, like me, you have a post type in which you want to limit support to only some of the formats, you’ll need to work a little magic. Core WP doesn’t have filter hooks for disabling formats.

The first thing we’ll do is create a function that returns an array of the post formats that our post type supports. I’ve chosen the audio, gallery, image, and video formats.

function jt_get_allowed_project_formats() {

	return array( 'audio', 'gallery', 'image', 'video' );
}

Because there are no hooks for changing the available formats, we’ll instead work with the “theme support” system by changing the theme-supported formats. We’ll just need to limit it to our post type’s admin screens so that it won’t mess with other post types.

add_action( 'load-post.php',     'jt_post_format_support_filter' );
add_action( 'load-post-new.php', 'jt_post_format_support_filter' );
add_action( 'load-edit.php',     'jt_post_format_support_filter' );

function jt_post_format_support_filter() {

	$screen = get_current_screen();

	// Bail if not on the projects screen.
	if ( empty( $screen->post_type ) ||  $screen->post_type !== 'portfolio_project' )
		return;

	// Check if the current theme supports formats.
	if ( current_theme_supports( 'post-formats' ) ) {

		$formats = get_theme_support( 'post-formats' );

		// If we have formats, add theme support for only the allowed formats.
		if ( isset( $formats[0] ) ) {
			$new_formats = array_intersect( $formats[0], jt_get_allowed_project_formats() );

			// Remove post formats support.
			remove_theme_support( 'post-formats' );

			// If the theme supports the allowed formats, add support for them.
			if ( $new_formats )
				add_theme_support( 'post-formats', $new_formats );
		}
	}

	// Filter the default post format.
	add_filter( 'option_default_post_format', 'jt_default_post_format_filter', 95 );
}

You might notice a filter on the default post format there at the end of that function. The reason for this is because core WP allows the user to select a default format. We’ll need to overwrite that if it’s not one of the approved formats for our post type.

function jt_default_post_format_filter( $format ) {

	return in_array( $format, jt_get_allowed_project_formats() ) ? $format : 'standard';
}

That’s all there is to it. Now a post type like portfolio projects doesn’t have to support formats like “chat” and “aside” when it doesn’t make sense.

Like this tutorial? Please consider helping me write more in the future by making a donation via PayPal, grabbing something from my Amazon Wish List, or signing up at Theme Hybrid where you can ask me any support questions you want.