Create template for custom post types in Wordpress

zuzuleinen picture zuzuleinen · Aug 30, 2011 · Viewed 12.7k times · Source

I know how to create a custom template for a specific page. However I would like to create a template for a specific custom post type. Is that possible and if true how can I do that?

If I create a new template it will show in admin only when I'm adding a page, but when I'm adding a new post type I don't have the option to select a certain template.

Problem resolved:

/* 
Show the list of available custom templates templates in the Custom Post Type admin section
*/

/**
 * Post_type
 */
define( 'MY_THEME_POST_TYPE', 'cases' );
/**
 * Load the page template for any post object
 * having the appropriate meta key set.
 */
add_action( 'template_redirect', 'mytheme_template_redirect' );
function mytheme_template_redirect() {
    global $wp_query;
    $id = (int) $wp_query->get_queried_object_id();
    $template = get_post_meta( $id, '_wp_page_template', true );
    if ( $template && 'default' !== $template ) {
        $file = STYLESHEETPATH . '/' . $template;
        if( is_file( $file ) ) {
            require_once $file;
            exit;
        }
    }

}
/**
 * Process the Meta Box
 * @todo Permissions check.
 * @todo Filter input.
 * @todo Nonces.
 */
add_action( 'save_post', 'mytheme_process_resource_template' );
function mytheme_process_resource_template() {
    global $post;

    /* Sanitize $_POST array. */
    $clean_id = ( isset( $_POST['ID'] ) ) ? intval( $_POST['ID'] ) : 0;

    if ( !empty( $_POST['page_template'] ) && MY_THEME_POST_TYPE == $post->post_type ) {
        $page_templates = get_page_templates();
        if ( 'default' != $page_template && !in_array( $_POST['page_template'], $page_templates ) ) {
            if ( $wp_error )
                return new WP_Error('invalid_page_template', __('The page template is invalid.'));
            else
                return 0;
        }
        update_post_meta( $clean_id, '_wp_page_template',  $_POST['page_template'] );
    }
}
/**
 * Registers the Meta Box
 * @uses mytheme_page_attributes_meta_box()
 */
add_action( 'admin_init', 'mytheme_register_meta_boxes', 10 );
function mytheme_register_meta_boxes()  {
    add_meta_box(
        'mytheme_post_type_template',
        'Template',
        'mytheme_page_attributes_meta_box',
        MY_THEME_POST_TYPE,
        'side',
        'low'
        );
}
/**
 * Creates the Meta Box
 */
function mytheme_page_attributes_meta_box() {
    global $post;
    $post_type_object = get_post_type_object($post->post_type);    
    if ( 0 != count( get_page_templates() ) ) {
        $template = get_post_meta( $post->ID, '_wp_page_template',  true );
        ?>
<p><strong><?php _e('Template') ?></strong></p>
<label class="screen-reader-text" for="page_template"><?php _e('Page Template') ?></label><select name="page_template" id="page_template">
<option value='default'><?php _e('Default Template'); ?></option>
<?php page_template_dropdown( $template ); ?>
</select>
<?php
    }
}

Answer

Ivan Ivanić picture Ivan Ivanić · Aug 30, 2011

Create page that is called:

single-{cpt-slug}.php e.g. single-product.php

It will be used when showing a page of a custom post type. i.e. when someone goes to http://example.com/product/awesome-shoes/