I thought I would provide you with another approach. It is also a bit hackish, but it is general purpose and allows you to simply register the filename and label that you want to use, like so:
if ( class_exists( 'WPSE_196995_Page_Templates' ) ) {
WPSE_196995_Page_Templates::register_page_template(
'My Page Template',
'my-page-template.php'
);
}
You could add the above code to your theme's functions.php
file.
To enable the above to actually work I implemented a self-contained class that could be used as a plugin or just copied into functions.php
:
<?php
/**
* Plugin Name: WPSE 196995 Page Templates
*
* Class WPSE_196995_Page_Templates
*
* Allows registering page templates via code.
*/
class WPSE_196995_Page_Templates {
static $registered_templates = array();
static function on_load() {
/**
* Add registered page templates to 'page_template' cache.
* @note This hook is called just before page templates are loaded
*/
add_action( 'default_page_template_title', array( __CLASS__, '_default_page_template_title' ) );
}
/**
* Register page templates
*
* @param string $label
* @param string $filename
*/
static function register_page_template( $label, $filename ) {
self::$registered_templates[ $filename ] = $label;
}
/**
* Add registered page templates to 'page_template' cache.
*
* @param string $title
*
* @return string mixed
*/
static function _default_page_template_title( $title ) {
/**
* @var WP_Theme $theme
*/
$theme = wp_get_theme();
/**
* Access the cache the hard way since WP_Theme makes almost everything private
*/
$cache_hash = md5( $theme->get_stylesheet_directory() );
/**
* Get the page templates as the 'page_templates' cache will already be primed
*/
$page_templates = wp_cache_get( $key = "page_templates-{$cache_hash}", $group = 'themes' );
/**
* Add in registered page templates
*/
$page_templates += self::$registered_templates;
/**
* Now update the cache, which is what the get_page_templates() uses.
*/
wp_cache_set( $key, $page_templates, $group, 1800 );
/**
* We are using this hook as if it were an action.
* So do not modify $title, just return it.
*/
return $title;
}
}
WPSE_196995_Page_Templates::on_load();
The class provides the register_page_template()
method, of course, but to actually add your page template it updates the value for 'page_templates'
set in the object cache.
It is a bit hacky because WordPress made most methods and properties of the WP_Theme
class private
, but fortunately they used the publicly-accessible WordPress object cache to store the values. And by updating the object cache in the 'default_page_template_title'
hook, which is called just before the page templates dropdown is generated and sent to the browser, we can get WordPress to display your page template(s), as you desired.