From 23a8d39d664ef56d23c5d74d722d877ad14932a8 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Thu, 29 Apr 2010 07:58:52 +0200 Subject: [PATCH] fixed nested block definitions with a parent call (closes #45) --- CHANGELOG | 1 + lib/Twig/Parser.php | 22 ++++++++++++---- lib/Twig/TokenParser/Block.php | 11 +------- lib/Twig/TokenParser/Parent.php | 4 +- test/fixtures/tags/inheritance/parent_nested.test | 27 +++++++++++++++++++++ 5 files changed, 48 insertions(+), 17 deletions(-) create mode 100644 test/fixtures/tags/inheritance/parent_nested.test diff --git a/CHANGELOG b/CHANGELOG index c7d7143..c005080 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,6 @@ * 0.9.6-DEV + * fixed nested block definitions with a parent call (rarely useful but nonetheless supported now) * added the cycle filter * fixed the Lexer when mbstring.func_overload is used with an mbstring.internal_encoding different from ASCII * added a long-syntax for the set tag ({% set foo %}...{% endset %}) diff --git a/lib/Twig/Parser.php b/lib/Twig/Parser.php index 29d60ef..03a7621 100644 --- a/lib/Twig/Parser.php +++ b/lib/Twig/Parser.php @@ -17,7 +17,7 @@ class Twig_Parser protected $visitors; protected $expressionParser; protected $blocks; - protected $currentBlock; + protected $blockStack; protected $macros; protected $env; @@ -63,7 +63,7 @@ class Twig_Parser $this->extends = null; $this->blocks = array(); $this->macros = array(); - $this->currentBlock = null; + $this->blockStack = array(); try { @@ -170,14 +170,24 @@ class Twig_Parser $this->visitors[] = $visitor; } - public function getCurrentBlock() + public function getBlockStack() { - return $this->currentBlock; + return $this->blockStack; } - public function setCurrentBlock($name) + public function peekBlockStack() { - $this->currentBlock = $name; + return $this->blockStack[count($this->blockStack) - 1]; + } + + public function popBlockStack() + { + array_pop($this->blockStack); + } + + public function pushBlockStack($name) + { + $this->blockStack[] = $name; } public function hasBlock($name) diff --git a/lib/Twig/TokenParser/Block.php b/lib/Twig/TokenParser/Block.php index 0d35aba..ea61515 100644 --- a/lib/Twig/TokenParser/Block.php +++ b/lib/Twig/TokenParser/Block.php @@ -14,20 +14,13 @@ class Twig_TokenParser_Block extends Twig_TokenParser public function parse(Twig_Token $token) { $lineno = $token->getLine(); - $stream = $this->parser->getStream(); $name = $stream->expect(Twig_Token::NAME_TYPE)->getValue(); if ($this->parser->hasBlock($name)) { throw new Twig_SyntaxError("The block '$name' has already been defined", $lineno); } - - if (null !== $current = $this->parser->getCurrentBlock()) - { - throw new Twig_SyntaxError("Blocks cannot be nested (you are trying to define a '$name' block inside the '$current' block)", $lineno); - } - - $this->parser->setCurrentBlock($name); + $this->parser->pushBlockStack($name); if ($stream->test(Twig_Token::BLOCK_END_TYPE)) { @@ -54,7 +47,7 @@ class Twig_TokenParser_Block extends Twig_TokenParser $block = new Twig_Node_Block($name, $body, $lineno); $this->parser->setBlock($name, $block); - $this->parser->setCurrentBlock(null); + $this->parser->popBlockStack(); return new Twig_Node_BlockReference($name, $lineno, $this->getTag()); } diff --git a/lib/Twig/TokenParser/Parent.php b/lib/Twig/TokenParser/Parent.php index 9771488..5cd7b98 100644 --- a/lib/Twig/TokenParser/Parent.php +++ b/lib/Twig/TokenParser/Parent.php @@ -13,13 +13,13 @@ class Twig_TokenParser_Parent extends Twig_TokenParser { public function parse(Twig_Token $token) { - if (null === $this->parser->getCurrentBlock()) + if (!count($this->parser->getBlockStack())) { throw new Twig_SyntaxError('Calling "parent" outside a block is forbidden', $token->getLine()); } $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); - return new Twig_Node_Parent($this->parser->getCurrentBlock(), $token->getLine(), $this->getTag()); + return new Twig_Node_Parent($this->parser->peekBlockStack(), $token->getLine(), $this->getTag()); } public function getTag() diff --git a/test/fixtures/tags/inheritance/parent_nested.test b/test/fixtures/tags/inheritance/parent_nested.test new file mode 100644 index 0000000..1a5cf44 --- /dev/null +++ b/test/fixtures/tags/inheritance/parent_nested.test @@ -0,0 +1,27 @@ +--TEST-- +"extends" tag +--TEMPLATE-- +{% extends "foo.twig" %} + +{% block content %} + {% block inside %} + INSIDE OVERRIDDEN + {% endblock %} + + BEFORE + {% parent %} + AFTER +{% endblock %} +--TEMPLATE(foo.twig)-- +{% block content %} + BAR +{% endblock %} +--DATA-- +return array() +--EXPECT-- + +INSIDE OVERRIDDEN + + BEFORE + BAR + AFTER -- 1.7.2.5