Add Page Templates to WordPress with a Plugin

By WP Saviour •  Updated: 03/04/21 •  8 min read

Change: The code has been updated not too way back to work on WordPress 4.7+

Have you ever ever ever wanted to create your private internet web page templates, nevertheless not had entry to the theme itself? I, as a WordPress plugin author, have found this draw back to be considerably annoying when rising my plugins. Fortuitously the reply is form of simple! I’m going to take you shortly by the few strains of code which you’ll want to dynamically create WordPress Internet web page Templates instantly by PHP.

Inspiration for this textual content and the genius behind the code decision comes from Tom McFarlin: I am using my edited mannequin of his genuine code, which you’ll uncover on his GitHub. I’ve saved his commenting in (along with together with a number of of my very personal) as I uncover it very helpful in explaining what is going on on – I couldn’t have talked about it any greater myself!

You will discover the code in its entirety and an occasion plugin on the very bottom of this put up.

Lets begin?

THE CODE

We’re going to create our PHP carry out using a PHP Class. For these of you who aren’t properly versed with PHP Classes, a Class is printed as an object which accommodates a set of capabilities and variables which might be working collectively. Check out the PHP.internet Introduction for further particulars regarding the syntax and idea.

Our wrapper will solely need three variables:

  1. The Plugin Slug: That’s merely used as a novel identifier for the plugin.
  2. Class Event: As we’re together with an event of this class to WordPress’ head, we’d greater retailer it.
  3. Template Array: As you could possibly guess, that’s an array holding the template names and titles.

Proper right here they’re in code:

class PageTemplater { protected $plugin_slug; personal static $event; protected $templates;

Get Class Event

As I discussed beforehand, we’ll be together with an event of our class to the WordPress header using the add_filter() carry out. Subsequently we’ll need a manner which is ready to return (or create) this event for us.

For this, we’ll need a simple method, which is likely to be known as ‘get_instance’. Try it out beneath;


public static carry out get_instance() { if( null == self::$event ) { self::$event = new PageTemplater(); } return self::$event; }

This is able to be the method known as when our class is added to the WordPress head using ‘add_action()’.

WordPress Filters

Now we’ve sorted out the ‘get_instance’ method, we’ve to sort out what happens when it is really instantiated.

We’re going to use WordPress’s inbuilt add_filter() carry out in order so as to add an event of our class into key elements alongside the WordPress initialisation timeline. Using this method we’ll insert our internet web page templates’ data into associated slots, harking back to telling WordPress what file to utilize as a template when the net web page is known as, and the title to point out on the dropdown menu on the Internet web page Editor.

For this we’ve to make use of the ‘__construct’ method (this is likely to be run when the class is instantiated).


personal carry out __construct() { $this->templates = array(); if ( version_compare( floatval( get_bloginfo( 'mannequin' ) ), '4.7', 'templates = array();’, which is just preparing the variable for use);

  1. Strains 9 – 13: This filter is together with the ‘register_project_templates’ to the ‘page_attributes_dropdown_pages_args’ hook. That’s populating the WordPress cache with our new templates, ‘tricking’ WordPress into believing that the net web page template recordsdata really exist inside the template itemizing. This supplies the net web page templates to the dropdown guidelines on the internet web page attributes meta area inside the internet web page editor.
  2. Strains 16 – 20: Proper right here we’re doing mainly the similar as a result of the sooner code block, in addition to this time we’re together with our internet web page template (if chosen) to the saved put up data as properly.
  3. Strains 23 – 28: This filter is together with the ‘template_include’ to the ‘view_project_template’ hook. It’s a important carry out; this tells WordPress the place your internet web page template file really is. WordPress will use the path equipped by this to render the last word internet web page.
  4. Strains 31 – 34: Although that’s simple, this can be very mandatory. That’s the place you specify the net web page templates it’s good to be added, and the path relative to the file the place the net web page template file is ( eg. ‘one factor.php’ ). I’ve included one occasion (which is likely to be used inside the occasion plugin). Check out beneath for a standard occasion:

$this->templates = array( 'FILE_PATH_AND_NAME' => 'TEMPLATE_TITLE', 'awesome-template.php' => 'Superior', 'templates/organised-template.php' => 'Organised',
);

(Eat, Sleep,) Code, Repeat as necessary.

register_project_templates()


I’ve alluded to this method beforehand; let’s see what it really does.
Primarily, the intention of this method is to manage WordPress’s cache, inserting the associated details about our internet web page templates on the correct places. Have a look on the code first, and I’ll focus on you through it afterwards.
public carry out register_project_templates( $atts ) { $cache_key = 'page_templates-' . md5( get_theme_root() . '/' . get_stylesheet() ); $templates = wp_get_theme()->get_page_templates(); if ( empty( $templates ) ) { $templates = array(); } wp_cache_delete( $cache_key , 'themes'); $templates = array_merge( $templates, $this->templates ); wp_cache_add( $cache_key, $templates, 'themes', 1800 ); return $atts; }

Correct then. Line 4 is the first place to look. As you may need guessed, we’re producing a ‘cache key’. This is likely to be used as a novel identifier for our internet web page template data. Using the md5() carry out merely creates a novel string identifier to steer clear of any conflicts.
Subsequent, on line 8, we’re on the lookout for and retrieving the net web page template cache (if it exists already): this will return an array of paths and titles. On strains 9-11 we study to see if there was any output from the cache query. If positive, good. If not, create an space array to hold the information we is likely to be merging into the cache.
The next step is crucial. On line 14 we delete the current internet web page template cache. Don’t worry, no data is misplaced – it is saved inside the $templates variable.
On line 18 we merge the current internet web page templates cache with our new entries, and on line 22 we re-insert the whole internet web page template cache into WordPress’s system.
Simple!

view_project_template ()


We’re now onto our final method; that’s the place we inform WordPress the place the true internet web page template file is.

public carry out view_project_template( $template ) { worldwide $put up; if ( ! $put up ) { return $template; } if ( !isset( $this->templates[get_post_meta( $post->ID, '_wp_page_template', true )] ) ) { return $template; } $file = plugin_dir_path(__FILE__). get_post_meta( $put up->ID, '_wp_page_template', true ); if ( file_exists( $file ) ) { return $file; } else { echo $file; } return $template; }

Okay then, this method is likely to be checking in direction of the worldwide $put up variable (line 6). It checks to see if an internet web page template ( ‘_wp_page_template’ ) has been set for the put up (which implies it must be an internet web page). If not, then under no circumstances ideas – non-pages can’t have internet web page templates.
Line 16 specifies the location of the net web page template file. As I’ve set out above, it checks for the specified internet web page template file inside the root itemizing of your plugin. (This can be merely modified though; see beneath.)
$file = plugin_dir_path(__FILE__). 'templates/' .get_post_meta( $put up->ID, '_wp_page_template', true );

After this, on strains 21 – 24, we now have only a bit little little bit of validation which checks if the file really exists. If positive, superior! If not, oh costly… You will virtually undoubtedly get a PHP error message if WordPress can’t uncover the template file, or maybe a clear show display screen. If any of these indicators sounds acquainted, merely study the template file path by printing the $file variable to the show display screen.
For those who occur to plan to utilize this code commercially (which you are free to do – my mannequin of the code comes with no license, subsequently you are free to do with it as you please), I actually recommend investing some time in error coping with for optimum reliability.
That is that. With our class completed, there is only one issue left to do – add it to the WordPress head.
add_action( 'plugins_loaded', array( 'PageTemplater', 'get_instance' ) );

Congrats within the occasion you made it throughout! I hope you found what I wanted to say useful, and likewise you revenue from it ultimately!

ENTIRE CODE


Bellow is all of the code for the plugin for easy copy and paste.

WP Saviour