This week one of my colleagues was working on a new project, where a page template in the parent theme was broken. There was a better similar page template to use instead, but there might still be the chance that someone would use this broken page template, when creating a new page. So I had the idea to find out, how to deactivate a page template from the dropdown.
Deactivate a page template
In a child theme, it is quite easy to create a new page template or to overwrite a page template, by copying it over from the parent theme. But how can you prevent a page template from showing up in the dropdown? Fortunately, there is almost always a hook for that. If you want to deactivate a page template, use this filter:
function child_theme_disable_page_template( $post_templates, $theme, $post, $post_type ) {
unset( $post_templates['page-templates/tpl-hero-light.php'] );
return $post_templates;
}
add_filter( 'theme_templates', 'child_theme_disable_page_template', 10, 4 );
The filter theme_templates
will get an array with all templates, using the relative path as the key and the (translated) name as a value. It could look like this:
$post_templates = array(
'page-templates/tpl-fullscreen-light.php' => 'Fullscreen, light header',
'page-templates/tpl-fullscreen.php' => 'Fullscreen',
'page-templates/tpl-fullwidth-notitle.php' => 'Full Width, no page title',
'page-templates/tpl-fullwidth.php' => 'Full Width',
'page-templates/tpl-hero-light.php' => 'Hero, light header',
'page-templates/tpl-hero.php' => 'Hero',
);
The array contains page templates from both the parent theme and the child theme. If both have a page template with the same path, only one of it will be included in the array.
Replace a page template
So now you know how to avoid someone from using a page template you don’t want them to use. But what about all the pages that already have that page template selected? You could do a search/replace in the database, replacing all postmeta with the key _wp_page_template
and replace it with a new value. But maybe you want to keep the information in the database intakt. Then you can use a variety of hooks to overwrite the path. This is one of the filters you can use:
function child_theme_overwrite_page_template( $template ) {
if ( get_parent_theme_file_path( '/page-templates/tpl-hero-light.php' ) === $template ) {
return get_theme_file_path( '/page-templates/tpl-hero.php' );
}
return $template;
}
add_filter( 'template_include', 'child_theme_overwrite_page_template' );
In this example, any page that would use the page-templates/tpl-hero-light.php
page template from the parent theme will now be using the page-templates/tpl-hero.php
page template from the child theme.
Conclusion
While it’s very easy to add or overwrite page templates in a child theme, deactivating one in a child theme is not as easy. But as WordPress usually has a hook for anything you want to customize, even this task is not that hard.