Added joined by statement to for loops

This commit is contained in:
Jordi Boggiano
2010-11-28 16:00:01 +01:00
committed by Fabien Potencier
parent 3f9453c8ea
commit 0e1b2ca857
4 changed files with 55 additions and 8 deletions
@@ -581,6 +581,20 @@ You can also access both keys and values:
>On Twig before 0.9.3, you need to use the `items` filter to access both the
>keys and values (`{% for key, value in users|items %}`).
To conveniently display comma-separated lists or things alike, you can use
`joined by ", "` at the end of the loop statement. Of course this is not
limited to commas.
[twig]
<h1>Members</h1>
<p>
{% for key in users|keys joined by ", " %}{{ key }}{% endfor %}
</p>
>**NOTE**
>This way you don't have to check if the item is the first or last, the comma
>will only be added in between two items.
### If
The `if` statement in Twig is comparable with the if statements of PHP. In the
+21 -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, $withLoop = false, $lineno, $tag = null)
public function __construct(Twig_Node_Expression_AssignName $keyTarget, Twig_Node_Expression_AssignName $valueTarget, Twig_Node_Expression $seq, Twig_NodeInterface $body, Twig_NodeInterface $else = null, $withLoop = false, Twig_Node_Expression $joinedBy = null, $lineno, $tag = null)
{
parent::__construct(array('key_target' => $keyTarget, 'value_target' => $valueTarget, 'seq' => $seq, 'body' => $body, 'else' => $else), array('with_loop' => $withLoop), $lineno, $tag);
parent::__construct(array('key_target' => $keyTarget, 'value_target' => $valueTarget, 'seq' => $seq, 'body' => $body, 'else' => $else, 'joined_with' => $joinedBy), array('with_loop' => $withLoop), $lineno, $tag);
}
/**
@@ -68,6 +68,10 @@ class Twig_Node_For extends Twig_Node
;
}
if (null !== $this->getNode('joined_with')) {
$compiler->write("\$context['_first_iteration'] = true;\n");
}
$compiler
->write("foreach (\$context['_seq'] as ")
->subcompile($this->getNode('key_target'))
@@ -81,6 +85,21 @@ class Twig_Node_For extends Twig_Node
$compiler->write("\$context['_iterated'] = true;\n");
}
if (null !== $this->getNode('joined_with')) {
$compiler
->write("if (\$context['_first_iteration']) {\n")
->indent()
->write("\$context['_first_iteration'] = false;\n")
->outdent()
->write("} else {\n")
->indent()
->write("echo ")
->subcompile($this->getNode('joined_with'))
->raw(";\n")
->outdent()
->write("}\n");
}
$compiler->subcompile($this->getNode('body'));
if ($this->getAttribute('with_loop')) {
+8 -1
View File
@@ -32,6 +32,13 @@ class Twig_TokenParser_For extends Twig_TokenParser
$withLoop = false;
}
$joinedBy = null;
if ($this->parser->getStream()->test('joined')) {
$this->parser->getStream()->next();
$this->parser->getStream()->expect('by');
$joinedBy = $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') {
@@ -50,7 +57,7 @@ class Twig_TokenParser_For extends Twig_TokenParser
$valueTarget = $targets->getNode(0);
}
return new Twig_Node_For($keyTarget, $valueTarget, $seq, $body, $else, $withLoop, $lineno, $this->getTag());
return new Twig_Node_For($keyTarget, $valueTarget, $seq, $body, $else, $withLoop, $joinedBy, $lineno, $this->getTag());
}
public function decideForFork($token)
+12 -5
View File
@@ -24,7 +24,7 @@ class Twig_Tests_Node_ForTest extends Twig_Tests_Node_TestCase
$body = new Twig_Node_Print(new Twig_Node_Expression_Name('foo', 0), 0);
$else = null;
$withLoop = false;
$node = new Twig_Node_For($keyTarget, $valueTarget, $seq, $body, $else, $withLoop, 0);
$node = new Twig_Node_For($keyTarget, $valueTarget, $seq, $body, $else, $withLoop, null, 0);
$this->assertEquals($keyTarget, $node->getNode('key_target'));
$this->assertEquals($valueTarget, $node->getNode('value_target'));
@@ -35,7 +35,7 @@ class Twig_Tests_Node_ForTest extends Twig_Tests_Node_TestCase
$this->assertEquals($withLoop, $node->getAttribute('with_loop'));
$else = new Twig_Node_Print(new Twig_Node_Expression_Name('foo', 0), 0);
$node = new Twig_Node_For($keyTarget, $valueTarget, $seq, $body, $else, $withLoop, 0);
$node = new Twig_Node_For($keyTarget, $valueTarget, $seq, $body, $else, $withLoop, null, 0);
$this->assertEquals($else, $node->getNode('else'));
}
@@ -58,7 +58,7 @@ class Twig_Tests_Node_ForTest extends Twig_Tests_Node_TestCase
$body = new Twig_Node_Print(new Twig_Node_Expression_Name('foo', 0), 0);
$else = null;
$withLoop = false;
$node = new Twig_Node_For($keyTarget, $valueTarget, $seq, $body, $else, $withLoop, 0);
$node = new Twig_Node_For($keyTarget, $valueTarget, $seq, $body, $else, $withLoop, null, 0);
$tests[] = array($node, <<<EOF
\$context['_parent'] = (array) \$context;
@@ -78,7 +78,8 @@ EOF
$body = new Twig_Node_Print(new Twig_Node_Expression_Name('foo', 0), 0);
$else = null;
$withLoop = true;
$node = new Twig_Node_For($keyTarget, $valueTarget, $seq, $body, $else, $withLoop, 0);
$joinedBy = new Twig_Node_Expression_Constant(', ', 0);
$node = new Twig_Node_For($keyTarget, $valueTarget, $seq, $body, $else, $withLoop, $joinedBy, 0);
$tests[] = array($node, <<<EOF
\$context['_parent'] = (array) \$context;
@@ -97,7 +98,13 @@ if (\$countable) {
\$context['loop']['length'] = \$length;
\$context['loop']['last'] = 1 === \$length;
}
\$context['_first_iteration'] = true;
foreach (\$context['_seq'] as \$context['k'] => \$context['v']) {
if (\$context['_first_iteration']) {
\$context['_first_iteration'] = false;
} else {
echo ", ";
}
echo (isset(\$context['foo']) ? \$context['foo'] : null);
++\$context['loop']['index0'];
++\$context['loop']['index'];
@@ -120,7 +127,7 @@ EOF
$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);
$withLoop = true;
$node = new Twig_Node_For($keyTarget, $valueTarget, $seq, $body, $else, $withLoop, 0);
$node = new Twig_Node_For($keyTarget, $valueTarget, $seq, $body, $else, $withLoop, null, 0);
$tests[] = array($node, <<<EOF
\$context['_parent'] = (array) \$context;