In the first part of this blog post we introduced exciting new Twig features like inline comments, PHP enums support, improved operator precedence, the guard tag, and enhanced deprecation handling. This second part highlights other nice recent additions to Twig.
Dot Operator Improvements
The attribute() function allows accessing attributes or properties of variables or objects where the name of the attribute/property is dynamic:
1 2 3 4 5 6 7
{# the dot notation can be used because the property name ('fullName') is known and static #}
{{ user.fullName }}
{# attribute() is needed because the name of the property is stored in a variable #}
{% for property in ['fullName', 'email', 'phoneNumber'] %}
{{ attribute(user, property) }} <br>
{% endfor %}
In Twig 3.15, the attribute()
function is deprecated, and the dot operator
has been extended to handle dynamic properties:
1 2 3 4
{# wrap dynamic properties with parentheses #}
{% for property in ['fullName', 'email', 'phoneNumber'] %}
{{ user.(property) }} <br>
{% endfor %}
Although the attribute()
is deprecated, it will remain available in Twig 4.0
to ensure a smoother upgrade path.
Another enhancement to the dot operator is the ability to access class constants directly from an object:
1 2 3 4 5 6
{# previously, you needed to pass the fully qualified class name #}
{{ constant('App\\Some\\Namespace\\Of\\Some\\Class::CONSTANT_NAME') }}
{# now, you can also use any object of the class containing the constants #}
{# SHIPPING_TYPE_EXPEDITED is the name of a constant in the Order class #}
{{ order.SHIPPING_TYPE_EXPEDITED }}
Named Arguments Improvements
Twig macros are similar to functions in programming languages and they are
useful to reuse template fragments. Starting from Twig 3.15, you can use
named arguments when calling a macro, with the syntax argument: value
,
just like in PHP:
1
{{ forms.field(type: 'text', name: 'user[name]') }}
Named arguments are also supported when passing arguments with the dot operator:
1 2 3 4 5
{{ user.fullName(maxLength: 32) }}
{% for property in ['fullName', 'email', 'phoneNumber'] %}
{{ user.(property)(escape: true, maxLength: 32) }} <br>
{% endfor %}
With these changes, named arguments are now supported everywhere: functions, filters, tests, macros, and dot operator arguments.
Free-Form PHP Callable Argument Names
Previously, Twig required snake_case argument names when calling PHP callables, regardless of their original signature. In Twig 3.15, you can use either snake_case or camelCase, no matter which format is used by the PHP signature:
1 2 3
{# both syntaxes yield the same result #}
{{ order.summary(include_total: true) }}
{{ order.summary(includeTotal: true) }}
Argument Unpacking
The ...
spread operator can now expand arguments when calling a function:
1 2
{% set attr = [{type: 'submit'}, {class: 'btn btn-primary'}, {'data-tracking-id', '12345'}] %}
{{ html_attributes(...attr) }}
Arrow Functions in All Twig Callables
Arrow functions, a favorite of many developers, are now supported everywhere in Twig. Previously supported in filters and functions, they can now also be used in tests, macro arguments, and method call arguments:
1 2 3 4 5 6 7
{% set people = [
{first: "Bob", last: "Smith"},
{first: "Alice", last: "Dupond"},
] %}
{# passing an arrow function to a macro #}
{{ _self.display_people_names(people, (person) => person.first) }}
Arrow functions can now also be stored in Twig variables:
1 2 3 4
{# defining the arrow function and storing it in a variable #}
{% set first_name_fn = (p) => p.first %}
{{ _self.display_people_names(people, first_name_fn) }}
This is really good news. I only miss
===
, because I write it out of habit and then have to correct it.