Upgrading to Twig 2

Doing a major version upgrade is always fun so this is no exception. I use Twig for my PHP projects so I run into multiple little snags whilst upgrading to version 2. I have listed the most interesting ones here with the errors I was seeing and the recommended updates:

  • macros defined in parent templates
  • the spaceless block
  • nested blocks in other statements

Macros defined in parent templates

A new change introduced with Twig 2 means that macros should be imported from the templates that are actually using them.
Say you have the following hierarchy of templates:

+-- homepage.html.twig
    +-- page.html.twig
+-- login.html.twig
    +-- change_password.html.twig

with a macro being imported in base.html.twig and used from page.html.twig. This will produce the following error now:

Accessing \Twig\Template attributes is forbidden.

The way to resolve this is to actually import the macro in page.html.twig.
This creates some repetition, especially if that is being used from multiple locations, but at the same time it brings the macro closer to the point of use (reference here).


Prior to version 1.38 of twig we could use the following syntax to remove spaces from compiled templates

{% spaceless %}
        <b&gt;Some text</b&gt;
{% endspaceless %}

This needs to be replaced now with the spaceless filter

{% filter spaceless %}
        <b&gt;Some text</b&gt;
{% endfilter %}

Nested blocks

This was a little bit cryptic as an error message

User Deprecated: Nesting a block definition under a non-capturing node in “template_view.html.twig” at line 11 is deprecated since Twig 2.5.0 and will become a syntax error in 3.0.

But what it actually says is that somewhere in the template you have a block nested inside a different type of statement which is not allowed. The following template snippet is going to produce this warning for example

{% if someValue == false %}
    {% block name %}
        <h2&gt;The value is actually true</h2&gt;
    {% endblock %}
{% endif %}

The way to fix is to reverse the two statements but make sure that the same result is observed by doing so.

{% block name %}
    {% if someValue == false %}
        <h2&gt;The value is actually true</h2&gt;
    {% endif %}
{% endblock %}

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s