I’m proud to announce the immediate availability of Twig 0.9.5.
Before upgrading from 0.9.4, read this post carefully as this new release
might break your existing code.
The documentation has been
updated to reflect the changes made in this new version. We have also enhanced
the documentation based on the feedback we had.
New Features
.. Operator
One of the main frequently asked question was about iterating over a range of
integer. Thanks to the new .. operator, this is now really easy to
accomplish:
{% for i in 0..10 %}
* {{ i }}
{% endfor %}
The above snippet of code prints all numbers from 0 to 9.
The left and right side of the .. operator can be any valid expression:
{% for letter in 'a'..'z' %}
* {{ letter }}
{% endfor %}
{% for letter in 'a'|upper..'z'|upper %}
* {{ letter }}
{% endfor %}
Note that the .. operator is just syntactic sugar for the range filter.
The first example is equivalent to the following:
{% for i in 0|range(10) %}
* {{ i }}
{% endfor %}
Array Support
Twig supports a new literal: arrays. Arrays are defined by a sequence of
expressions separated by a comma (,) and wrapped with squared brackets
([]). Arrays can also be nested as much as needed:
{% set foo as [a, 'b', ['c', 'd']] %}
Like in PHP, arrays are a mix between lists and dictionaries, arrays and
hashes:
{% set foo as ['a': 'a', 'b': 'c'] %}
in Operator
The in operator performs a containment test. It returns true if the left
operand is contained in the right one:
{{ 1 in [1, 2, 3] }}
{# returns true #}
{% if current_user in users %}
{# do something #}
{% endif %}
To perform a negative test, the whole expression should be prefixed with not:
{{ not 1 in [1, 2, 3] }}
{# returns false #}
The in operator is just syntactic sugar for the in filter. The first
example is equivalent to the following:
{{ 1|in([1, 2, 3]) }}
Better Filter System
The filter system has been rework to allow for more flexibility. For instance,
You can now easily bundle your filters in your extension class:
class Project_Twig_Extension extends Twig_Extension
{
public function getFilters()
{
return array(
'rot13' => new Twig_Filter_Method($this, 'rot13Filter'),
);
}
public function rot13Filter($string)
{
return str_rot13($string);
}
public function getName()
{
return 'project';
}
}
include tag
You can now explicitly pass variables when including another template:
{% include 'foo' with ['foo': foo] %}
The with option can be combined with the sandboxed one to allow for very secure templates:
{% include 'foo' sandboxed with vars %}
Speed improvements
This new version of Twig is faster than any other Twig version. The speed gain
depends on your templates of course.
For even more speed, you can now disable the automatic creation of the loop
variable in a for loop:
{% for i in 0..10 without loop %}
* {{ i }}
{% endfor %}
Miscellaneous
This version also has many other small improvements. The full
changelog read as
follows:
- fixed list nodes that did not extend the Twig_NodeListInterface
- added the “without loop” option to the for tag (it disables the generation of the loop variable)
- refactored node transformers to node visitors
- fixed automatic-escaping for blocks
- added a way to specify variables to pass to an included template
- changed the automatic-escaping rules to be more sensible and more configurable in custom filters (the documentation lists all the rules)
- improved the filter system to allow object methods to be used as filters
- changed the Array and String loaders to actually make use of the cache mechanism
- included the default filter function definitions in the extension class files directly (Core, Escaper)
- added the // operator (like the floor() PHP function)
- added the .. operator (as a syntactic sugar for the range filter when the step is 1)
- added the in operator (as a syntactic sugar for the in filter)
- added the following filters in the Core extension: in, range
- added support for arrays (same behavior as in PHP, a mix between lists and dictionaries, arrays and hashes)
- enhanced some error messages to provide better feedback in case of parsing errors
Backwards Incompatibilities
Custom Filters
If you have defined custom filters, you MUST upgrade them for this release.
Before 0.9.4, filters were defined with a simple array like this:
// before
'even' => array('twig_is_even_filter', false),
'escape' => array('twig_escape_filter', true),
As of 0.9.5, a filter is defined as an object and the needs_environment
option replaces the Boolean:
// after
'even' => new Twig_Filter_Function('twig_is_even_filter'),
'escape' => new Twig_Filter_Function('twig_escape_filter', array('needs_environment' => true)),
NodeTransformers
If you have created NodeTransformer classes, you will need to upgrade them
to the new interface. Read the built-in transformers classes to learn more
about this topic.
Upgrading
Upgrading can be done in a few easy steps:
Install the new version (via
PEAR, SVN, Git, or by downloading the new package);
Read the previous section about backward incompatibilities, and upgrade
your code accordingly;
Remove all cached templates;
Test.