I'm developing a multisite and creating my own themes for it. All the themes will feature some standard pre-defined pages eg. homepage, about, blog, contact us etc.

Each page will also have a number of page template options available, eg: homepage1, homepage2, blog 1, blog 2, contact.

The problem is that some of the page templates will not be appropriate for all pages.

For example, if I have a template designed as a "blog" page, it will not work well if applied to a "contact us" page.

The Question (finally): How can you limit or restrict the templates available to choose depending on the page title or ID?

"Human" code required: if the page is the about page, then only show page template options x & y etc.



The short answer: there isn't a way to control what shows up in that dropdown list, there are no filters available for it. Hopefully that will change in a future version.

A possible solution would be to create your own meta box that lists templates from your own array of templates appropriate for the current page, and save the choice as post meta. Then add a filter to page_template to check for that meta value and load that template.

EDIT- here's a full working example with code adapted from the add_meta_box codex page. The only thing you'll have to change is the $wpa70686_custom_templates array. The format is the page ID you'd like to make the templates available for, then within those arrays, the filename (minus .php), and the name that's displayed in the dropdown menu.

// page ID, template filename, template display name
$wpa70686_custom_templates = array(
    42 => array(
        'custom1' => 'Custom Template One',
        'custom2' => 'Custom Template Two',
    96 => array(
        'custom3' => 'Custom Template Three',
        'custom4' => 'Custom Template Four',

// add the meta box
add_action( 'add_meta_boxes', 'wpa70686_add_template_box' );

function wpa70686_add_template_box() {
        'Page Template', 

// display the meta box on the apprpriate pages
function wpa70686_render_template_box( $post ) {
    global $wpa70686_custom_templates;
    wp_nonce_field( 'wpa70686_nonce', 'wpa70686_noncename' );

    if( array_key_exists( $post->ID, $wpa70686_custom_templates ) ) :

        $current_value = get_post_meta( $post->ID, '_wpa70686_template', TRUE );

        echo '<select id="wpa70686_template_box" name="wpa70686_template_box">';
        echo '<option value="default">Default</option>';

        foreach( $wpa70686_custom_templates[$post->ID] as $template_file => $template_name ):

            $selected = $current_value == $template_file ? ' selected' : '';
            echo '<option value="' . $template_file . '"' . $selected . '>' .$template_name . '</option>';


        echo '</select>';

        echo 'no templates for this page';

// save the meta box value if it exists
add_action( 'save_post', 'wpa70686_save_template_box' );

function wpa70686_save_template_box( $post_id ) {

    if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return;

    if ( !wp_verify_nonce( $_POST['wpa70686_noncename'], 'wpa70686_nonce' ) ) return;

    if ( 'page' == $_POST['post_type'] ){
        if ( !current_user_can( 'edit_page', $post_id ) ) return;
    } else {
        if ( !current_user_can( 'edit_post', $post_id ) ) return;

    if( isset( $_POST['wpa70686_template_box'] ) ):

        $new_value = $_POST['wpa70686_template_box'];
        $current_value = get_post_meta( $post_id, '_wpa70686_template', true );

        if( $current_value ):

            if( 'default' == $new_value ):
                delete_post_meta( $post_id, '_wpa70686_template' );
                update_post_meta( $post_id, '_wpa70686_template', $new_value );


            add_post_meta( $post_id, '_wpa70686_template', $new_value, true );



// load the custom template for pages with the meta value set
add_filter( 'page_template', 'wpa70686_custom_template' );

function wpa70686_custom_template(){
    global $wp_query;
    if ( $template = get_post_meta( $wp_query->queried_object_id, '_wpa70686_template', true ) )
        return locate_template( $template . '.php' );
| improve this answer | |
  • Thanks once again Milo - I'll check that out tomorrow & get back with the results. – speedypancake Oct 27 '12 at 19:52
  • I think what you have suggested would work. It would create a new metabox with page-specific template choices? Unfortunately my lack of technical skills would make this very difficult to achieve so I've decided to put this bit of the project on the back burner for now. But many thanks for your help and suggestions :-)_ – speedypancake Oct 28 '12 at 11:02
  • @user22537 - added a working example, see edit above. – Milo Oct 28 '12 at 18:26
  • Milo, what can I say but amazing! That was exactly what I was trying to achieve and it works perfectly. Thank you so much for taking the time to help me again - THANKS :) – speedypancake Oct 29 '12 at 6:53
  • ...spoke too soon... The new metabox works and displays the templates I want to use for each page, but selecting the template doesn't change and the page stays set with what it had before in the main wp template menu. I used the exact template titles as loaded in my theme's folder (minus the .php) eg. page-template-home1 Don't want to take up any more of your time on this, but if there's anything obvious I might be doing wrong... Thanks again – speedypancake Oct 29 '12 at 7:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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