Is it possible to manipulate the list of page templates?

After answering this question I wondered if it is possible to manipulate the dropdown list of possible page templates that’s available when you edit a page. WordPress derives this list from the template files available in the root directory (like page.php, page-onecolumn.php, page-about-us.php). It doesn´t seem to store the list in the database.

I could imagine there are legit reasons to want this, for instance if you have ten page templates, but you want to limit access to some of them for non-admin users. Or perhaps you want to create templates dynamically through an option page, so you want to extend the list.

1
1

The workhorse is WP_Theme::get_page_templates() (wrapped by the helper function get_page_templates()). If you check out the source, you’ll see:

/**
 * Filter list of page templates for a theme.
 *
 * @since 3.9.0
 * @since 4.4.0 Converted to allow complete control over the `$page_templates` array.
 *
 * @param array        $page_templates Array of page templates. Keys are filenames,
 *                                     values are translated names.
 * @param WP_Theme     $this           The theme object.
 * @param WP_Post|null $post           The post being edited, provided for context, or null.
 */
return (array) apply_filters( 'theme_page_templates', $page_templates, $this, $post );

Example:

function wpse_226324_page_templates( $templates ) {
    // Remove tpl-home.php template
    unset( $templates['tpl-home.php'] );

    // Add custom template
    $templates['tpl-custom.php'] = 'Custom Template';

    return $templates;
}

add_filter( 'theme_page_templates', 'wpse_226324_page_templates' );

See also theme_page_templates code reference.

Leave a Comment