added the "without loop" option to the for tag (it disables the generation of the...
authorfabien <fabien@93ef8e89-cb99-4229-a87c-7fa0fa45744b>
Fri, 8 Jan 2010 13:16:37 +0000 (13:16 +0000)
committerfabien <fabien@93ef8e89-cb99-4229-a87c-7fa0fa45744b>
Fri, 8 Jan 2010 13:16:37 +0000 (13:16 +0000)
git-svn-id: http://svn.twig-project.org/trunk@216 93ef8e89-cb99-4229-a87c-7fa0fa45744b

CHANGELOG
lib/Twig/Node/For.php
lib/Twig/TokenParser/For.php

index f7f619d..ad19699 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -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
index cd3e0fc..f2ec43c 100644 (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)
+    $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")
+    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
       ->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;
+  }
 }
index b3d0cfd..19c2481 100644 (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)