added if modifier support to for loop like {% for k in v if k is odd %}

This commit is contained in:
kotas
2011-06-18 04:00:46 +09:00
parent 027f4890a7
commit f5b9df98be
3 changed files with 79 additions and 8 deletions
+18 -2
View File
@@ -18,9 +18,9 @@
*/
class Twig_Node_For extends Twig_Node
{
public function __construct(Twig_Node_Expression_AssignName $keyTarget, Twig_Node_Expression_AssignName $valueTarget, Twig_Node_Expression $seq, Twig_NodeInterface $body, Twig_NodeInterface $else = null, $lineno, $tag = null)
public function __construct(Twig_Node_Expression_AssignName $keyTarget, Twig_Node_Expression_AssignName $valueTarget, Twig_Node_Expression $seq, Twig_Node_Expression $ifexpr = null, Twig_NodeInterface $body, Twig_NodeInterface $else = null, $lineno, $tag = null)
{
parent::__construct(array('key_target' => $keyTarget, 'value_target' => $valueTarget, 'seq' => $seq, 'body' => $body, 'else' => $else), array('with_loop' => true), $lineno, $tag);
parent::__construct(array('key_target' => $keyTarget, 'value_target' => $valueTarget, 'seq' => $seq, 'ifexpr' => $ifexpr, 'body' => $body, 'else' => $else), array('with_loop' => true), $lineno, $tag);
}
/**
@@ -72,6 +72,15 @@ class Twig_Node_For extends Twig_Node
->indent()
;
if (null !== $this->getNode('ifexpr')) {
$compiler
->write("if (")
->subcompile($this->getNode('ifexpr'))
->raw(") {\n")
->indent()
;
}
$compiler->subcompile($this->getNode('body'));
if (null !== $this->getNode('else')) {
@@ -93,6 +102,13 @@ class Twig_Node_For extends Twig_Node
;
}
if (null !== $this->getNode('ifexpr')) {
$compiler
->outdent()
->write("}\n")
;
}
$compiler
->outdent()
->write("}\n")
+7 -1
View File
@@ -25,6 +25,12 @@ class Twig_TokenParser_For extends Twig_TokenParser
$this->parser->getStream()->expect(Twig_Token::OPERATOR_TYPE, 'in');
$seq = $this->parser->getExpressionParser()->parseExpression();
$ifexpr = null;
if ($this->parser->getStream()->test(Twig_Token::NAME_TYPE, 'if')) {
$this->parser->getStream()->next();
$ifexpr = $this->parser->getExpressionParser()->parseExpression();
}
$this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
$body = $this->parser->subparse(array($this, 'decideForFork'));
if ($this->parser->getStream()->next()->getValue() == 'else') {
@@ -43,7 +49,7 @@ class Twig_TokenParser_For extends Twig_TokenParser
$valueTarget = $targets->getNode(0);
}
return new Twig_Node_For($keyTarget, $valueTarget, $seq, $body, $else, $lineno, $this->getTag());
return new Twig_Node_For($keyTarget, $valueTarget, $seq, $ifexpr, $body, $else, $lineno, $this->getTag());
}
public function decideForFork(Twig_Token $token)
+54 -5
View File
@@ -21,19 +21,21 @@ class Twig_Tests_Node_ForTest extends Twig_Tests_Node_TestCase
$keyTarget = new Twig_Node_Expression_AssignName('key', 0);
$valueTarget = new Twig_Node_Expression_AssignName('item', 0);
$seq = new Twig_Node_Expression_Name('items', 0);
$ifexpr = new Twig_Node_Expression_Constant(true, 0);
$body = new Twig_Node_Print(new Twig_Node_Expression_Name('foo', 0), 0);
$else = null;
$node = new Twig_Node_For($keyTarget, $valueTarget, $seq, $body, $else, 0);
$node = new Twig_Node_For($keyTarget, $valueTarget, $seq, $ifexpr, $body, $else, 0);
$node->setAttribute('with_loop', false);
$this->assertEquals($keyTarget, $node->getNode('key_target'));
$this->assertEquals($valueTarget, $node->getNode('value_target'));
$this->assertEquals($seq, $node->getNode('seq'));
$this->assertEquals($ifexpr, $node->getNode('ifexpr'));
$this->assertEquals($body, $node->getNode('body'));
$this->assertEquals(null, $node->getNode('else'));
$else = new Twig_Node_Print(new Twig_Node_Expression_Name('foo', 0), 0);
$node = new Twig_Node_For($keyTarget, $valueTarget, $seq, $body, $else, 0);
$node = new Twig_Node_For($keyTarget, $valueTarget, $seq, $ifexpr, $body, $else, 0);
$node->setAttribute('with_loop', false);
$this->assertEquals($else, $node->getNode('else'));
}
@@ -54,9 +56,10 @@ class Twig_Tests_Node_ForTest extends Twig_Tests_Node_TestCase
$keyTarget = new Twig_Node_Expression_AssignName('key', 0);
$valueTarget = new Twig_Node_Expression_AssignName('item', 0);
$seq = new Twig_Node_Expression_Name('items', 0);
$ifexpr = null;
$body = new Twig_Node_Print(new Twig_Node_Expression_Name('foo', 0), 0);
$else = null;
$node = new Twig_Node_For($keyTarget, $valueTarget, $seq, $body, $else, 0);
$node = new Twig_Node_For($keyTarget, $valueTarget, $seq, $ifexpr, $body, $else, 0);
$node->setAttribute('with_loop', false);
$tests[] = array($node, <<<EOF
@@ -74,9 +77,10 @@ EOF
$keyTarget = new Twig_Node_Expression_AssignName('k', 0);
$valueTarget = new Twig_Node_Expression_AssignName('v', 0);
$seq = new Twig_Node_Expression_Name('values', 0);
$ifexpr = null;
$body = new Twig_Node_Print(new Twig_Node_Expression_Name('foo', 0), 0);
$else = null;
$node = new Twig_Node_For($keyTarget, $valueTarget, $seq, $body, $else, 0);
$node = new Twig_Node_For($keyTarget, $valueTarget, $seq, $ifexpr, $body, $else, 0);
$node->setAttribute('with_loop', true);
$tests[] = array($node, <<<EOF
@@ -115,9 +119,54 @@ EOF
$keyTarget = new Twig_Node_Expression_AssignName('k', 0);
$valueTarget = new Twig_Node_Expression_AssignName('v', 0);
$seq = new Twig_Node_Expression_Name('values', 0);
$ifexpr = new Twig_Node_Expression_Constant(true, 0);
$body = new Twig_Node_Print(new Twig_Node_Expression_Name('foo', 0), 0);
$else = null;
$node = new Twig_Node_For($keyTarget, $valueTarget, $seq, $ifexpr, $body, $else, 0);
$node->setAttribute('with_loop', true);
$tests[] = array($node, <<<EOF
\$context['_parent'] = (array) \$context;
\$context['_seq'] = twig_ensure_traversable((isset(\$context['values']) ? \$context['values'] : null));
\$context['loop'] = array(
'parent' => \$context['_parent'],
'index0' => 0,
'index' => 1,
'first' => true,
);
if (is_array(\$context['_seq']) || (is_object(\$context['_seq']) && \$context['_seq'] instanceof Countable)) {
\$length = count(\$context['_seq']);
\$context['loop']['revindex0'] = \$length - 1;
\$context['loop']['revindex'] = \$length;
\$context['loop']['length'] = \$length;
\$context['loop']['last'] = 1 === \$length;
}
foreach (\$context['_seq'] as \$context['k'] => \$context['v']) {
if (true) {
echo (isset(\$context['foo']) ? \$context['foo'] : null);
++\$context['loop']['index0'];
++\$context['loop']['index'];
\$context['loop']['first'] = false;
if (isset(\$context['loop']['length'])) {
--\$context['loop']['revindex0'];
--\$context['loop']['revindex'];
\$context['loop']['last'] = 0 === \$context['loop']['revindex0'];
}
}
}
\$_parent = \$context['_parent'];
unset(\$context['_seq'], \$context['_iterated'], \$context['k'], \$context['v'], \$context['_parent'], \$context['loop']);
\$context = array_merge(\$_parent, array_intersect_key(\$context, \$_parent));
EOF
);
$keyTarget = new Twig_Node_Expression_AssignName('k', 0);
$valueTarget = new Twig_Node_Expression_AssignName('v', 0);
$seq = new Twig_Node_Expression_Name('values', 0);
$ifexpr = null;
$body = new Twig_Node_Print(new Twig_Node_Expression_Name('foo', 0), 0);
$else = new Twig_Node_Print(new Twig_Node_Expression_Name('foo', 0), 0);
$node = new Twig_Node_For($keyTarget, $valueTarget, $seq, $body, $else, 0);
$node = new Twig_Node_For($keyTarget, $valueTarget, $seq, $ifexpr, $body, $else, 0);
$node->setAttribute('with_loop', true);
$tests[] = array($node, <<<EOF