added the "without loop" option to the for tag (it disables the generation of the loop variable)

git-svn-id: http://svn.twig-project.org/trunk@216 93ef8e89-cb99-4229-a87c-7fa0fa45744b
This commit is contained in:
fabien
2010-01-08 13:16:37 +00:00
parent b8cf67ab51
commit 83ea0a5eca
3 changed files with 52 additions and 22 deletions
+1
View File
@@ -16,6 +16,7 @@ If you have created NodeTransformer classes, you will need to upgrade them to
the new interface (please note that the interface is not yet considered
stable).
* 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
+41 -21
View File
@@ -24,8 +24,9 @@ class Twig_Node_For extends Twig_Node implements Twig_NodeListInterface
protected $seq;
protected $body;
protected $else;
protected $withLoop;
public function __construct($isMultitarget, $item, $seq, Twig_NodeList $body, Twig_Node $else = null, $lineno, $tag = null)
public function __construct($isMultitarget, $item, $seq, Twig_NodeList $body, Twig_Node $else = null, $withLoop = false, $lineno, $tag = null)
{
parent::__construct($lineno, $tag);
$this->isMultitarget = $isMultitarget;
@@ -33,6 +34,7 @@ class Twig_Node_For extends Twig_Node implements Twig_NodeListInterface
$this->seq = $seq;
$this->body = $body;
$this->else = $else;
$this->withLoop = $withLoop;
$this->lineno = $lineno;
}
@@ -72,19 +74,27 @@ class Twig_Node_For extends Twig_Node implements Twig_NodeListInterface
->write("\$seq$var = twig_iterator_to_array(")
->subcompile($this->seq)
->raw(");\n")
->write("\$length = count(\$seq$var);\n")
;
->write("\$context['loop'] = array(\n")
->write(" 'parent' => \$context['_parent'],\n")
->write(" 'length' => \$length,\n")
->write(" 'index0' => 0,\n")
->write(" 'index' => 1,\n")
->write(" 'revindex0' => \$length - 1,\n")
->write(" 'revindex' => \$length,\n")
->write(" 'first' => true,\n")
->write(" 'last' => 1 === \$length,\n")
->write(");\n")
if ($this->withLoop)
{
$compiler
->write("\$length = count(\$seq$var);\n")
->write("\$context['loop'] = array(\n")
->write(" 'parent' => \$context['_parent'],\n")
->write(" 'length' => \$length,\n")
->write(" 'index0' => 0,\n")
->write(" 'index' => 1,\n")
->write(" 'revindex0' => \$length - 1,\n")
->write(" 'revindex' => \$length,\n")
->write(" 'first' => true,\n")
->write(" 'last' => 1 === \$length,\n")
->write(");\n")
;
}
$compiler
->write("foreach (\$seq$var as \$context[")
->repr($loopVars[0])
->raw("] => \$context[")
@@ -99,16 +109,21 @@ class Twig_Node_For extends Twig_Node implements Twig_NodeListInterface
$compiler->write("\$context['_iterated'] = true;\n");
}
$compiler->subcompile($this->body);
if ($this->withLoop)
{
$compiler
->write("++\$context['loop']['index0'];\n")
->write("++\$context['loop']['index'];\n")
->write("--\$context['loop']['revindex0'];\n")
->write("--\$context['loop']['revindex'];\n")
->write("\$context['loop']['first'] = false;\n")
->write("\$context['loop']['last'] = 0 === \$context['loop']['revindex0'];\n")
;
}
$compiler
->subcompile($this->body)
->write("++\$context['loop']['index0'];\n")
->write("++\$context['loop']['index'];\n")
->write("--\$context['loop']['revindex0'];\n")
->write("--\$context['loop']['revindex'];\n")
->write("\$context['loop']['first'] = false;\n")
->write("\$context['loop']['last'] = 0 === \$context['loop']['revindex0'];\n")
->outdent()
->write("}\n")
;
@@ -126,4 +141,9 @@ class Twig_Node_For extends Twig_Node implements Twig_NodeListInterface
}
$compiler->popContext();
}
public function setWithLoop($boolean)
{
$this->withLoop = (Boolean) $boolean;
}
}
+10 -1
View File
@@ -17,6 +17,15 @@ class Twig_TokenParser_For extends Twig_TokenParser
list($isMultitarget, $item) = $this->parser->getExpressionParser()->parseAssignmentExpression();
$this->parser->getStream()->expect('in');
$seq = $this->parser->getExpressionParser()->parseExpression();
$withLoop = true;
if ($this->parser->getStream()->test('without'))
{
$this->parser->getStream()->next();
$this->parser->getStream()->expect('loop');
$withLoop = false;
}
$this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
$body = $this->parser->subparse(array($this, 'decideForFork'));
if ($this->parser->getStream()->next()->getValue() == 'else')
@@ -30,7 +39,7 @@ class Twig_TokenParser_For extends Twig_TokenParser
}
$this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
return new Twig_Node_For($isMultitarget, $item, $seq, $body, $else, $lineno, $this->getTag());
return new Twig_Node_For($isMultitarget, $item, $seq, $body, $else, $withLoop, $lineno, $this->getTag());
}
public function decideForFork($token)