Preparing for use of Twig 2 in Drupal 9
The update from Drupal 8 to Drupal 9 includes updating the Twig dependency from Twig 1 to Twig 2. Unfortunately due to how composer dependencies work for Drupal 8 sites, we cannot update Drupal 8 to optionally allow Twig 2 support, even though the API is fully ready for that. So these changes can only be made currently in your Drupal 9 environment.
Use Upgrade Status 8.x-2.x either on the UI or via Drush to check your Twig files for deprecated syntax use. Fortunately, the changes from Twig 1 to Twig 2 should be manageable for most users, and many projects will not require any changes.
Template-facing Twig 2 changes
Twig 2 has a few small changes that impact the template level language (i.e. the language used in .html.twig files):
-
As of Twig 2.0, macros imported in a file are no longer available in child templates anymore (via an
includecallfor instance). Macros must now be explicitly imported in each file they are used. -
Silent display of undefined blocks is deprecated since version 1.29 and will throw an exception in 2.0. This can be addressed by wrapping potentially-undefined blocks in conditionals that verify they are defined before attempting to display them.
{% if block('potentially-undefined-block') is defined %} {{ block('potentially-undefined-block') }} {% endif %} -
Using an
ifcondition onfortags is deprecated since Twig 2.10.0, use afilterfilter or anifcondition inside theforbody instead (if your condition depends on a variable updated inside the loop).<ul> {% for user in users if user.active %} <li>{{ user.username|e }}</li> {% endfor %} </ul>can be replaced with:
<ul> {% for user in users|filter(user => user.active) %} <li>{{ user.username|e }}</li> {% endfor %} </ul>or
<ul> {% for user in users %} {% if user.active %} <li>{{ user.username|e }}</li> {% endif %} {% endfor %} </ul>And if you are filtering against the key.
<ul> {% for key, item in items if key|first != '#' %} {{ link(item.title, item.url) }} {% endfor %} <ul>can be replaced with:
<ul> {% for key, item in items|filter((value, key) => key|first != '#') %} {{ link(item.title, item.url) }} {% endfor %} <ul>
-
As of Twig 2.7, the
spacelesstag is deprecated. Use thespacelessfilter instead or{% apply spaceless %}- {% spaceless %} + {% apply spaceless %} {{ element_to_be_spaceless }} - {% endspaceless %} + {% endapply %}(The filter
apply spacelesshas been deprecated in Twig 3.12. It is still available in Drupal 11. Drupal core is removing use of this filter in #3477375: Provide non-deprecated replacement for Twig "spaceless" filter.) -
As of Twig 1.x, the
rawtag is deprecated in favor ofverbatim -
The
sameasanddivisiblebytests are deprecated in favor ofsame asanddivisible byrespectively. -
As of Twig 1.x, using the
_selfglobal variable to access to the current\Twig\Templateinstance is deprecated. In Twig 2.0, the output of_selfis the current template name, so instances of{{ _self.templateName }}should be replaced with{{ _self }}. Note that_selfcan still be used to access macros - e.g.{{ _self.macro_name() }}is still valid.
Changes affecting module developers
Changes affecting module developers can also be detected using the Upgrade status module.
Major changes include:
- As of Twig 1.x, the ability to remove an extension is deprecated and the
\Twig\Environment::removeExtension()method will be removed in 2.0. - As of Twig 1.x, use
\Twig\TwigFunctionto add a function. The following classes and interfaces will be removed in 2.0:Twig_FunctionInterfaceTwig_FunctionCallableInterfaceTwig_FunctionTwig_Function_FunctionTwig_Function_MethodTwig_Function_Node
- As of Twig 1.x, use
\Twig\TwigFilterto add a filter. The following classes and interfaces will be removed in 2.0:Twig_FilterInterfaceTwig_FilterCallableInterfaceTwig_FilterTwig_Filter_FunctionTwig_Filter_MethodTwig_Filter_Node
Additional information on the change from Twig 1 to Twig 2
- Overview of Twig 1.x deprecations: https://twig.symfony.com/doc/1.x/deprecated.html
- Full change log: https://github.com/twigphp/Twig/blob/2.x/CHANGELOG
Help improve this page
You can:
- Log in, click Edit, and edit this page
- Log in, click Discuss, update the Page status value, and suggest an improvement
- Log in and create a Documentation issue with your suggestion