WordPress.org

Codex

Attention Interested in functions, hooks, classes, or methods? Check out the new WordPress Code Reference!

User:Chipbennett/Post Formats

Post Formats are a WordPress Theme feature introduced with WordPress version 3.1, implemented as a taxonomy that includes a standard list of Post Format types: Aside, Audio, Chat, Gallery, Image, Link, Quote, Status, and Video. Themes that support the feature can customize the layout and styling of Posts according to Post Format type, generally by altering the Loop output for Posts with a given Post Format type, or by targeting specific CSS classes applied to such Posts.

In order to ensure feature compatibility among Themes and to facilitate integration with external blogging tools, the list of Post Format types is not extensible. Unlike other core taxonomies such as Categories and Post Tags, Themes must register support for the Post Formats feature in order to use it, and can add support for any or all Post Format types.

Note: Post Formats should not be confused with Custom Post Types. Post Formats are a taxonomy, not a post-type.

Function Reference

Main Functions
Other Functions

Adding Theme Support

Themes add support for the Post Formats feature by calling add_theme_support() in functions.php. This function call must include an array listing the Post Format types for which to add support. For example, to add support for the "Aside" and "Gallery" Post Format types:

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

Note: this function call must be made inside a callback hooked into the after_setup_theme action hook. Normally, this function call is located inside the Theme setup function; for example:

function mytheme_setup() {
	// Enable Theme support for Post Formats
	add_theme_support( 'post-formats', array( 'aside', 'gallery' ) );
}
add_action( 'after_setup_theme', 'mytheme_setup' );

Once a WordPress Theme has added support for Post Formats, the Edit Post page displays a metabox with a radio-select list of the Post Format types supported by the Theme. The user can then select the appropriate Post Format type for the current post. (Note: "Standard" is not actually a Post Format type; rather, indicates that no Post Format type has been selected. In other words, "Standard" indicates that the current post does not use the Post Format taxonomy.)

The above function call, which enables Theme support for the "Aside" and "Gallery" Post Format types, would result in the following meta box:

INSERT SCREENSHOT HERE

Enabling Theme support for the full list of Post Format types would result in the following meta box:

INSERT SCREENSHOT HERE

Using Post Formats

Modifying Loop Output Based on Post Format Type

Themes can use Post Formats to modify the output of the Loop. Assuming the usual Loop markup, e.g.:

<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
	<div id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
		<!--POST MARKUP GOES HERE-->
	</div>
<?php endwhile; endif; ?>

Themes can use Post Formats to modify the markup inside of the <div></div> tags, using one of at least two methods:

Using get_template_part()

Themes can use get_template_part(), combined with get_post_format(), to define the Post markup based on Post Format type. For example:

<?php get_template_part( 'entry', get_post_format() ); ?>

In the context of the Loop markup:

<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
	<div id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
		<?php get_template_part( 'entry', get_post_format() ); ?>
	</div>
<?php endwhile; endif; ?>

Using this method, Themes would include a entry.php template-part file that includes the default Post markup, and would include a entry-{format}.php template-part file (e.g. entry-gallery.php) for each Post Format type supported by the Theme.

Due to the locate_template() hierarchy built into get_template_part(), this method facilitates Child-Theme overriding of Post markup for specific Post Format types. For example, a entry-aside.php in a Child Theme would override the same template-part file in the Parent Theme.

Additionally, due to the fallback built into get_template_part(), a Theme need only include entry.php, regardless of the Post Format types supported by the Theme, since any entry-{format}.php template-part file not found will fall back to entry.php.

Using Conditionals

Alternately, Themes can use has_post_format( $format ), either in an if/else conditional or a switch, to define the Post markup based on Post Format type. For example:

<?php
if ( has_post_format( 'gallery' ) ) {
	// Gallery Post Format markup here
} else if ( has_post_format( 'aside' ) ) {
	// Aside Post Format markup here
} else {
	// Default post markup here
}
?>

In the context of the Loop markup:

<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
	<div id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
		<?php
		if ( has_post_format( 'gallery' ) ) {
			// Gallery Post Format markup here
		} else if ( has_post_format( 'aside' ) ) {
			// Aside Post Format markup here
		} else {
			// Default post markup here
		}
		?>
	</div>
<?php endwhile; endif; ?>

Modifying CSS Based on Post Format Type

In addition to modifying the Loop output, Themes can use Post Formats to modify the style of individual posts and of single-post and archive index pages according to Post Format type, using CSS.

Modifying Individual Posts

Themes can target the Post Format type-specific CSS classes applied to the Post container via the post_class() template tag:

  • For Posts that have a given Post Format type, the post_class() template tag adds a .format-{format} CSS class.
    • Example: .format-gallery for Posts with the "Gallery" Post Format type.

For example, one could hide post titles from status format posts in this manner:

.format-status .post-title {
	display:none;
}

Modifying Single-Post and Archive Index Pages

Themes can target the Post Format type-specific CSS classes applied to the HTML <body> tag via the body_class() template tag:

  • For single-post pages for Posts that have a given Post Format type, the body_class() template tag adds a .single-format-{format} CSS class.
    • Example: .single-format-gallery for single-post pages for Posts with the "Gallery" Post Format type.
  • For Post Format term archive index pages for a given Post Format type, the body_class() template tag adds a .term-format-{format} CSS class.
    • Example: .term-format-gallery for "Gallery" Post Format type archive index pages.

Suggested Post Format Layout/Style Conventions

Although Themes can design the layout and style of Post Format types to be displayed any way as seen fit, each Post Format type lends itself to a certain type of "style", as dictated by modern usage. Consideration of this intended usage facilitates ease of recognition of the Post Format types.

For example, the aside, link, and status Post Format types are typically displayed without Post Title or Post meta information (author, timestamp, categories, tags). They are simple, short, and minor. The aside could contain perhaps a paragraph or two, while the link would probably be only a sentence with a link to some URL in it.

An image post, on the other hand, would typically just contain a single image, with or without a caption/text to go along with it. An audio/video post would be the same but with audio/video added in. Any of these three could use either Plugins or standard Embeds to display their content. Post Title and meta information might not be displayed for them either, as the content could be self-explanatory.

The quote format is especially well-suited to posting a simple quote from a person with no extra information. If you were to put the quote into the post content alone, and put the quoted person's name into the title of the post, then you could style the post so as to display the_content() by itself but restyled into a blockquote format, and use the_title() to display the quoted person's name as the byline.

A chat is typically displayed using a monospaced font, perhaps inside a shaded background.

  • Aside
    • Description: Similar to a Facebook note update
    • Content: typically text, HTML, and other non-attached/embedded content
    • Layout: Post Title typically not displayed. Post Meta (author, timestamp, categories, tags) typically not displayed.
    • Style:
  • Audio
    • Description: an audio file
    • Content: typically an attached, embedded, or linked audio file
    • Layout: Post Title typically displayed. Post Meta
    • Style:
  • Chat
    • Description: a chat transcript
    • Content: typically text, like so:
John: foo
Mary: bar
John: foo 2
    • Layout:
    • Style: typically displayed using a monospaced font
  • Gallery
    • Description: a gallery of images
    • Content: typically multiple attached images, using the [gallery] shortcode
    • Layout:
    • Style:
  • Image
    • Description: a single image.
    • Content: typically an attached or linked image
    • Layout: The first <img /> tag in the post could be considered the image. Alternatively, if the post consists only of a URL, that will be the image URL and the title of the post (post_title) will be the title attribute for the image.
    • Style:
  • Link
    • Description: a link to another site
    • Content: typically an HTML hyperlink, with or without additional text
    • Layout: Post Title typically not displayed. Post Meta (author, timestamp, categories, tags) typically not displayed.
      • Themes may wish to use the first <a href=””> tag in the post content as the external link for that post. An alternative approach could be if the post consists only of a URL, then that will be the URL and the title (post_title) will be the name attached to the anchor for it.
    • Style:
  • Quote
    • Description: a quotation
    • Content: typically text and HTML, with the quote enclosed within HTML <blockquote></blockquote> tags.
    • Layout: Post Title typically not displayed. Post Meta (author, timestamp, categories, tags) typically not displayed.
      • Alternatively, the quote may be just the content, with the source/author being the title.
    • Style:
  • Status
    • Description: a short status update, similar to a Twitter update
    • Content: typically text, HTML, and other non-attached/embedded content
    • Layout: Post Title typically not displayed. Post Meta: author, timestamp typically displayed; categories, tags typically not displayed.
    • Style:
  • Video
    • Description: a single video
    • Content: typically an attached, embedded, or linked video file
    • Layout: the first <video /> tag or object/embed in the post content could be considered the video. Alternatively, if the post consists only of a URL, that will be the video URL. May also contain the video as an attachment to the post, if video support is enabled on the blog (like via a plugin).
    • Style:

Advanced Post Format Usage

Excluding Post Formats from the Primary Loop

A Theme may choose to exclude Posts with a specific Post Format type, e.g. "Status", from the Primary Loop, so that such Posts can be displayed alternately (perhaps in the Sidebar, or in a Widget, etc.). To do so, modify the Primary Loop parameters via query_posts(), using a tax_query. For example, use the following code before the Loop:

global $wp_query;
$exclude_status_posts_args = array(
	'tax_query' => array(
		array(
			'taxonomy' => 'post_format',
			'field' => 'slug',
			'terms' => array( 'post-format-status' ),
			'operator' => 'NOT IN'
		)
	)
);
$exclude_status_posts_query = array_merge( $wp_query->query, $exclude_status_posts_args );
query_posts( $exclude_status_posts_query );

Then, to display Posts with the "Status" Post Format type elsewhere, create a secondary loop, using e.g. WP_QUery() or get_posts().

Post Formats in Child Themes

Child Themes inherit the post formats defined by the parent theme. Calling add_theme_support() for post formats in a child theme will override the existing list, not add to it. Calling remove_theme_support('post-formats') will remove it all together.

Extending Post Format Support to Other Post Types

Post Types need to use add_post_type_support() in the functions.php file to tell WordPress which post formats to support:

// add post-formats to post_type 'page'
add_post_type_support( 'page', 'post-formats' );

// add post-formats to post_type 'my_custom_post_type'
add_post_type_support( 'my_custom_post_type', 'post-formats' );

Or in the function register_post_type(), add 'post-formats', in 'supports' parameter array:

$args = array(
	...
	'supports' => array('title', 'editor', 'author', 'post-formats')
); 
register_post_type('book', $args);

Backwards Compatibility

If a Plugin or Theme requires backwards compatibility with versions of WordPress prior to version 3.1, it must register the post_format taxonomy using register_taxonomy(), and then must add post-format-$format terms for each of the Post Format types. For example:

wp_insert_term( 'post-format-aside', 'post_format' );

Origin of Post Formats

Post Formats are an evolution of an earlier practice of customizing Loop markup and style for given categories: specifically, for the "gallery" and "asides" categories. This practice was popularized in two Themes relased by Matt Mullenweg: Matala and Mazeld. Using asides as an example, a category named "Asides" was created, and Posts were assigned that category, and then displayed using different markup via the in_category('asides') conditional.


Source File

External Resources

Related

Post Formats: set_post_format(), get_post_format(), has_post_format(), the_post_format_audio(), get_the_post_format_media(), get_content_audio(), the_post_format_chat(), get_the_post_format_chat(), get_content_chat(), add_chat_detection_format(), the_post_format_gallery(), get_content_galleries(), get_post_gallery_images(), the_post_format_image(), get_the_post_format_image(), get_content_images(), the_post_format_quote(), get_the_post_format_quote(), get_content_quote(), the_post_format_url(), get_the_post_format_url(), get_content_url(), the_post_format_video(), get_content_video(), the_remaining_content(), get_the_remaining_content(), get_post_format_meta(), post_format_content_class(), get_post_format_content_class(), post_formats_compat()