This used to be a tricky problem to solve involving ‘fooling’ WordPress into loading the right template from its cache etc. However, for about 12 months now – since 4.7 – it’s relatively trivial to load a WordPress page template from a plugin. Here’s how:
/**
* Add the Page Template to the dropdown in the Edit Screen.
*
* @param array $templates The current list of page templates
* @return array Modified list of page templates
*/
function theme_page_templates__register_page_template( $templates ) {
$templates['your-custom-template'] = 'YOUR CUSTOM TEMPLATE';
return $templates;
}// end theme_page_templates__register_page_template()
add_filter( 'theme_page_templates', 'theme_page_templates__register_page_template' );
/**
* When the user has selected our custom page template, ensure WordPress
* loads it from the correct location here in the plugin.
*
* @param string $template path to current template being requested
* @return string path to template
*/
function page_template__load_page_template_when_required( $template ) {
// Determine if this is our template being requested
$post = get_post();
$page_template = get_post_meta( $post->ID, '_wp_page_template', true );
// Bail if this isn't our template being requested
if ( 'your-custom-template' !== basename( $page_template ) ) {
return $template;
}
// OK, our template is being asked for. Let's load it from here in the plugin.
$dir = plugin_dir_path( __FILE__ );
$template = $dir . '/templates/your-custom-template';
return $template;
}// end page_template__load_page_template_when_required()
add_filter( 'page_template', 'page_template__load_page_template_when_required' );
The first filter – ‘theme_page_templates’ adds the template to the dropdown in the edit screen. The second – ‘page_template’ – picks up when WordPress is deciding which template to show on the front-end.
Simple, yet pretty powerful, stuff.