* 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 %})
protected $visitors;
protected $expressionParser;
protected $blocks;
- protected $currentBlock;
+ protected $blockStack;
protected $macros;
protected $env;
$this->extends = null;
$this->blocks = array();
$this->macros = array();
- $this->currentBlock = null;
+ $this->blockStack = array();
try
{
$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)
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))
{
$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());
}
{
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()
--- /dev/null
+--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