Page Templates – this code only works for one Custom Post Type

I have the code below in my functions.php file, it works great and allows me to use page templates in my custom post type ‘services’.

I have defined which ‘type’ to use on the first line with ‘services’.

Read More
define('MY_CUSTOM_POST_TYPE', 'services');

The problem is I have multiple custom post types. I want to use the function allow me to choose page templates for ALL my custom post types. Being a complete novice I can’t get it to work.

Here is the code in full:

# Define your custom post type string
define('MY_CUSTOM_POST_TYPE', 'services');

/**
 * Register the meta box
 */
add_action('add_meta_boxes', 'page_templates_dropdown_metabox');
function page_templates_dropdown_metabox(){
    add_meta_box(
        MY_CUSTOM_POST_TYPE.'-page-template',
        __('Template', 'my_template'),
        'render_page_template_dropdown_metabox',
        MY_CUSTOM_POST_TYPE,
        'side', #I prefer placement under the post actions meta box
        'low'
    );
}

/**
 * Render your metabox - This code is similar to what is rendered on the page post type
 * @return void
 */
function render_page_template_dropdown_metabox(){
    global $post;
    $template = get_post_meta($post->ID, '_wp_page_template', true);
    echo "
        <label class='screen-reader-text' for='page_template'>Page Template</label>
            <select name='_wp_page_template' id='page_template'>
            <option value='default'>Default Template</option>";
            page_template_dropdown($template);
    echo "</select>";
}

/**
 * Save the page template
 * @return void
 */
function save_page_template($post_id){

    # Skip the auto saves
    if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
        return;
    elseif ( defined( 'DOING_AJAX' ) && DOING_AJAX )
        return;
    elseif ( defined( 'DOING_CRON' ) && DOING_CRON )
        return;

    # Only update the page template meta if we are on our specific post type
    elseif(MY_CUSTOM_POST_TYPE === $_POST['post_type'])
        update_post_meta($post_id, '_wp_page_template', esc_attr($_POST['_wp_page_template']));
}
add_action('save_post', 'save_page_template');


/**
 * Set the page template
 * @param string $template The determined template from the WordPress brain
 * @return string $template Full path to predefined or custom page template
 */
function set_page_template($template){
    global $post;
    if(MY_CUSTOM_POST_TYPE === $post->post_type){
        $custom_template = get_post_meta($post->ID, '_wp_page_template', true);
        if($custom_template)
            #since our dropdown only gives the basename, use the locate_template() function to easily find the full path
            return locate_template($custom_template);
    }
    return $template;
}
add_filter('single_template', 'set_page_template');

Related posts

Leave a Reply

1 comment

  1. Dump the constant MY_CUSTOM_POST_TYPE use the $post->post_type instead.

    /**
     * Register the meta box
     */
    
    add_action('add_meta_boxes', 'page_templates_dropdown_metabox');
    function page_templates_dropdown_metabox(){
        global $post;
        add_meta_box(
            $post->post_type.'-page-template',
            __('Template', 'my_template'),
            'render_page_template_dropdown_metabox',
            $post->post_type,
            'side', #I prefer placement under the post actions meta box
            'low'
        );
    }
    
    /**
     * Render your metabox - This code is similar to what is rendered on the page post type
     * @return void
     */
    function render_page_template_dropdown_metabox(){
        global $post;
        $template = get_post_meta($post->ID, '_wp_page_template', true);
        echo "
            <label class='screen-reader-text' for='page_template'>Page Template</label>
                <select name='_wp_page_template' id='page_template'>
                <option value='default'>Default Template</option>";
                page_template_dropdown($template);
        echo "</select>";
    }
    
    /**
     * Save the page template
     * @return void
     */
    function save_page_template($post_id){
    
        # Skip the auto saves
        if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
            return;
        elseif ( defined( 'DOING_AJAX' ) && DOING_AJAX )
            return;
        elseif ( defined( 'DOING_CRON' ) && DOING_CRON )
            return;
    
    
            update_post_meta($post_id, '_wp_page_template', esc_attr($_POST['_wp_page_template']));
    }
    add_action('save_post', 'save_page_template');
    
    
    /**
     * Set the page template
     * @param string $template The determined template from the WordPress brain
     * @return string $template Full path to predefined or custom page template
     */
    function set_page_template($template){
        global $post;
    
            $custom_template = get_post_meta($post->ID, '_wp_page_template', true);
            if($custom_template)
                #since our dropdown only gives the basename, use the locate_template() function to easily find the full path
                return locate_template($custom_template);
    
        return $template;
    }
    add_filter('single_template', 'set_page_template');
    

    Code not tested

    Code will show the dropdown for all post types.