Connecting Twig templates in WordPress: How to avoid conflicts
Table of Contents
Twig is a powerful template engine that enables us to create clear and expressive front-end templates. It is widely used in frameworks like Symfony and Drupal. However, WordPress does not natively support Twig, so if we want to use Twig templates, we must connect it manually.
We recently tackled this challenge while working on our plugin, which offers smart templates for displaying content in WordPress. Since our plugin required a template engine, we embarked on the journey of integrating Twig. In this article, we'll share our experience and the solution we arrived at.
Why not use Twig directly in WordPress?#
We chose not to integrate Twig directly into our plugin due to the potential for conflicts with other plugins.
Even if you're developing a theme, we strongly advise against overlooking the possibility of conflicts.
So, what exactly are these conflicts? They arise when multiple plugins or a combination of plugins and themes use Twig but in different versions.
Unlike Node.js, PHP doesn't support multiple versions of the same package concurrently. In the case of Twig, it includes special checks. If several plugins or themes all employ Twig, only the first one will load its version of Twig, and the others will be skipped.
This may seem logical and initially problem-free, but in reality, it can lead to critical errors. Different plugins rely on different Twig versions, so at runtime, they may attempt to use Twig features that weren't loaded, resulting in critical issues.
If you choose to use Twig directly in your plugin or theme, you run the risk of encountering version conflicts with one of these existing plugins or with plugins that may emerge in the future.
Scoping with PHP Scoper#
The optimal solution at the moment is scoping. Scoping involves adding a prefix to the original namespace of a package. This approach is widely embraced among WordPress plugins, and a notable example is the Yoast SEO plugin.
If we encapsulate all Twig files within our namespace, it will prevent any conflicts. But how do we go about doing this?
Enter PHP Scoper, an exceptional Composer package designed to handle this task for us.
Once you've installed the package and think you're all set, reality sets in. The life of a developer is never that simple. PHP Scoper requires us to overcome a few challenges before it allows us to seamlessly integrate Twig templates into WordPress.
Issues with Twig scoping#
PHP Scoper generally works well out of the box with most packages. Unfortunately, Twig is an exception. Aside from the fact that Twig includes a set of global functions (which Scoper can handle), it dynamically generates code while compiling templates. This generated code interacts with Twig classes and functions that are expected to be global.
PHP Scoper is unable to handle these aspects, which means that during runtime, we'll encounter errors like 'function or class is not defined,' as certain parts of the code will attempt to access globally declared classes.
Manually addressing each individual case is not a viable option, as it would take weeks to complete.
It would be beneficial to establish a solution for this issue, wouldn't it? Especially when considering that PHP Scoper supports custom patches, which are essentially functions invoked during runtime to assist with scoping.
Custom patch in PHP Scoper#
So, we've identified the correct approach, but we still need to put in the effort and write the patch snippet.
It may seem like we're in for days of work, but as developers, we should always keep in mind that no matter how challenging our task may seem, there might be someone out there who has already tackled it.
After conducting some research, I discovered that the kind folks at OnTheGoSystems (the developers behind WPML) had already created a patch for this. They, too, needed Twig templates for their WordPress solutions and generously decided to share their solution with others.
The bulk of the work was already done, but life has a way of throwing curveballs. This package was designed for Twig v1 and doesn't cover all the changes introduced in the latest, third version. So, we had to make some improvements ourselves, although they were relatively minor compared to the groundwork laid by OnTheGoSystems.
We've created a repository that includes the Scoper configuration for Twig v3 with the necessary patch. You can utilize it in your projects to safely integrate Twig v3 into your plugin or theme.
Alternative approaches to integrate Twig templates in WordPress#
If manual scoping of Twig doesn't appeal to you, there are alternative solutions worth considering to integrate Twig templates into WordPress.
One option is the Timber framework, which is also available as a plugin. Another option is the Advanced Views plugin, designed to provide smart templates (Twig-based) for displaying content in WordPress.
Timber is more than just a Twig integration—it's a framework that offers a range of helpers and classes in addition to integrating Twig. However, a notable drawback of Timber, especially concerning Twig usage, is that it doesn't inherently scope Twig. By utilizing Timber, you're essentially shifting the responsibility of scoping Twig from yourself to the author, potentially leading to compatibility issues.
On the other hand, the Advanced Views plugin is specifically tailored towards handling templates. Initially an ACF addon, the basic version of ACF suffices; the Pro version is not a requirement. This plugin facilitates the creation of smart templates, where selected post fields are loaded into the template, and it automatically generates a basic markup (following the BEM style), ultimately saving a significant amount of time. You can read about the benefits here, and find more information on the official page.
The journey has come to an end, and we trust that this article has been valuable to you, potentially saving hours of work for someone.
Follow us to get notified about new articles