WordPress templates can be overridden to create a different layout of the content or to add additional content directly on the template. Usually plugins provide basic templates for their content which can be then overridden by themes. In this tutorial we will learn how you can override WordPress templates and even provide that option in your own plugin.
Before we code our own override rules, we need to understand how WordPress works. The best thing you can do to understand it is to read the WordPress Template Hierarchy. Here is a simple explanation:
- User visit a single post
- WordPress looks for a template in the theme for that custom post type
- If there is no specific custom post type template defined it will use a general single post template
- If there is no single page template defined it will use the index.php
What are those templates?
A general single post template is single.php, or for a page is also page.php. For a custom post type, for example: Portfolio, which slug is portfolio the specific custom post type template would be single-portfolio.php.
There can be templates defined by the slug of a post or page. We could have a page title Checkout which slug is checkout and the specific template would then be page-checkout.php.
Including WordPress Templates
WordPress template can be included by using the filter template_include. When that filter is used, WordPress has already loaded the page and we can use WordPress conditionals to check on which page we are.
Let’s say that we want to include a specific page template for our previously mentioned Checkout page. We would do this:
By using the function locate_template we are looking for a template that exists in our theme (or even in our parent theme if we are using a child theme).
This is a rather simple example so that you can easily understand it. Let’s see how can we include a template from a plugin.
Including WordPress Templates from a Plugin
Including a template from a theme is really simple with a function such as locate_template. When it comes to including templates from a plugin, this can be a slightly different than what we did for a theme.
When using a plugin, a good practice would be to define a folder that will hold all our templates. Let’s say the folder would be named templates. Inside that folder we would have different templates such as checkout.php from the previous example.
Another good practice would be to define a constant at the first lines of code that will hold our plugin directory path so that we can easily reference to any file in our plugin from any file in our plugin. We could also define one for our templates folder:
Now that our constants are defined we can easily reference to any template in our templates folder:
The variable $template contains the whole path to the template file which WordPress will display. We must specify a template to use over the template WordPress has found in our theme. By using this conditionals we have specified the templates we want to use. If those templates do not exist in our plugin, we will return the provided template.
Using the Provided WordPress Template
What if we wanted to make our process a little simpler? Let’s say that we have our custom post type Portfolio and another one Services. We could specify templates for each of them but that could take time if we had many custom post types or even something else.
We could use the provided WordPress Template for our custom post types. So if our provided WordPress Template is single.php we could have those templates defined in our plugin for each custom post type. If the WordPress template is single-portfolio.php we would not include that because that is the template our theme used to specify the layout for our custom post type. We do not want that overriden.
In these example we are defining our custom post types at the beginning. This could be also done by an outside function to keep it more maintainable. After that, we are checking if we are on a single page or an archive page for that post type. If that is not true we are just returning the provided template. By doing that, we are securing that the WordPress life cycle will not be interrupted by a non existing template.
On the other hand, if we are on a page of our custom post type then we will inspect the provided template by transforming the string into an array. The separator for each array element will be the path separator /. To get the template name we use the function end.
Since, at this point we already know that we are on a page of our custom post type, we are using the function get_post_type to get the current post type slug. That will be used in our plugin so that we can look into a subfolder to check for such template.
If we are on single page of a portfolio post type, the path would be templates/portfolio/single.php.
Creating Overridable Custom WordPress Templates in Plugin
You now know everything about overriding and including WordPress templates. Let’s now look at a different scenario where we provide our custom templates that are can’t be replaced just by simple WordPress hierarchy in the theme.
Why would I do that? This can be useful when you are using some generic names such as we did with Portfolio and Services in the examples above. This can also be useful if we have a templating function to get parts of our templates and we want to make it available for override.
Ok, let’s go with our well known Portfolio custom post type. For our portfolio we will still use our single-portfolio.php but we have some parts of our portfolio page that are defined by functions. For example:
This will get a header for our portfolio template. We are here also using another function my_plugin_get_template which we defined immediately after.
In this function we are searching for a folder my_plugin in our theme directory. Inside that folder we are searching for a subfolder portfolio and a file header.php. If that folders and file do exist in our theme, we will provide that template. If that file or folders do not exist, we will look for a template in our plugin as we did when including templates in the examples above.
Conclusion
Including and overriding WordPress templates can be a great thing if you code it carefully. If you are not careful, you could break the whole WordPress life cycle because you returned an empty string for a template. When writing your own plugins with templates, make sure you have overridable templates so that themes can easily change the appearance to match their design.
Have you ever done anything with custom WordPress templates? Did you include some for a project of yours? Share your experience with others in the comments below.
Become a Sponsor
I couldn’t resist commenting. Well written!
Thank you very much John! I am glad that you liked this tutorial.
Thank you for this tutorial. I want to define a custom footer.php template inside a site plugin. I tried some of the examples you shared, but could not make it work. Could you please advise on the following code? All suggestions are welcome.
add_filter( ‘template_include’, ‘force_customization’ );
function force_customization( $newtemplate ) {
if ( is_singular( ‘footer’ ) ) {
$newtemplate = plugin_dir_path( __FILE__ ) . ‘customization/php/backpackingseriesfooter.php’;
}
return $newtemplate;
}
Kind regards,
Abhijeet
Hi Abhijeet, that would not be possible since the footer is another thing here. The template_include is used on a higher level and it will include a complete template which would have the get_header & get_footer inside. Since WordPress looks at footer and header to be theme specific, you can’t change it in that way. You could copy the whole template in your plugin and then instead of get_footer add your own footer there. I don’t see it possible in another way.
Thank you Igor.
I do not quite follow your recommendation. I am sorry but I am a newb (to both wordpress and coding) trying to get a hang of things here. Are you suggesting to copy the entire theme directory structure inside the plugin to make this happen?
Kind regards,
Abhijeet
I wanted to share this one resource for your consideration too and seek your advise whether I can achieve what I am looking to. – https://9seeds.com/including-templates-inside-a-plugin/#comment-474924
Really appreciate your guidance here.
Hi Abhijeet, as you have already read on there also, you can’t change the footer template with filters since it’s just a part of a template not a template itself. That is why I have told you that you might want to copy the template inside your plugin and then change it from there. And I mean the whole template with
get_header()
call but without theget_footer()
call since you want a custom footer. But don’t forget to addwp_footer()
at the end of the template (before thetag).
Hi, Igor. Good article. There is such question. Do you know how WooCommerce replaces the product listing template in a loop? So that even the subject without the support of WC correctly displays the products without breaking the layout. The fact is that if you just use the hook template_include, Yes, I can substitute my output in taxonomy-product_cat.php. But other html markup can be used in a third-party theme. I hope to help.