The weight of opinion seems to favour using custom post types instead of custom post formats.

I have several custom post types that I want to style in 4 different formats in a way that is not public ie not a category, tag or custom taxonomy.

Custom post formats would seem to provide an ideal solution for this - they're built-in functionality, easily implemented, come with handy meta box, easily applied with conditional statements etc.

The major draw back being they are not readily customisable - I could rename them for the sake of clarity.

So given the prevailing thought, what would be a better approach to creating the same functionality.

4 Answers 4


You have several options here so I will clarify what you can do.

  1. Create a custom post type template page using something like single-customposttype.php and take advantage of the template hierarchy, http://codex.wordpress.org/Template_Hierarchy

  2. Use a conditional query for your styling in the loop ( or whatever you're using), along the line of if (post type= your custom one) style it this way;. or use some other WordPress conditionals. http://codex.wordpress.org/Class_Reference/WP_Query

  3. Use a taxonomy for back-end organization, custom taxonomies do not have to be public.

  4. Use post formats for your custom post type, CPT's can support post-formats, http://codex.wordpress.org/Function_Reference/register_post_type

Most people go with option one, but it depends on what you're trying to do.

  • Thanks for your answer Wyck. I have 3 CPT which I want to format according to 4 sub types as post formats would. I may use templates down the track but at this point I'm looking for a way to apply the format without using taxonomies that are seen in the front-end. So I either need to find a way to restrict the visbility of the custom tax to the back end or use post formats renamed for clarity which are already nicely restricted to the back-end. Any pointers on how to achieve the back-end only taxonmomies appreciated as this is probably the better option.
    – Rothbert
    Oct 31, 2011 at 2:36
  • When you register a taxonomy you have many options, some of which are to not make them public, codex.wordpress.org/Function_Reference/register_taxonomy
    – Wyck
    Oct 31, 2011 at 3:36
  • Thanks Wyck - OK I'd seen the public => false option and tried that but was still seeing the taxonomy in my post footer, but realise that option removes it from the tag clouds etc. I can see that I'll have to work out a way to exclude particular custom taxonomies from the function that is generating the post footer. Will start a new question.
    – Rothbert
    Oct 31, 2011 at 22:51

Rothbert, you remove the visibility of taxonomies in your theme files.

The crucial difference between "Custom Post Types" and "Post Formats" is the word 'custom.'

In other words, you cannot change the name of custom post formats. You are limited to the default 10 native to WordPress. You cannot add new post formats. And you cannot change the names of existing ones.


You can enable support for post formats in a CPT. When registering the post type set post-formats in the 'supports' argument.

  • can you improve you answer with some code example and links to further documentation?
    – Aurovrata
    Apr 17, 2021 at 14:28

I found this interesting blog piece by Nathan Swartz that basically creates custom post formats for any post type by using a custom taxonomy. I am reproducing his code here so should his blog disappear, his solution persist here.

The basic steps involved are:

  1. Create a custom taxonomy and assign it to posts.
  2. Programmatically create the terms in that custom taxonomy, in a way where non-admins can’t create. edit or delete new ones, but can assign them to posts.
  3. Set a default post term.
  4. Change the way the custom taxonomy is displayed on the post editor page, so that only one format can be chosen.

here is the code,

// hook into the init action and call custom_post_formats_taxonomies when it fires
add_action( 'init', 'custom_post_formats_taxonomies', 0 );
// create a new taxonomy we're calling 'format'
function custom_post_formats_taxonomies() {
    // Add new taxonomy, make it hierarchical (like categories)
    $labels = array(
        'name'              => _x( 'Formats', 'taxonomy general name', 'textdomain' ),
        'singular_name'     => _x( 'Format', 'taxonomy singular name', 'textdomain' ),
        'search_items'      => __( 'Search Formats', 'textdomain' ),
        'all_items'         => __( 'All Formats', 'textdomain' ),
        'parent_item'       => __( 'Parent Format', 'textdomain' ),
        'parent_item_colon' => __( 'Parent Format:', 'textdomain' ),
        'edit_item'         => __( 'Edit Format', 'textdomain' ),
        'update_item'       => __( 'Update Format', 'textdomain' ),
        'add_new_item'      => __( 'Add New Format', 'textdomain' ),
        'new_item_name'     => __( 'New Format Name', 'textdomain' ),
        'menu_name'         => __( 'Format', 'textdomain' ),

    $args = array(
        'hierarchical'      => true,
        'labels'            => $labels,
        'show_ui'           => true,
        'show_admin_column' => true,
        'query_var'         => true,
        'rewrite'           => array( 'slug' => 'format' ),
        'capabilities' => array(
            'manage_terms' => '',
            'edit_terms' => '',
            'delete_terms' => '',
            'assign_terms' => 'edit_posts'
        'public' => true,
        'show_in_nav_menus' => false,
        'show_tagcloud' => false,
    register_taxonomy( 'format', array( 'post' ), $args ); // our new 'format' taxonomy

// programmatically create a few format terms
function example_insert_default_format() { // later we'll define this as our default, so all posts have to have at least one format
          'description' => '',
          'slug'        => 'default'
add_action( 'init', 'example_insert_default_format' );

// repeat the following 11 lines for each format you want
function example_insert_map_format() {
        'Map', // change this to
          'description' => 'Adds a large map to the top of your post.',
          'slug'        => 'map'
add_action( 'init', 'example_insert_map_format' );

// make sure there's a default Format type and that it's chosen if they didn't choose one
function moseyhome_default_format_term( $post_id, $post ) {
    if ( 'publish' === $post->post_status ) {
        $defaults = array(
            'format' => 'default' // change 'default' to whatever term slug you created above that you want to be the default
        $taxonomies = get_object_taxonomies( $post->post_type );
        foreach ( (array) $taxonomies as $taxonomy ) {
            $terms = wp_get_post_terms( $post_id, $taxonomy );
            if ( empty( $terms ) && array_key_exists( $taxonomy, $defaults ) ) {
                wp_set_object_terms( $post_id, $defaults[$taxonomy], $taxonomy );
add_action( 'save_post', 'moseyhome_default_format_term', 100, 2 );

// replace checkboxes for the format taxonomy with radio buttons and a custom meta box
function wpse_139269_term_radio_checklist( $args ) {
    if ( ! empty( $args['taxonomy'] ) && $args['taxonomy'] === 'format' ) {
        if ( empty( $args['walker'] ) || is_a( $args['walker'], 'Walker' ) ) { // Don't override 3rd party walkers.
            if ( ! class_exists( 'WPSE_139269_Walker_Category_Radio_Checklist' ) ) {
                class WPSE_139269_Walker_Category_Radio_Checklist extends Walker_Category_Checklist {
                    function walk( $elements, $max_depth, $args = array() ) {
                        $output = parent::walk( $elements, $max_depth, $args );
                        $output = str_replace(
                            array( 'type="checkbox"', "type='checkbox'" ),
                            array( 'type="radio"', "type='radio'" ),
                        return $output;
            $args['walker'] = new WPSE_139269_Walker_Category_Radio_Checklist;
    return $args;

add_filter( 'wp_terms_checklist_args', 'wpse_139269_term_radio_checklist' );

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.