Add Page Templates to WordPress with a Plugin
Have you ever wanted to create your own page templates, but not had access to the theme itself? I, as a WordPress plugin author, have found this problem to be particularly annoying when developing my plugins. Thankfully the solution is quite simple! I’m going to take you quickly through the few lines of code which you will need to dynamically create WordPress Page Templates directly through PHP.
Inspiration for this article and the genius behind the code solution comes from Tom McFarlin: I am using my edited version of his original code, which you can find on his GitHub. I have kept his commenting in (as well as adding some of my own) as I find it very helpful in explaining what is going on – I couldn’t have said it any better myself!
You can find the code in its entirety and an example plugin at the very bottom of this post.
Shall we begin?
The Code
We will create our PHP function using a PHP Class. For those of you who aren’t well versed with PHP Classes, a Class is defined as an object which contains a collection of functions and variables which are working together. Check out the PHP.net Introduction for more details about the syntax and theory.
Our wrapper will only need 3 variables:
- The Plugin Slug: This is simply used as a unique identifier for the plugin.
- Class Instance: As we are adding an instance of this class to WordPress’ head, we’d better store it.
- Template Array: As you can probably guess, this is an array holding the template names and titles.
Here they are in code:
class PageTemplater {
/**
* A Unique Identifier
*/
protected $plugin_slug;
/**
* A reference to an instance of this class.
*/
private static $instance;
/**
* The array of templates that this plugin tracks.
*/
protected $templates;
Get Class Instance
As I said previously, we’ll be adding an instance of our class to the WordPress header using the add_filter() function. Therefore we will need a method which will return (or create) this instance for us.
For this, we will need a simple method, which will be called ‘get_instance’. Check it out below;
/**
* Returns an instance of this class.
*/
public static function get_instance() {
if( null == self::$instance ) {
self::$instance = new PageTemplater();
}
return self::$instance;
}
This will be the method called when our class is added to the WordPress head using ‘add_action()’.
WordPress Filters
Now we’ve sorted out the ‘get_instance’ method, we need to sort out what happens when it is actually instantiated.
We will use WordPress’s inbuilt add_filter() function to add an instance of our class into key points along the WordPress initialisation timeline. Using this method we will insert our page templates’ data into relevant slots, such as telling WordPress what file to use as a template when the page is called, and the title to display on the dropdown menu on the Page Editor.
For this we need to use the ‘__construct’ method (this will be run when the class is instantiated).
/**
* Initializes the plugin by setting filters and administration functions.
*/
private function __construct() {
$this->templates = array();
// Add a filter to the attributes metabox to inject template into the cache.
if ( version_compare( floatval( get_bloginfo( 'version' ) ), '4.7', '<' ) ) {
// 4.6 and older
add_filter(
'page_attributes_dropdown_pages_args',
array( $this, 'register_project_templates' )
);
} else {
// Add a filter to the wp 4.7 version attributes metabox
add_filter(
'theme_page_templates', array( $this, 'add_new_template' )
);
}
// Add a filter to the save post to inject out template into the page cache
add_filter(
'wp_insert_post_data',
array( $this, 'register_project_templates' )
);
// Add a filter to the template include to determine if the page has our
// template assigned and return it's path
add_filter(
'template_include',
array( $this, 'view_project_template')
);
// Add your templates to this array.
$this->templates = array(
'goodtobebad-template.php' => 'It\'s Good to Be Bad',
);
}
There are 4 different things going on here (ignoring ‘ $this->templates = array();’, which is just preparing the variable for use);
- Lines 9 – 13: This filter is adding the ‘register_project_templates’ to the ‘page_attributes_dropdown_pages_args’ hook. This is populating the WordPress cache with our new templates, ‘tricking’ WordPress into believing that the page template files actually exist in the template directory. This adds the page templates to the dropdown list on the page attributes meta box in the page editor.
- Lines 16 – 20: Here we are doing essentially the same as the previous code block, except this time we are adding our page template (if selected) to the saved post data as well.
- Lines 23 – 28: This filter is adding the ‘template_include’ to the ‘view_project_template’ hook. This is a very important function; this tells WordPress where your page template file actually is. WordPress will use the path provided by this to render the final page.
- Lines 31 – 34: Although this is simple, it is very important. This is where you specify the page templates you want to be added, and the path relative to the file where the page template file is ( eg. ‘something.php’ ). I’ve included one example (which will be used in the example plugin). Check out below for a general example:
$this->templates = array(
'FILE_PATH_AND_NAME' => 'TEMPLATE_TITLE',
'awesome-template.php' => 'Awesome',
'templates/organised-template.php' => 'Organised',
);
(Eat, Sleep,) Code, Repeat as necessary.
register_project_templates()
I’ve alluded to this method previously; let’s see what it actually does.
Essentially, the purpose of this method is to manipulate WordPress’s cache, inserting the relevant data about our page templates at the right places. Have a look at the code first, and I’ll talk you through it afterwards.
public function register_project_templates( $atts ) {
// Create the key used for the themes cache
$cache_key = 'page_templates-' . md5( get_theme_root() . '/' . get_stylesheet() );
// Retrieve the cache list.
// If it doesn't exist, or it's empty prepare an array
$templates = wp_get_theme()->get_page_templates();
if ( empty( $templates ) ) {
$templates = array();
}
// New cache, therefore remove the old one
wp_cache_delete( $cache_key , 'themes');
// Now add our template to the list of templates by merging our templates
// with the existing templates array from the cache.
$templates = array_merge( $templates, $this->templates );
// Add the modified cache to allow WordPress to pick it up for listing
// available templates
wp_cache_add( $cache_key, $templates, 'themes', 1800 );
return $atts;
}
Right then. Line 4 is the first place to look. As you may have guessed, we are generating a ‘cache key’. This will be used as a unique identifier for our page template data. Using the md5() function simply creates a unique string identifier to avoid any conflicts.
Next, on line 8, we are searching for and retrieving the page template cache (if it exists already): this will return an array of paths and titles. On lines 9-11 we check to see if there was any output from the cache query. If yes, great. If not, create a local array to hold the data we will be merging into the cache.
The next step is crucial. On line 14 we delete the existing page template cache. Don’t worry, no data is lost – it is stored in the $templates variable.
On line 18 we merge the existing page templates cache with our new entries, and on line 22 we re-insert the whole page template cache into WordPress’s system.
Simple!
view_project_template ()
We’re now onto our final method; this is where we tell WordPress where the real page template file is.
/**
* Checks if the template is assigned to the page
*/
public function view_project_template( $template ) {
// Get global post
global $post;
// Return template if post is empty
if ( ! $post ) {
return $template;
}
// Return default template if we don't have a custom one defined
if ( !isset( $this->templates[get_post_meta(
$post->ID, '_wp_page_template', true
)] ) ) {
return $template;
}
$file = plugin_dir_path(__FILE__). get_post_meta(
$post->ID, '_wp_page_template', true
);
// Just to be safe, we check if the file exist first
if ( file_exists( $file ) ) {
return $file;
} else {
echo $file;
}
// Return template
return $template;
}
Ok then, this method will be checking against the global $post variable (line 6). It checks to see if a page template ( ‘_wp_page_template’ ) has been set for the post (meaning it must be a page). If not, then never mind – non-pages can’t have page templates.
Line 16 specifies the location of the page template file. As I have set out above, it checks for the specified page template file in the root directory of your plugin. (This can be easily changed though; see below.)
// Just changing the page template path
// WordPress will now look for page templates in the subfolder 'templates',
// instead of the root
$file = plugin_dir_path(__FILE__). 'templates/' .get_post_meta(
$post->ID, '_wp_page_template', true
);
After this, on lines 21 – 24, we have just a little bit of validation which checks if the file actually exists. If yes, awesome! If not, oh dear… You will most likely get a PHP error message if WordPress can’t find the template file, or even a blank screen. If any of these symptoms sounds familiar, just check the template file path by printing the $file variable to the screen.
If you plan to use this code commercially (which you are free to do – my version of the code comes with no license, hence you are free to do with it as you please), I truly recommend investing some time in error handling for maximum reliability.
That is that. With our class completed, there is only one thing left to do – add it to the WordPress head.
add_action( 'plugins_loaded', array( 'PageTemplater', 'get_instance' ) );
Congrats if you made it all the way through! I hope you found what I had to say useful, and you benefit from it in the future!
Entire Code
Bellow is the entire code for the plugin for easy copy and paste.
<?php
/*
Plugin Name: Page Template Plugin : 'Good To Be Bad'
Plugin URI: http://www.wpexplorer.com/wordpress-page-templates-plugin/
Version: 1.1.0
Author: WPExplorer
Author URI: http://www.wpexplorer.com/
*/
class PageTemplater {
/**
* A reference to an instance of this class.
*/
private static $instance;
/**
* The array of templates that this plugin tracks.
*/
protected $templates;
/**
* Returns an instance of this class.
*/
public static function get_instance() {
if ( null == self::$instance ) {
self::$instance = new PageTemplater();
}
return self::$instance;
}
/**
* Initializes the plugin by setting filters and administration functions.
*/
private function __construct() {
$this->templates = array();
// Add a filter to the attributes metabox to inject template into the cache.
if ( version_compare( floatval( get_bloginfo( 'version' ) ), '4.7', '<' ) ) {
// 4.6 and older
add_filter(
'page_attributes_dropdown_pages_args',
array( $this, 'register_project_templates' )
);
} else {
// Add a filter to the wp 4.7 version attributes metabox
add_filter(
'theme_page_templates', array( $this, 'add_new_template' )
);
}
// Add a filter to the save post to inject out template into the page cache
add_filter(
'wp_insert_post_data',
array( $this, 'register_project_templates' )
);
// Add a filter to the template include to determine if the page has our
// template assigned and return it's path
add_filter(
'template_include',
array( $this, 'view_project_template')
);
// Add your templates to this array.
$this->templates = array(
'goodtobebad-template.php' => 'It\'s Good to Be Bad',
);
}
/**
* Adds our template to the page dropdown for v4.7+
*
*/
public function add_new_template( $posts_templates ) {
$posts_templates = array_merge( $posts_templates, $this->templates );
return $posts_templates;
}
/**
* Adds our template to the pages cache in order to trick WordPress
* into thinking the template file exists where it doens't really exist.
*/
public function register_project_templates( $atts ) {
// Create the key used for the themes cache
$cache_key = 'page_templates-' . md5( get_theme_root() . '/' . get_stylesheet() );
// Retrieve the cache list.
// If it doesn't exist, or it's empty prepare an array
$templates = wp_get_theme()->get_page_templates();
if ( empty( $templates ) ) {
$templates = array();
}
// New cache, therefore remove the old one
wp_cache_delete( $cache_key , 'themes');
// Now add our template to the list of templates by merging our templates
// with the existing templates array from the cache.
$templates = array_merge( $templates, $this->templates );
// Add the modified cache to allow WordPress to pick it up for listing
// available templates
wp_cache_add( $cache_key, $templates, 'themes', 1800 );
return $atts;
}
/**
* Checks if the template is assigned to the page
*/
public function view_project_template( $template ) {
// Get global post
global $post;
// Return template if post is empty
if ( ! $post ) {
return $template;
}
// Return default template if we don't have a custom one defined
if ( ! isset( $this->templates[get_post_meta(
$post->ID, '_wp_page_template', true
)] ) ) {
return $template;
}
$file = plugin_dir_path( __FILE__ ). get_post_meta(
$post->ID, '_wp_page_template', true
);
// Just to be safe, we check if the file exist first
if ( file_exists( $file ) ) {
return $file;
} else {
echo $file;
}
// Return template
return $template;
}
}
add_action( 'plugins_loaded', array( 'PageTemplater', 'get_instance' ) );
The Plugin
You can also download the full code as a plugin on Github.
Post Editor Closeup
Here’s a close up of the plugin in action. See the page template added under Page Attributes?
I actually didn’t know how to do this and it’s going to come in handy for a new plugin I’m developing 😉 Thanks for being a contributor with us and sharing your knowledge 😉
Thanks AJ! Its great to be a part of such a great blog!
Nice! I’ve been wondering how to create a Page Template via a plugin. Saving this straight to Evernote for future reference.
I’m glad you’ve found this useful!
Very nice code, simple end good…ten plus.
Thanks for the kind feedback 🙂
Thanks – it helped me greatly.
Do you have any updates for the registration of the page templates in the dropdown? I noticed that it deletes the list of templates provided by the theme, and only lists my custom plugin templates.
Hey there Karl,
I’m sorry you are having this problem. I can see where this error is probably coming from, so I’ll have a look and try and find out what’s going awry!
I’ll update the article and leave another reply here when I have more news and hopefully a solution.
Thanks, Harri
I think I’ve figured it out – the problem lay in retrieving the pre-existing page template cache. I will update the post now, but if you would like to apply the fix manually, simply change;
$templates = wp_cache_get( $cache_key, ‘themes’ ); (Line 92 in pagetemplater.php of the plugin) to
$templates = wp_get_theme()->get_page_templates(); (This is probably a nicer solution in retrospect)
I hope this fixes the problem 🙂
P.S. Pretty proud of the 20 minute response time 😉
Thanks that worked great!
Glad to hear 🙂
Very nice article, working for me !!!. I need to know how can i use this code to my plugin. I used this code to my plugin and then my SMS feature functionality is break. when i comment this file code the SMS feature is again working fine. Please tell me how to properly use this code to plugin.
Thanks and regards,
Yash
Sorry for the delay on this. We’ve updated the code if you want to check it out!
I recently used this plugin/code in one of my own plugins and it worked fantastically. But now i’m noticing that the template added via this code is the only template available to choose from. Is there something to be updated to make this more current?
never mind. i saw the solution posted. works great now
This seems like a great idea and exactly what I need! I have downloaded the code, added my custom templates to: $this->templates = array(
I have added ‘templates/’ to: $file = plugin_dir_path(__FILE__). ‘templates/’
I can activate the plugin in my wp-admin but, it is not showing any of the templates in the page editor template drop-down. I have read and reread this article a and all I can find that Tom McFarlin has posted about this method and I still have the same problem.
Does anyone have any ideas of what I might be doing wrong or know how I could figure it out?
Hello Spence,
Sorry for the delay in replying. Could we possibly discuss this over on Github, as it’s easier to talk through code there.
Thanks!
Harri
Hello Harri,
Thank you for the reply. I figured it out. Details are on the WordPress forms here.
This method works really great! Thanks for all this helpful info.
I did run into one bug that doesn’t stop it from working. It is something that would just be nice to figure out. I detail the minor problem in the WP post but I will explain it again here for anyone else following this.
Using your great explanation and code above, the new templates that I have created show up nicely in the template drop-down in page editors. However, they do not show up in the list of pages under “Quick Edit” template drop-down options. It would be nice to have them show up in the “Quick Edit” options too, for connivance.
I would be happy to continue this conversation on Github.
Hello again Harri,
I got this bug worked out, that was not showing page templates in the “Quick Edit” options of the pages list. It was resolved here if you are interested.
Thanks for posting this helpful info about this plugin method for page templates, it has been a big help.
Great, thanks for sharing Spence!
Thanks Spence – that is actually a really nice solution!
Another solution (to using the ‘wp_dropdown_pages’ filter as explained in the above link) is to hook the method ‘register_project_templates’ additionally to the filter ‘quick_edit_dropdown_pages_args’. This makes the templates appear in the Quick Edit dropdown menu, too. Just an alternative.
Thanks boss. It works great
Great post. I am able to add template in the drop down however Template code does not works. Somehow wordpress can’t find this new templstr created by the plugin. Any help? Thanks
Hello Mushtaq,
This is probably a problem with the path to the template file. Have you edited this line in your code?
$file = plugin_dir_path(__FILE__). get_post_meta( $post->ID, ‘_wp_page_template’, true );
If not, are you sure you have the template file in the root folder of your plugin. If yes, just double check that your new location matches where you keep the files.
If none of the above works, then could you pop over to Github, as it’s easier for us to talk code there.
Thanks!
Harri
Hi, Thanks for the reply, I had changed the line as below :
$file = plugin_dir_path( __FILE__ ) . ‘templates/’ . get_post_meta( $post->ID, ‘_wp_page_template’, true );
Also I have kept the template file under myplugin/templates/mytemplate.php and pageTemplater.php in includes directory. The structure is as follows:
myplugindir/myplugin.php
myplugindir/includes/pageTemplater.php
myplugindir/templates/template.php
P.S: I am new to github, I really don’t know how to create comment/ issue. Thanks
That seems to be ok – what have you put for this;
$this->templates = array(
. . .
);
(Line 72) ?
Harri
That is odd…
Does mytemplate.php contain a valid Page Template declaration header?
e.g;
Harri
This worked out perfectly for me. Thank you for the code! 🙂
Awesome guide – I am having one issue and I can’t seem to narrow down where it is coming from. My template is being found and is working properly but above my header it is spitting out the file path to the template file. Any ideas what could be causing this? I have also read through all of the comments and made appropriate changes where needed and double checked issues others were having. Everything seems like it should be working properly, just not sure why the file path is being echo’d in the header.
Thanks!
Hi there! I’m wondering what your solution was, as I’m experiencing the same error (file path showing instead). Thanks 😊
Never mind 😊 I figured it out. Anyone else, make sure you’re calling the right path FROM the right path.
I had plugins_loaded.php inside a directory, and it was trying to call the template from inside the same directory. Solution:
$file = plugin_dir_path(__FILE__) . ‘../templates/’ . get_post_meta( $post->ID, ‘_wp_page_template’, true );
(see the 2 dots and slash in front of the file name). I hope that helps someone.
Nevermind, found what I was doing wrong. Thanks!
Great, glad you got it working!
Working like a charm. Nothing more to add !!! 🙂
Hello Harri,
I want to create page template for frontend & this seems to be for admin section. Can you help me to tell how can i solve my requirement? Any suggestions.
Thanks,
Vishal
Hi Vishal,
It’s the same thing. Have a look at the CODEX for creating the page template file.
Thanks for the great tutorial. Is it possible to register a custom header template using the same approach? This should not appear on the drop down.
Awesome solution! Thanks. This is really going to be a big time saver 🙂 You Rock!
Muchas muchas gracias! Una y otra vez lo digo, gracias por toda tu ayuda!
Absolutely a great tutorial! Many thanks for it!
First: thamk you verry much for your outstanding solution, Harri! It works perfect for me!
But I have a little question:
I am writting a PlugIn, this PlugIn injects different Page-Templates into a existing Theme. For this, I use your awesome code. It works perfect.
But, i also want to enqueue a Script only on Pages who uses the injected Page-Templates.
For this I use the WP-Function “is_page_template()” http://codex.wordpress.org/Function_Reference/is_page_template
But it doesnt work, whatever data path I try.
For better understanding whats going on, I output two diferent Parameters (WP-Functions) inside the Template.
For the first “get_page_template_slug( $post->ID );”, I get the right name of the injected Page-Template back.
But for the second “get_page_template(__FILE__);” I get the absolute path to the default Template inside the used Theme (page.php) back.
So, I am a litte bit confused, dont know how to enqueue Scripts only on the injected Pagetemplates.
Hope, you understand my bad english -> sorry for that!
But if you have a question, i will answer!!
If you need some Code-Snippets from me, i will post!!
Thamks,
Pixselig
Sorry, for second post!
I only want to say, that I got it to work!
My brain was fried – the answer is very easy:
“is_page_template()” can only be called afte the template has been loaded. So I had to add some wp-action:
This solution had nothing to do with the great code from Harri – its the common way to check for templates in WP-functions.
Thanks twice Harri!
Pixselig
Nice! Thanks for sharing.
Thanks for the solution, Pixselig!
Any pointers on how to get this to work with a custom post? I’m creating the custom post via a plugin, and would like to include the archive and post template in the plugin.
Thanks!
Plus one on the CPT and archive page template…
@Robby, what I ended up doing was making a normal page and using the Custom Archive Template page I made. Then I made set has_archive => false.
+1, would really like to know how to make this work with Custom Post Types and plugin-included templates
You simply need to duplicate the line with the filter ‘theme_page_templates’ and update it with the custom post type slug, so for posts it would be ‘theme_post_templates’.
Awesome, thanks for the tip Plamen!
Thanks! It works perfectly for me. Nice help. @Robby I’m doing the same thing I would suggest you to include the class like:
into your main plugin file and it is all since:
Regards!
Hi everyone,
Thanks for this tutorial and comments.
I’m new to wordpress plugins and not sure where exactly the add_action line should be placed. I’ve been placing it in a child theme header.php like this just before the wp_head…
Can someone tell me if this is correct?
If you want to use the add_action function to add something to the head, you would create the function in functions.php and “hook” that function see the examples at the bottom of the CODEX. All that would be added in functions.php
Thanks for this! Delighted it’s now working.
Thank you.
That was JUST what I needed.
I am not a big fan of child themes and prefer to handle everything inside my own plugin
You’re welcome, Jürgen! That was exactly my thinking as well. Glad you found this useful 🙂
Harri
Hi, Thank you for the code.
I’m using Genesis Framework and you allways have to use a child theme with Genesis as parent.
The original code from Tom McFarlin seems to block the templates placed in the child, your code not – so it is perfect!
Thanks for the feedback, Tom! Really glad it’s working for you 🙂
Harri
Hi, Thanks for sharing the code, I was searching for such a thing.
Glad I could help!
You can also scan a directory for templates (so you don’t need to fill the $templates_array var) with this
Thanks for the tip! I’ll look at adding this into the class when I next get the chance 🙂
Harri
Hello, Thank you for the code. I’m not sure yet if this suits my needs and sorry if this post is unappropriate. I’m trying to get the code inside the file goodtobebad-template.php to appear in the page with the default template of my website. But when I sellect the custom template “It’s good to be bad” I only get the code in there and not the rest of the template. I’m I missing something or this plugin is not suitable to inject code into de page content within the the active template?
Thank you.
Hello europop,
You can get your theme’s header, footer and sidebar by calling the get_header(), get_footer() and get_sidebar() functions, allowing you to keep your theme’s general styling while still being able to customise the inner page content. Therefore I do think this is what you’re looking for for the problem you describe.
For more information about what you can do with page templates, I’d recommend taking a look at the examples on the Codex.
Let me know if you have any other questions either here or on Twitter (@harribellthomas),
Harri
Thanks – exactly what I was looking for. Helped a ton.
Glad I could help!
@Harri Bell-Thomas Thanks so much for this, it worked right out of the box. I used this to tie the PayPal API to wordpress actions. I may eventually build it out to generally do “charge for X” where X is publishing a post, submitting a gravity form, etc.
Am I right in thinking that a page template is the best way to tie API’s to the WordPress framework? I’m used to MVC frameworks, so that seems like a janky hack. A page that isn’t meant to be accessed directly doesn’t feel very good.
Hi Joshua,
It’s an interesting point you make, about it being a ‘hack’. I do agree with you somewhat, but the WordPress experience is built upon templates such as these, so it will be greatly different to MVC frameworks. I can assure you that using page templates is normal in WordPress development, specifically for themes.
The implementation I talk about in this article can definitely be seen as a hack, as it hooks in to and amends the WordPress cache; it is done in the most semantically valid way though (and please do correct me if this isn’t the case 😉 ).
If you want to discuss this further (I do find this argument extremely fascinating having triend my hand at Ruby-on-Rails) please feel free tweet me @harribellthomas to discuss this further.
Thanks!
Harri
This Article is Outstanding and worked as well, thanks clarke for this. But i wanna simple ask, since i using your code, my shortcode doesn’t work while using those page template from my developed plugins. Did you know why, or it’s just my mistakes? Anyone here has the same issue? thank before and sorry for my bad english.
Hi rahendz,
I’d recommend looking at the do_shortcode() function. This can be used to execute shortcodes that aren’t currently being executed in your page.
Hope this helps,
Harri
Thank you so much. That was super easy.
Glad I could help you out!
This is something I’ve tried to do multiple times for soooo long. You’ve just solved the final piece of the puzzle on a major project for me. Thank you!!
Thank you !!!!!!
Thank you soooooooooo!!!
Thanks guys! just looking for that kind of plugin.
Hey,
Great plugin, helped me a lot, but I ran into a problem and I was wondering if there’s a workaround.
The site I installed this plugin on uses W3Total cache and each time I update the page the template gets overriden by the default template.
You have to save as draft again and publish it. This is the only way it’ll work.
I’ve tried adding the page slug to w3tc’s page cache/advanced/”Never cache the following pages” but it didn’t work.
Any suggestions?
Do you have the same issue when w3 is not enabled?
If you have multiple theme directories your get_theme_root() might not be correct so better to use this. Specially bedrock has this problem.
‘page_templates-‘ . md5( get_raw_theme_root( get_stylesheet() ) . ‘/’ . get_stylesheet() );
Thanks for the tip!
Thanks! Nice Work!
Awesome work, thanks for uploading such a nice tutorial, it helped a lot..
Hey, I’ve got this problem with wordpress. I created a custom template independent to the my current theme. The problem is that I want plugins to work with it. So I use wp_head() in the head but it override my custom CSS files and break my custom template design. Can you point me to the right direction?
You have to use wp_head() if it’s causing issues with your template design, you probably have to tweak your CSS so it overrides correctly or use wp_dequeue_style to remove any css files you don’t want loaded for this page.
Great solution. Only issue I see is if you are using a Custom Page Post Type (ie: post-new.php?post_type=landing ), the templates show when you create a page in the dropdown, but when you go back in and edit the page the templates dont show in the dropdown. Any idea’s?
Thanks, Great solution, actually I use this in my devs. But I have a question, the page template created don’t showing in the Advanced Custom Fields location by Page Template, any idea how fix that?
Hi, great plugin. It’s just what I need. I see the template in the dropdown but when I select it for a page and save, it resets to the Default Template (or what was previously selected). If I copy the template to the themes folder, it works fine. Any suggestions?
Work fine for me but now i can’t select the template page with ACF.
I try to add a rule location for a field groupe and the template page doesn’t appear.
Any idea’s
In case you still have issue with this or for anyone else, check https://github.com/kenreidy/page-templater/blob/master/pagetemplater.php
Hope that helps…
Hi sir
please if i used this i have to keep the plugin on my site?
what if wordpress got updated will i need to come back here and update the plugin?
i hope my question is clear, am new to deeper wordpress and learning everyday
thanks a lot
Unless WordPress changes the way templates work you won’t have to update anything. If you created a plugin you should be able to update without issues. If you do run into any issues let me know so I can look and then update our code accordingly.
Thanks for this. Very well explained
not possible to add an issue to the github repo
You should check if post exist in view_project_template
Good call, I will update the code on the post.
Huge thanks for this AJ. The class works beautifully
Harri,
I have just started to do some research as I am using two custom templates in a plugin and was wondering if this code works will work for the new WordPress 4.7. I just downloaded the WP 4.7 RC and I cannot get my templates to show up when creating a new page? Any help would be greatly appreciated.
Thanks in advanced
Hey, if you check out the github repository it has been updated already to support WP 4.7
Thank you so much for this quick fix! Used this code for a while now and didn’t understand why it wouldn’t work on my new project.
Thanks so much for posting the update; saved me on a project of my own that was affected by the change (where I need to register a page template in a plugin) at https://github.com/redblueconcepts/redblue-sections
Awesome!
What were the changes? I have a plugin using this on two sites, and I’d like to quickly update the code.
Hi Paul,
If you go to the Github repository you can click on “History” to see all the changes that have been made to the code over time. You can also subscribe to be notified of any changes to the repository if you want.
4.7 upgrade broke it. I nearly flipped.. Then I upgraded from the git repo. Thanks for being on top of it and letting me keep my sanity.
Super helpful tutorial and example code. Does exactly what I need for a client project. Thank you!
This plugin does not work: Copied and pasted code verbatim. No template dropdown appears, and when I force it to appear by adding a new page template to the theme folder (Twenty Seventeen) the template name(s) in this plugin do not appear in the list.
The code has been updated recently to fix issues with the latest version of WordPress (4.7) everything should be working now with the updated code.
Stop running on wordpress version 4.7, could you help us?
We’ve updated the code to fix any issues with 4.7. In the future you may want to “subscribe” to the Github repository because we do push out updates there from time to time and you can also report any issues there and or pull-requests.
I think this broke with wp 4.7, the templates still work but no longer show in the select list.
Please check out the updated code on Github. I will update the article right now as well 😉
Amazing work! This helps me a lot! Thank you!
Super neato…. if anyone is doing this for a custom post type follow Alexis Duran’s comment for the require once in main in your custom post type plugin file worked perfectly for my portfolio custom post type
Much thanks for updating the code for WP 4.7+ compatibility. I was having some trouble with it, but hadn’t gotten around to working on it.
Great post! Keep up the good work and congratulations!
hi in my case that have remove the drop down menu of page template in my dashboard pages section
Thank you for keeping this updated! I really appreciate it 🙂
It stopped working with a new release of WP. I came back here and sure enough it works with the updated code you provided.
Thank you for updating for WP 4.7.x!
Thank’s a lot for the update !!!!
This is exactly what I was looking for! Thank you very very much!!!
Thank you so much, this code help Me ^^
Thank you. This was extremely helpful.
I adapted this code with slight modifications as a composer package. Hope it helps someone. https://github.com/codelight-eu/wp-page-templates
Cool! Thanks for sharing 😉
This is exactly what I was looking for. Thanks for the great help, keep it up. 🙂
Excellent plugin thanks. I have a question is it possible to add some content to it like html and PHP and so on so that the page can follow the theme’s structure? Would appreciate the help!
Why wrap it in an object? It’s way easier to incorporate code into an existing plugin if it’s just plain functions. You can still throw it in your own object if you want.
If anyone is interested, I re-wrote it this in about half the amount of code without objects, designed for just one template (but easy to add more):
https://gist.github.com/RadGH/025b6c80187be200e05e6e89ad6fadfd
The update for 4.7 saved my life. Thanks a lot!
THANK YOU very much for this! Works like a charm. I have recently ventured into building plugins. The only thing I have not been able to figure out is how to include page templates in my plugins. Thanks, again.
Thanks! Exactly what I was looking for and it works like a charm on my WP 5.3.1. installation.
A ton of thanks to you. It works perfectly on WP 5.4 multisite
Thanks ! This post helped me a lot. 🙂
Wow, its 2020 and this code still works!
Thanks Harri.
Thank you Harri, this post was really useful for me
I’m kinda new to WordPress, Templates, Plugins, but I managed to get this to work. Thanks for the excellent code. One of the post that was really helpful, (and put on my light bulb), was the post regarding:
$this->templates = array(
. . .
);
This is a great post. Saved me from adding post types for just lots of css/js for a plugin. Kudos and thanks!
Great article Harri!
I’ve been pounding this issue for days with no clear solution in the view until I found your article.
You saved the day!!!
Thanks,