The majority of the work that I do right now focuses on custom plugins or utilities that work on top of WordPress.
If you were to conceptualize how many of the projects that I build are put together, you’d review WordPress (and all that it entails) as the foundation, and then the code has having a layer that communicates with WordPress, and that may communicate with third-party APIs.
When doing this, though, there’s often a front-end component that requires I render information into templates. Though building templates for WordPress aren’t inherently difficult (though I do wish we had a bit more than template tags – such as a templating engine, that’s another post), I think it’s worth looking at a couple of ways that we can handle custom templates that we bundled with plugins.
One of the first questions that’s often raised with this statement, though, is
Why would you include custom templates in a plugin?
And I get it on some levels.
- Keeping templates in a plugin blurs the lines a bit between themes and plugins especially when you leave themes for presentation and plugins for business logic,
- Asking users to copy theme files on from one location to another is bad user experience.
But there are a few rebuttles or perhaps outright exceptions to the above cases.
WordPress template_redirect Hook
Before talking about the WordPress template_redirect hook, I want to talk a bit about the points mentioned above.
1. Templates in Plugins
If you’re building a custom plugin that interfaces both with WordPress and a third-party API or that uses some type of combination of repositories, factories, models, and views, then you’re going to need to display this information on the front-end, and it needs to be theme agnostic.
This doesn’t mean that someone can’t style the elements on the page or include the template in their work, but it does mean that the plugin should provide a basic level of information that’s rendered to the user.
2. Asking Users to Copy Files Is Bad
Remember the slogan that Apple once and often touted as “It just works?” Even though it may not be something they spout off as much as they once did (if at all, anymore), I like the idea of having “just work” for the user, and it’s something that I try to strive for in my work.
So when it comes to creating custom templates or views for plugins, I don’t want to ask the user to have to copy files. I just want them to:
- install the plugin,
- click activate.
And that’s it. The rest should be either self-evident or well-documented.
Back to the Hook
Okay so let’s assume for a moment that we’ve built a plugin, the plugin includes several basic templates (or views depending on the lingo you use) and that the templates need to be written to the root of the active theme’s directory.
You can use the template_redirect hook (and many popular plugins do that). You can read more about it here, but the gist of it is as follows:
This action hook executes just before WordPress determines which template page to load. It is a good hook to use if you need to do a redirect with full knowledge of the content that has been queried.
And, to be clear, I’m not dissuading the usage of this hook. I’m just offering an alternative. And that’s this (as it should work as follows):
- activate the plugin,
- locate the active theme,
- if they don’t already exist, copy the template files from the plugin to the active theme’s root directory
The final step is critical because if the template files do exist, then it’s important not to overwrite them primarily because the user could have written their customizations.
With that said, here’s how you can do it in a single function (complete with comments to show what you’re using).
Note that this uses several PHP functions. Namely:
All of which I think are handy and important to know regardless of the nature in which you’re using them.
Do Hosts Support This?
Some hosts do. I know for a fact that hosts like WPEngine do not and this is not a critique of the host, either. Some do it for security reasons; others allow it but that doesn’t mean they are less secure – it just means they have their infrastructure set up differently.
Ultimately, this goes to show to that there are other ways of making templates available to users when a plugin is being used, but it’s not the only way, and it may not always work.
Having options is good, though, especially if you prefer a specific architecture in your plugin over another.