WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have registered a new post type called Resources. I specify 'page-attributes' as a supported feature. When I go to create a new Resource post I see under Template that I can pick from a number of custom templates I have defined. But after I choose this and click update the setting isn't saved and the template isn't used. Any ideas?

function create_post_type() {
register_post_type( 'foo_resources',
        'labels' => array(
            'name' => __( 'Resources' ),
            'singular_name' => __( 'Resource' )
    'public' => true,
    'has_archive' => true,
    'hierarchical' => true,
    'show_ui' => true,
    'show_in_menu' => true,
    'menu_position' => 5,   
    'supports' => array('title','editor','author','page-attributes'),
    'rewrite' => array(
        'slug' => 'resources',
        'with_front' => false


share|improve this question

The page template for custom post type is not saved because it is checking whether the post type is "page" - it is not implemented for custom post types yet. The drop-down for the page templates was completely removed in 3.1.

This is my way how to deal with it:

/* Define the custom box */

// WP 3.0+
add_action('add_meta_boxes', 'custom_template_add_custom_box');

// backwards compatible
//add_action('admin_init', 'custom_templatet_add_custom_box', 1);

/* Do something with the data entered */
add_action('save_post', 'custom_template_save_postdata');

/* Adds a box to the main column on the Post and Page edit screens */
function custom_template_add_custom_box() {
    add_meta_box( 'custom-post-type-template', 'Custom Post Type Template', 'custom_template_inner_box', 'foo_resources', 'side' );

/* Prints the box content */
function custom_template_inner_box( $post ) {

    // Use nonce for verification
    wp_nonce_field( plugin_basename(__FILE__), 'custom_template_noncename' );

    if ( 0 != count( get_page_templates() ) ) {
        $page_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($page_template); ?>
<?php }

/* When the post is saved, saves our custom data */
function custom_template_save_postdata( $post_id ) {

     // verify this came from the our screen and with proper authorization,
     // because save_post can be triggered at other times

     if ( !isset( $_POST['custom_template_noncename'] ) || !wp_verify_nonce( $_POST['custom_template_noncename'], plugin_basename(__FILE__) ) )
         return $post_id;

     // verify if this is an auto save routine. 
     // If it is our form has not been submitted, so we dont want to do anything
     if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) 
         return $post_id;

     // Check permissions
     if ( 'page' == $_POST['post_type'] ) 
       if ( !current_user_can( 'edit_page', $post_id ) )
           return $post_id;
       if ( !current_user_can( 'edit_post', $post_id ) )
           return $post_id;

     // OK, we're authenticated: we need to find and save the data

     $page_template = $_POST['page_template'];

    if ( !empty($page_template) && 'foo_resources' == get_post_type($post_id) ) {
        $page_templates = get_page_templates();
        if ( 'default' != $page_template && !in_array($page_template, $page_templates) ) {
            if ( $wp_error )
                return new WP_Error('invalid_page_template', __('The page template is invalid.'));
                return 0;
        update_post_meta($post_id, '_wp_page_template',  $page_template);

/* Custom template redirection hook */

function custom_template_redirect() {
    global $post;

    if ( is_single() && 'foo_resources' == get_post_type($post) ) {
        $page_template = get_page_template();
add_action("template_redirect", 'custom_template_redirect');

Maybe you should consider to use Post Formats as another option.

share|improve this answer
Looks good. This is more work than I currently have time to implement. But I will put this on my list of things to do. Instead I am using the single-custom_post_type.php solution. Not good long term, but good enough for now. – mrtsherman Apr 21 '11 at 15:28

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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