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.
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.