added the parent as an argument to the embed tag (removes the need to use extends)
authorFabien Potencier <fabien.potencier@gmail.com>
Tue, 24 Apr 2012 06:31:52 +0000 (08:31 +0200)
committerFabien Potencier <fabien.potencier@gmail.com>
Tue, 24 Apr 2012 06:31:52 +0000 (08:31 +0200)
doc/tags/embed.rst
lib/Twig/TokenParser/Embed.php
lib/Twig/TokenStream.php
test/Twig/Tests/Fixtures/tags/embed/basic.test
test/Twig/Tests/Fixtures/tags/embed/with_extends.test

index 34b4b43..edea190 100644 (file)
@@ -9,9 +9,7 @@ from an external file (like with the ``include`` statement):
 
 .. code-block:: jinja
 
-    {% embed %}
-        {% extends "sidebar.twig" %}
-
+    {% embed "sidebar.twig" %}
         {% block content %}
             Some content for the sidebar
         {% endblock %}
@@ -93,9 +91,7 @@ content is kept in each page (as in solution 2):
     {% extends page %}
 
     {% block base %}
-        {% embed %}
-            {% extends "base_A.twig" %}
-
+        {% embed "base_A.twig" %}
             {% block content1 %}
                 Content 1 for page 2
             {% endblock %}
@@ -127,20 +123,19 @@ And here is the code for ``base_A.twig``:
 The goal of the ``base_a.twig`` base template being to factor out the ``Some
 code``, ``Some other code``, and ``Yet some other code`` parts.
 
-The ``embed`` tag can be customized with the same options (``with``, ``only``,
-``ignore missing``) as the ``include`` tag:
+The ``embed`` tag takes the exact same arguments as the ``include`` tag:
 
 .. code-block:: jinja
 
-    {% embed with {'foo': 'bar'} %}
+    {% embed "base" with {'foo': 'bar'} %}
         ...
     {% endembed %}
 
-    {% embed with {'foo': 'bar'} only %}
+    {% embed "base" with {'foo': 'bar'} only %}
         ...
     {% endembed %}
 
-    {% embed ignore missing %}
+    {% embed "base" ignore missing %}
         ...
     {% endembed %}
 
index 4c8ba40..69cb5f3 100644 (file)
@@ -23,12 +23,28 @@ class Twig_TokenParser_Embed extends Twig_TokenParser_Include
      */
     public function parse(Twig_Token $token)
     {
+        $stream = $this->parser->getStream();
+
+        $parent = $this->parser->getExpressionParser()->parseExpression();
+
         list($variables, $only, $ignoreMissing) = $this->parseArguments();
 
-        $module = $this->parser->parse($this->parser->getStream(), array($this, 'decideBlockEnd'), true);
+        // inject a fake parent to make the parent() function work
+        $stream->injectTokens(array(
+            new Twig_Token(Twig_Token::BLOCK_START_TYPE, '', $token->getLine()),
+            new Twig_Token(Twig_Token::NAME_TYPE, 'extends', $token->getLine()),
+            new Twig_Token(Twig_Token::STRING_TYPE, '__parent__', $token->getLine()),
+            new Twig_Token(Twig_Token::BLOCK_END_TYPE, '', $token->getLine()),
+        ));
+
+        $module = $this->parser->parse($stream, array($this, 'decideBlockEnd'), true);
+
+        // override the parent with the correct one
+        $module->setNode('parent', $parent);
+
         $this->parser->embedTemplate($module);
 
-        $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
+        $stream->expect(Twig_Token::BLOCK_END_TYPE);
 
         return new Twig_Node_Embed($module->getAttribute('filename'), $module->getAttribute('index'), $variables, $only, $ignoreMissing, $token->getLine(), $this->getTag());
     }
index a2002b4..5708091 100644 (file)
@@ -45,6 +45,11 @@ class Twig_TokenStream
         return implode("\n", $this->tokens);
     }
 
+    public function injectTokens(array $tokens)
+    {
+        $this->tokens = array_merge(array_slice($this->tokens, 0, $this->current), $tokens, array_slice($this->tokens, $this->current));
+    }
+
     /**
      * Sets the pointer to the next token and returns the old one.
      *
index 78260d8..f44296e 100644 (file)
@@ -2,9 +2,7 @@
 "embed" tag
 --TEMPLATE--
 FOO
-{% embed %}
-    {% extends "foo.twig" %}
-
+{% embed "foo.twig" %}
     {% block c1 %}
         {{ parent() }}
         block1extended
index 04f0275..e8040bf 100644 (file)
@@ -9,9 +9,7 @@
 {% endblock %}
 
 {% block c2 %}
-    {% embed %}
-        {% extends "foo.twig" %}
-
+    {% embed "foo.twig" %}
         {% block c1 %}
             {{ parent() }}
             block1extended