How to easily use Twig templates in your WordPress plugin
In this post I’m going to show how to easily integrate the Twig templating system into your WordPress plugin code, allowing you to separate the program logic from the presentation.
Why use a templating system in WordPress?
There are many good things about using WordPress to set up a website. It’s quick to get running, has a ton of useful plugins and thousands of themes meaning for the majority of applications you can have a great looking site running very quickly.
If you need to extend WordPress with some new functionality, it’s easy to create a new plugin and the callback system in WordPress, using filters and actions, although a bit old fashioned is still a very effective way of hooking into core parts of the system without needing to modify the base WordPress code.
The place I find it tends not to shine is in the mixture of program logic and presentation. For this reason I decided I’d like to use a proper templating system in the plugins I develop and I thought I’d share how I do that.
Using Twig as a plugin presentation layer
The choice of Twig for templating was fairly natural to me because in my professional life I use Symfony in a few of the applications I develop and it is the templating system used by Symfony.
The first thing I did was a search to see if anyone had already produced a plugin to enable this, but all I found was a system which enabled Twig to be used in the main WordPress theme. That makes sense of course, but I didn’t want to limit the themes I could use[efn_note]Just to be clear I didn’t investigate the plugin I found in any detail so it may not limit the use of conventional themes[/efn_note] so I decided to add it to my own plugins within the plugin code.
The first prerequisite to adding twig is that you use composer to set up any additional modules your plugin is going to use. Although it would be possible to do this without using composer, the process is so much simpler with it that it’s basically a requirement. For guidance on setting up composer in WordPress, look at this article I wrote a few weeks ago.
Setting up Twig
Setting up Twig is fairly simple once you have set up composer. You just need to cd into the directory where the composer.json file is and run the command
php composer require "twig/twig:^3.0"
which will install the latest version 3.
The next step is to create a directory where the templates you create are going to be stored. In my projects I created a ‘templates’ directory in the top level plugin directory. This fits well with my normal directory structure, but it doesn’t really matter where it is as long as you can get a file path to the directory and set up the twig loader. Make sure you set the permissions of this directory so that the webserver can read the template files.
The next step is to set up the Twig Loader so it can read the templates from the directory you have created. In the classes where you want to call and render the template, you define a loader class which will be used to load the templates. Since my plugins are all written as classes, I just put this code in the class constructor:
protected $loader;
public function __construct()
{
$this->loader = new FileSystemLoader(__DIR__ . '/../templates/');
}
So that is all you need to do to set everything up.
Using Templates in your code.
With those simple steps complete you are ready to use a template in your code and I’m going to use a simple example to show how easy it is and how much better your code looks as a result.
This example comes are a site I run which uses the Advanced Custom Fields plugin to add an input form for a Custom Post Type. One simple function is used to move the content field from the standard WordPress editor (not the block editor but the original editor) into the ACF form for presentation purposes.
This first block of code shows how that was achieved before I switched to using twig. The function ff_acf_admin_head was called with an add_action call in the class constructor and basically drops out of php to echo some javascript and style tags.
public function ff_acf_admin_head()
{
// Add some javascript to move the native editor into the message field created for it
?>
<script type="text/javascript">
(function($) {
$(document).ready(function() {
$('.acf-field-76a4d326').append($('#postdivrich'));
});
})(jQuery);
</script>
<style type="text/css">
.acf-field #wp-content-editor-tools {
background: transparent;
padding-top: 0;
}
</style>
<?php
}
These two code blocks show how that code was amended to use the templating system to provide the rendered HTML / Javascript code. The first block shows the new ff_acf_admin_head method.
public function ff_acf_admin_head()
{
$twig = new TwigEnvironment($this->loader);
echo $twig->render(
'admin_head.html.twig',
[
'field' => '.acf-field-58442221efb72'
]
);
}
And this next section shows the template code. From this you can see that template variables, which are passed into the template in the first section of code are rendered using the {{ }} syntax in twig.
<script type="text/javascript">
(function($) {
$(document).ready(function() {
$('{{ field }}').append($('#postdivrich'));
});
})(jQuery);
</script>
<style type="text/css">
.acf-field #wp-content-editor-tools {
background: transparent;
padding-top: 0;
}
</style>
Although the code is exactly the same, I find moving the presentation layer into the template leaves the plugin code cleaner and easier to understand and maintain.
And this is a simple example. In plugins which define complex logic it is much easier to understand what they are doing when you don’t need to mix various echo and string join operations in with that code.
Pros and Cons of Templating
So I touched on the advantages of templating at the end of the example section and it’s pretty apparent from previous section what those advantages are:
- Cleaner code in both the php logic and the html template
- Much easier to change the presentation without changing the logic
It would be dishonest to fail to point out that there is at least one disadvantage that I can think of which is that sometimes it’s necessary to loop through the data twice; Once to prepare the data for presentation and then again in the actual template.
This post has only covered the steps necessary to install and use the twig templating system. There are many very useful functions and filters available in the twig system, and it’s very easy to add also add your own if you want. In a future post I may cover some of the basic functionality in the system.