From fab21d8a7641349dc390f153ef62431f836d989c Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Tue, 24 Apr 2012 07:34:14 +0200 Subject: [PATCH] renamed the inline tag to embed --- CHANGELOG | 2 +- doc/tags/embed.rst | 147 +++++++++++++++++++ doc/tags/index.rst | 2 +- doc/tags/inline.rst | 148 -------------------- lib/Twig/Environment.php | 4 +- lib/Twig/Extension/Core.php | 2 +- lib/Twig/Node/Embed.php | 39 +++++ lib/Twig/Node/Inline.php | 39 ----- lib/Twig/Node/Module.php | 14 +- lib/Twig/Node/SandboxedModule.php | 4 +- lib/Twig/Parser.php | 10 +- lib/Twig/TokenParser/Embed.php | 50 +++++++ lib/Twig/TokenParser/Inline.php | 50 ------- test/Twig/Tests/Fixtures/tags/embed/basic.test | 37 +++++ .../Tests/Fixtures/tags/embed/with_extends.test | 54 +++++++ test/Twig/Tests/Fixtures/tags/inline/basic.test | 37 ----- .../Tests/Fixtures/tags/inline/with_extends.test | 54 ------- 17 files changed, 346 insertions(+), 347 deletions(-) create mode 100644 doc/tags/embed.rst delete mode 100644 doc/tags/inline.rst create mode 100644 lib/Twig/Node/Embed.php delete mode 100644 lib/Twig/Node/Inline.php create mode 100644 lib/Twig/TokenParser/Embed.php delete mode 100644 lib/Twig/TokenParser/Inline.php create mode 100644 test/Twig/Tests/Fixtures/tags/embed/basic.test create mode 100644 test/Twig/Tests/Fixtures/tags/embed/with_extends.test delete mode 100644 test/Twig/Tests/Fixtures/tags/inline/basic.test delete mode 100644 test/Twig/Tests/Fixtures/tags/inline/with_extends.test diff --git a/CHANGELOG b/CHANGELOG index a6a8d08..6a0030f 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,6 @@ * 1.8.0 (2012-XX-XX) - * added an inline tag + * added an embed tag * 1.7.0 (2012-XX-XX) diff --git a/doc/tags/embed.rst b/doc/tags/embed.rst new file mode 100644 index 0000000..34b4b43 --- /dev/null +++ b/doc/tags/embed.rst @@ -0,0 +1,147 @@ +``embed`` +========= + +.. versionadded:: 1.8 + The ``embed`` tag was added in Twig 1.8. + +The ``embed`` statement allows you to embed a template instead of including it +from an external file (like with the ``include`` statement): + +.. code-block:: jinja + + {% embed %} + {% extends "sidebar.twig" %} + + {% block content %} + Some content for the sidebar + {% endblock %} + {% endembed %} + +As it's not easy to understand in which circumstances it might come in handy, +let's take an example; imagine a base template shared by many pages with a +single block:: + + ┌─── Page n ──────────────────────────┐ + │ │ + │ ┌─────────────────────┐ │ + │ │ │ │ + │ │ │ │ + │ │ │ │ + │ │ │ │ + │ │ │ │ + │ │ │ │ + │ └─────────────────────┘ │ + │ │ + └─────────────────────────────────────┘ + +Some pages (page 1, 2, ...) share the same structure for the block:: + + ┌─── Page 1 & 2 ──────────────────────┐ + │ │ + │ ┌── Base A ───────────┐ │ + │ │ ┌── content1 ─────┐ │ │ + │ │ │ content for p1 │ │ │ + │ │ └─────────────────┘ │ │ + │ │ ┌── content2 ─────┐ │ │ + │ │ │ content for p1 │ │ │ + │ │ └─────────────────┘ │ │ + │ └─────────────────────┘ │ + │ │ + └─────────────────────────────────────┘ + +While other pages (page a, b, ...) share a different structure for the block:: + + ┌─── Page a, b ──────────────────────┐ + │ │ + │ ┌── Base B ───────────┐ │ + │ │ ┌───────┐ ┌───────┐ │ │ + │ │ │ │ │ │ │ │ + │ │ │content│ │content│ │ │ + │ │ │a, ... │ │b, ... │ │ │ + │ │ │ │ │ │ │ │ + │ │ └───────┘ └───────┘ │ │ + │ └─────────────────────┘ │ + │ │ + └─────────────────────────────────────┘ + +Without the ``embed`` tag, you have two ways to design your templates: + + * Create two base templates (one for 1, 2, ... blocks and another one for a, + b, ... blocks) to factor out the common template code, then one template + for each page that inherits from one of the base template; + + * Embed each custom page content directly into each page without any use of + external templates (you need to repeat the common code for all templates). + +These two solutions do not scale well because they each have a major drawback: + + * The first solution makes you create many external files (that you won't + re-use anywhere else) and so it fails to keep your templates readable (many + code and content are out of context); + + * The second solution makes you duplicate some common code from one template + to another (so it fails to obey the "Don't repeat yourself" principle). + +In such a situation, the ``embed`` tag fixes all these issues. The common code +can be factored out in base templates (as in solution 1), and the custom +content is kept in each page (as in solution 2): + +.. code-block:: jinja + + {# template for pages 1, 2, ... #} + + {% extends page %} + + {% block base %} + {% embed %} + {% extends "base_A.twig" %} + + {% block content1 %} + Content 1 for page 2 + {% endblock %} + + {% block content2 %} + Content 2 for page 2 + {% endblock %} + {% endembed %} + {% endblock %} + +And here is the code for ``base_A.twig``: + +.. code-block:: jinja + + Some code + + {% block content1 %} + Some default content + {% endblock %} + + Some other code + + {% block content2 %} + Some default content + {% endblock %} + + Yet some other code + +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: + +.. code-block:: jinja + + {% embed with {'foo': 'bar'} %} + ... + {% endembed %} + + {% embed with {'foo': 'bar'} only %} + ... + {% endembed %} + + {% embed ignore missing %} + ... + {% endembed %} + +.. seealso:: :doc:`include<../tags/include>` diff --git a/doc/tags/index.rst b/doc/tags/index.rst index 52d0205..fe0a00f 100644 --- a/doc/tags/index.rst +++ b/doc/tags/index.rst @@ -21,4 +21,4 @@ Tags flush do sandbox - inline + embed diff --git a/doc/tags/inline.rst b/doc/tags/inline.rst deleted file mode 100644 index 312d872..0000000 --- a/doc/tags/inline.rst +++ /dev/null @@ -1,148 +0,0 @@ -``inline`` -========== - -.. versionadded:: 1.8 - The ``inline`` tag was added in Twig 1.8. - -The ``inline`` statement allows you to inline a template instead of including -it from an external file (like with the ``include`` statement): - -.. code-block:: jinja - - {% inline %} - {% extends "sidebar.twig" %} - - {% block content %} - Some content for the sidebar - {% endblock %} - {% endinline %} - -As it's not easy to understand in which circumstances it might come in handy, -let's take an example; imagine a base template shared by many pages with a -single block:: - - ┌─── Page n ──────────────────────────┐ - │ │ - │ ┌─────────────────────┐ │ - │ │ │ │ - │ │ │ │ - │ │ │ │ - │ │ │ │ - │ │ │ │ - │ │ │ │ - │ └─────────────────────┘ │ - │ │ - └─────────────────────────────────────┘ - -Some pages (page 1, 2, ...) share the same structure for the block:: - - ┌─── Page 1 & 2 ──────────────────────┐ - │ │ - │ ┌── Base A ───────────┐ │ - │ │ ┌── content1 ─────┐ │ │ - │ │ │ content for p1 │ │ │ - │ │ └─────────────────┘ │ │ - │ │ ┌── content2 ─────┐ │ │ - │ │ │ content for p1 │ │ │ - │ │ └─────────────────┘ │ │ - │ └─────────────────────┘ │ - │ │ - └─────────────────────────────────────┘ - -While other pages (page a, b, ...) share a different structure for the block:: - - ┌─── Page a, b ──────────────────────┐ - │ │ - │ ┌── Base B ───────────┐ │ - │ │ ┌───────┐ ┌───────┐ │ │ - │ │ │ │ │ │ │ │ - │ │ │content│ │content│ │ │ - │ │ │a, ... │ │b, ... │ │ │ - │ │ │ │ │ │ │ │ - │ │ └───────┘ └───────┘ │ │ - │ └─────────────────────┘ │ - │ │ - └─────────────────────────────────────┘ - -Without the ``inline`` tag, you have two ways to design your templates: - - * Create two base templates (one for 1, 2, ... blocks and another one for a, - b, ... blocks) to factor out the common template code, then one template - for each page that inherits from one of the base template; - - * Inline the each custom page content directly into each page without any use - of external templates (you need to repeat the common code for all - templates). - -These two solutions do not scale well because they each have a major drawback: - - * The first solution makes you create many external files (that you won't - re-use anywhere else) and so it fails to keep your templates readable (many - code and content are out of context); - - * The second solution makes you duplicate some common code from one template - to another (so it fails to obey the "Don't repeat yourself" principle). - -In such a situation, the ``inline`` tag fixes all these issues. The common -code can be factored out in base templates (as in solution 1), and the custom -content is kept in each page (as in solution 2): - -.. code-block:: jinja - - {# template for pages 1, 2, ... #} - - {% extends page %} - - {% block base %} - {% inline %} - {% extends "base_A.twig" %} - - {% block content1 %} - Content 1 for page 2 - {% endblock %} - - {% block content2 %} - Content 2 for page 2 - {% endblock %} - {% endinline %} - {% endblock %} - -And here is the code for ``base_A.twig``: - -.. code-block:: jinja - - Some code - - {% block content1 %} - Some default content - {% endblock %} - - Some other code - - {% block content2 %} - Some default content - {% endblock %} - - Yet some other code - -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 ``inline`` tag can be customized with the same options (``with``, -``only``, ``ignore missing``) as the ``include`` tag: - -.. code-block:: jinja - - {% inline with {'foo': 'bar'} %} - ... - {% endinline %} - - {% inline with {'foo': 'bar'} only %} - ... - {% endinline %} - - {% inline ignore missing %} - ... - {% endinline %} - -.. seealso:: :doc:`include<../tags/include>` diff --git a/lib/Twig/Environment.php b/lib/Twig/Environment.php index 0d869fe..b321e13 100644 --- a/lib/Twig/Environment.php +++ b/lib/Twig/Environment.php @@ -252,7 +252,7 @@ class Twig_Environment * Gets the template class associated with the given string. * * @param string $name The name for which to calculate the template class name - * @param integer $index The index for inline templates (null for main templates) + * @param integer $index The index if it is an embedded template * * @return string The template class name */ @@ -299,7 +299,7 @@ class Twig_Environment * Loads a template by name. * * @param string $name The template name - * @param integer $index The index for inline templates (null for main templates) + * @param integer $index The index if it is an embedded template * * @return Twig_TemplateInterface A template instance representing the given template name */ diff --git a/lib/Twig/Extension/Core.php b/lib/Twig/Extension/Core.php index 52ed531..813261f 100644 --- a/lib/Twig/Extension/Core.php +++ b/lib/Twig/Extension/Core.php @@ -109,7 +109,7 @@ class Twig_Extension_Core extends Twig_Extension new Twig_TokenParser_Spaceless(), new Twig_TokenParser_Flush(), new Twig_TokenParser_Do(), - new Twig_TokenParser_Inline(), + new Twig_TokenParser_Embed(), ); } diff --git a/lib/Twig/Node/Embed.php b/lib/Twig/Node/Embed.php new file mode 100644 index 0000000..5edb953 --- /dev/null +++ b/lib/Twig/Node/Embed.php @@ -0,0 +1,39 @@ + + */ +class Twig_Node_Embed extends Twig_Node_Include +{ + // we don't inject the module to avoid node visitors to traverse it twice (as it will be already visited in the main module) + public function __construct($filename, $index, Twig_Node_Expression $variables = null, $only = false, $ignoreMissing = false, $lineno, $tag = null) + { + parent::__construct(new Twig_Node_Expression_Constant('not_used', $lineno), $variables, $only, $ignoreMissing, $lineno, $tag); + + $this->setAttribute('filename', $filename); + $this->setAttribute('index', $index); + } + + protected function addGetTemplate(Twig_Compiler $compiler) + { + $compiler + ->write("\$this->env->loadTemplate(") + ->string($this->getAttribute('filename')) + ->raw(', ') + ->string($this->getAttribute('index')) + ->raw(")") + ; + } +} diff --git a/lib/Twig/Node/Inline.php b/lib/Twig/Node/Inline.php deleted file mode 100644 index ab26b40..0000000 --- a/lib/Twig/Node/Inline.php +++ /dev/null @@ -1,39 +0,0 @@ - - */ -class Twig_Node_Inline extends Twig_Node_Include -{ - // we don't inject the module to avoid node visitors to traverse it twice (as it will be already visited in the main module) - public function __construct($filename, $inline, Twig_Node_Expression $variables = null, $only = false, $ignoreMissing = false, $lineno, $tag = null) - { - parent::__construct(new Twig_Node_Expression_Constant('not_used', $lineno), $variables, $only, $ignoreMissing, $lineno, $tag); - - $this->setAttribute('filename', $filename); - $this->setAttribute('inline', $inline); - } - - protected function addGetTemplate(Twig_Compiler $compiler) - { - $compiler - ->write("\$this->env->loadTemplate(") - ->string($this->getAttribute('filename')) - ->raw(', ') - ->string($this->getAttribute('inline')) - ->raw(")") - ; - } -} diff --git a/lib/Twig/Node/Module.php b/lib/Twig/Node/Module.php index ba960f0..8a5b002 100644 --- a/lib/Twig/Node/Module.php +++ b/lib/Twig/Node/Module.php @@ -18,14 +18,14 @@ */ class Twig_Node_Module extends Twig_Node { - public function __construct(Twig_NodeInterface $body, Twig_Node_Expression $parent = null, Twig_NodeInterface $blocks, Twig_NodeInterface $macros, Twig_NodeInterface $traits, Twig_NodeInterface $inlinedTemplates, $filename) + public function __construct(Twig_NodeInterface $body, Twig_Node_Expression $parent = null, Twig_NodeInterface $blocks, Twig_NodeInterface $macros, Twig_NodeInterface $traits, Twig_NodeInterface $embeddedTemplates, $filename) { - parent::__construct(array('parent' => $parent, 'body' => $body, 'blocks' => $blocks, 'macros' => $macros, 'traits' => $traits, 'inlined_templates' => $inlinedTemplates), array('filename' => $filename, 'inline' => null), 1); + parent::__construct(array('parent' => $parent, 'body' => $body, 'blocks' => $blocks, 'macros' => $macros, 'traits' => $traits, 'embedded_templates' => $embeddedTemplates), array('filename' => $filename, 'index' => null), 1); } - public function setInline($index) + public function setIndex($index) { - $this->setAttribute('inline', $index); + $this->setAttribute('index', $index); } /** @@ -37,14 +37,14 @@ class Twig_Node_Module extends Twig_Node { $this->compileTemplate($compiler); - foreach ($this->getNode('inlined_templates') as $template) { + foreach ($this->getNode('embedded_templates') as $template) { $compiler->subcompile($template); } } protected function compileTemplate(Twig_Compiler $compiler) { - if (!$this->getAttribute('inline')) { + if (!$this->getAttribute('index')) { $compiler->write('write("\n\n") // if the filename contains */, add a blank to avoid a PHP parse error ->write("/* ".str_replace('*/', '* /', $this->getAttribute('filename'))." */\n") - ->write('class '.$compiler->getEnvironment()->getTemplateClass($this->getAttribute('filename'), $this->getAttribute('inline'))) + ->write('class '.$compiler->getEnvironment()->getTemplateClass($this->getAttribute('filename'), $this->getAttribute('index'))) ->raw(sprintf(" extends %s\n", $compiler->getEnvironment()->getBaseTemplateClass())) ->write("{\n") ->indent() diff --git a/lib/Twig/Node/SandboxedModule.php b/lib/Twig/Node/SandboxedModule.php index 8a9ed31..464819a 100644 --- a/lib/Twig/Node/SandboxedModule.php +++ b/lib/Twig/Node/SandboxedModule.php @@ -24,9 +24,9 @@ class Twig_Node_SandboxedModule extends Twig_Node_Module public function __construct(Twig_Node_Module $node, array $usedFilters, array $usedTags, array $usedFunctions) { - parent::__construct($node->getNode('body'), $node->getNode('parent'), $node->getNode('blocks'), $node->getNode('macros'), $node->getNode('traits'), $node->getNode('inlined_templates'), $node->getAttribute('filename'), $node->getLine(), $node->getNodeTag()); + parent::__construct($node->getNode('body'), $node->getNode('parent'), $node->getNode('blocks'), $node->getNode('macros'), $node->getNode('traits'), $node->getNode('embedded_templates'), $node->getAttribute('filename'), $node->getLine(), $node->getNodeTag()); - $this->setAttribute('inline', $node->getAttribute('inline')); + $this->setAttribute('index', $node->getAttribute('index')); $this->usedFilters = $usedFilters; $this->usedTags = $usedTags; diff --git a/lib/Twig/Parser.php b/lib/Twig/Parser.php index 7120ea4..cb8dab3 100644 --- a/lib/Twig/Parser.php +++ b/lib/Twig/Parser.php @@ -32,7 +32,7 @@ class Twig_Parser implements Twig_ParserInterface protected $importedFunctions; protected $tmpVarCount; protected $traits; - protected $inlinedTemplates = array(); + protected $embeddedTemplates = array(); /** * Constructor. @@ -109,7 +109,7 @@ class Twig_Parser implements Twig_ParserInterface throw $e; } - $node = new Twig_Node_Module(new Twig_Node_Body(array($body)), $this->parent, new Twig_Node($this->blocks), new Twig_Node($this->macros), new Twig_Node($this->traits), new Twig_Node($this->inlinedTemplates), $this->stream->getFilename()); + $node = new Twig_Node_Module(new Twig_Node_Body(array($body)), $this->parent, new Twig_Node($this->blocks), new Twig_Node($this->macros), new Twig_Node($this->traits), new Twig_Node($this->embeddedTemplates), $this->stream->getFilename()); $traverser = new Twig_NodeTraverser($this->env, $this->visitors); @@ -272,11 +272,11 @@ class Twig_Parser implements Twig_ParserInterface return count($this->traits) > 0; } - public function addInlinedTemplate(Twig_Node_Module $template) + public function embedTemplate(Twig_Node_Module $template) { - $template->setInline(count($this->inlinedTemplates) + 1); + $template->setIndex(count($this->embeddedTemplates) + 1); - $this->inlinedTemplates[] = $template; + $this->embeddedTemplates[] = $template; } public function addImportedFunction($alias, $name, Twig_Node_Expression $node) diff --git a/lib/Twig/TokenParser/Embed.php b/lib/Twig/TokenParser/Embed.php new file mode 100644 index 0000000..4c8ba40 --- /dev/null +++ b/lib/Twig/TokenParser/Embed.php @@ -0,0 +1,50 @@ +parseArguments(); + + $module = $this->parser->parse($this->parser->getStream(), array($this, 'decideBlockEnd'), true); + $this->parser->embedTemplate($module); + + $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); + + return new Twig_Node_Embed($module->getAttribute('filename'), $module->getAttribute('index'), $variables, $only, $ignoreMissing, $token->getLine(), $this->getTag()); + } + + public function decideBlockEnd(Twig_Token $token) + { + return $token->test('endembed'); + } + + /** + * Gets the tag name associated with this token parser. + * + * @return string The tag name + */ + public function getTag() + { + return 'embed'; + } +} diff --git a/lib/Twig/TokenParser/Inline.php b/lib/Twig/TokenParser/Inline.php deleted file mode 100644 index 9c5a0a5..0000000 --- a/lib/Twig/TokenParser/Inline.php +++ /dev/null @@ -1,50 +0,0 @@ -parseArguments(); - - $module = $this->parser->parse($this->parser->getStream(), array($this, 'decideBlockEnd'), true); - $this->parser->addInlinedTemplate($module); - - $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); - - return new Twig_Node_Inline($module->getAttribute('filename'), $module->getAttribute('inline'), $variables, $only, $ignoreMissing, $token->getLine(), $this->getTag()); - } - - public function decideBlockEnd(Twig_Token $token) - { - return $token->test('endinline'); - } - - /** - * Gets the tag name associated with this token parser. - * - * @return string The tag name - */ - public function getTag() - { - return 'inline'; - } -} diff --git a/test/Twig/Tests/Fixtures/tags/embed/basic.test b/test/Twig/Tests/Fixtures/tags/embed/basic.test new file mode 100644 index 0000000..78260d8 --- /dev/null +++ b/test/Twig/Tests/Fixtures/tags/embed/basic.test @@ -0,0 +1,37 @@ +--TEST-- +"embed" tag +--TEMPLATE-- +FOO +{% embed %} + {% extends "foo.twig" %} + + {% block c1 %} + {{ parent() }} + block1extended + {% endblock %} +{% endembed %} + +BAR +--TEMPLATE(foo.twig)-- +A +{% block c1 %} + block1 +{% endblock %} +B +{% block c2 %} + block2 +{% endblock %} +C +--DATA-- +return array() +--EXPECT-- +FOO + +A + block1 + + block1extended + B + block2 +C +BAR diff --git a/test/Twig/Tests/Fixtures/tags/embed/with_extends.test b/test/Twig/Tests/Fixtures/tags/embed/with_extends.test new file mode 100644 index 0000000..04f0275 --- /dev/null +++ b/test/Twig/Tests/Fixtures/tags/embed/with_extends.test @@ -0,0 +1,54 @@ +--TEST-- +"embed" tag +--TEMPLATE-- +{% extends "base.twig" %} + +{% block c1 %} + {{ parent() }} + blockc1baseextended +{% endblock %} + +{% block c2 %} + {% embed %} + {% extends "foo.twig" %} + + {% block c1 %} + {{ parent() }} + block1extended + {% endblock %} + {% endembed %} +{% endblock %} +--TEMPLATE(base.twig)-- +A +{% block c1 %} + blockc1base +{% endblock %} +{% block c2 %} + block2base +{% endblock %} +B +--TEMPLATE(foo.twig)-- +A +{% block c1 %} + block1 +{% endblock %} +B +{% block c2 %} + block2 +{% endblock %} +C +--DATA-- +return array() +--EXPECT-- +A + blockc1base + + blockc1baseextended + +A + block1 + + block1extended + B + block2 +CB \ No newline at end of file diff --git a/test/Twig/Tests/Fixtures/tags/inline/basic.test b/test/Twig/Tests/Fixtures/tags/inline/basic.test deleted file mode 100644 index 46d28f2..0000000 --- a/test/Twig/Tests/Fixtures/tags/inline/basic.test +++ /dev/null @@ -1,37 +0,0 @@ ---TEST-- -"inline" tag ---TEMPLATE-- -FOO -{% inline %} - {% extends "foo.twig" %} - - {% block c1 %} - {{ parent() }} - block1extended - {% endblock %} -{% endinline %} - -BAR ---TEMPLATE(foo.twig)-- -A -{% block c1 %} - block1 -{% endblock %} -B -{% block c2 %} - block2 -{% endblock %} -C ---DATA-- -return array() ---EXPECT-- -FOO - -A - block1 - - block1extended - B - block2 -C -BAR diff --git a/test/Twig/Tests/Fixtures/tags/inline/with_extends.test b/test/Twig/Tests/Fixtures/tags/inline/with_extends.test deleted file mode 100644 index b7509f9..0000000 --- a/test/Twig/Tests/Fixtures/tags/inline/with_extends.test +++ /dev/null @@ -1,54 +0,0 @@ ---TEST-- -"inline" tag ---TEMPLATE-- -{% extends "base.twig" %} - -{% block c1 %} - {{ parent() }} - blockc1baseextended -{% endblock %} - -{% block c2 %} - {% inline %} - {% extends "foo.twig" %} - - {% block c1 %} - {{ parent() }} - block1extended - {% endblock %} - {% endinline %} -{% endblock %} ---TEMPLATE(base.twig)-- -A -{% block c1 %} - blockc1base -{% endblock %} -{% block c2 %} - block2base -{% endblock %} -B ---TEMPLATE(foo.twig)-- -A -{% block c1 %} - block1 -{% endblock %} -B -{% block c2 %} - block2 -{% endblock %} -C ---DATA-- -return array() ---EXPECT-- -A - blockc1base - - blockc1baseextended - -A - block1 - - block1extended - B - block2 -CB \ No newline at end of file -- 1.7.2.5