* 0.9.5-DEV
+ * added the in operator (as a syntactic sugar for the in filter)
* added the following filters in the Core extension: in
* 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
The following operators are very useful but don't fit into any of the other
two categories:
+ * `in`: Perform containment test. Returns `true` if the left operand is
+ contained in the right. {{ 1 in [1, 2, 3] }} would for example return
+ `true`. To perform a negative test, the whole expression should be prefixed
+ with `not` ({{ not 1 in [1, 2, 3] }} would return `false`).
+
* `|`: Applies a filter.
* `~`: Converts all operands into strings and concatenates them. `{{ "Hello "
You can use this filter to perform a containment test on strings, arrays, or
objects implementing the `Traversable` interface.
+The `in` operator is a syntactic sugar for the `in` filter:
+
+ [twig]
+ {% if 1 in [1, 2, 3] %}
+ TRUE
+ {% endif %}
+
+ {# is equivalent to #}
+
+ {% if 1|in([1, 2, 3]) %}
+ TRUE
+ {% endif %}
+
### `default`
The `default` filter returns the passed default value if the value is
$lineno = $this->parser->getCurrentToken()->getLine();
$expr = $this->parseAddExpression();
$ops = array();
- while ($this->parser->getStream()->test(Twig_Token::OPERATOR_TYPE, $operators))
+ while (
+ $this->parser->getStream()->test(Twig_Token::OPERATOR_TYPE, $operators)
+ ||
+ $this->parser->getStream()->test(Twig_Token::NAME_TYPE, 'in')
+ )
{
$ops[] = array($this->parser->getStream()->next()->getValue(), $this->parseAddExpression());
}
public function compile($compiler)
{
+ $nbOps = count($this->ops) > 1;
+ if ('in' === $this->ops[0][0])
+ {
+ return $this->compileIn($compiler);
+ }
+
$this->expr->compile($compiler);
$i = 0;
- $useTmpVars = count($this->ops) > 1;
foreach ($this->ops as $op)
{
if ($i)
list($op, $node) = $op;
$compiler->raw(' '.$op.' ');
- if ($useTmpVars)
+ if ($nbOps)
{
$compiler
->raw('($tmp'.++$i.' = ')
$compiler->raw(')');
}
}
+
+ protected function compileIn($compiler)
+ {
+ $compiler
+ ->raw('twig_in_filter(')
+ ->subcompile($this->expr)
+ ->raw(', ')
+ ->subcompile($this->ops[0][1])
+ ->raw(')')
+ ;
+ }
}
--- /dev/null
+--TEST--
+Twig supports the in operator
+--TEMPLATE--
+{% if bar in foo %}
+TRUE
+{% endif %}
+{% if not bar in foo %}
+{% else %}
+TRUE
+{% endif %}
+--DATA--
+return array('bar' => 'bar', 'foo' => array('bar' => 'bar'))
+--EXPECT--
+TRUE
+TRUE
}
}
-$t = new LimeTest(53);
+$t = new LimeTest(54);
$fixturesDir = realpath(dirname(__FILE__).'/../fixtures/');
foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($fixturesDir), RecursiveIteratorIterator::LEAVES_ONLY) as $file)