mirror of
https://github.com/twigphp/Twig.git
synced 2026-09-21 07:37:43 +00:00
added traits support for the parent function
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
* 1.3.0
|
||||
|
||||
* allowed empty templates to be used as traits
|
||||
* added traits support for the "parent" function
|
||||
|
||||
* 1.2.0 (2011-09-13)
|
||||
|
||||
|
||||
+8
-4
@@ -1628,22 +1628,26 @@ is ignored. To avoid name conflicts, you can rename imported blocks:
|
||||
{% block title %}{% endblock %}
|
||||
{% block content %}{% endblock %}
|
||||
|
||||
Renaming also allows you to simulate inheritance by calling the "parent" block
|
||||
(like what you would have done with ``parent()``):
|
||||
The ``parent()`` function automatically determines the correct inheritance
|
||||
tree, so it can be used when overriding a block defined in an imported
|
||||
template:
|
||||
|
||||
.. code-block:: jinja
|
||||
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% use "blocks.html" with sidebar as parent_sidebar %}
|
||||
{% use "blocks.html" %}
|
||||
|
||||
{% block sidebar %}
|
||||
{{ block('parent_sidebar') }}
|
||||
{{ parent() }}
|
||||
{% endblock %}
|
||||
|
||||
{% block title %}{% endblock %}
|
||||
{% block content %}{% endblock %}
|
||||
|
||||
In this example, ``parent()`` will correctly call the ``sidebar`` block from
|
||||
the ``blocks.html`` template.
|
||||
|
||||
.. note::
|
||||
|
||||
You can use as many ``use`` statements as you want in any given template.
|
||||
|
||||
@@ -241,8 +241,8 @@ class Twig_ExpressionParser
|
||||
throw new Twig_Error_Syntax('Calling "parent" outside a block is forbidden', $line);
|
||||
}
|
||||
|
||||
if (!$this->parser->getParent()) {
|
||||
throw new Twig_Error_Syntax('Calling "parent" on a template that does not extend another one is forbidden', $line);
|
||||
if (!$this->parser->getParent() && !$this->parser->hasTraits()) {
|
||||
throw new Twig_Error_Syntax('Calling "parent" on a template that does not extend nor "use" another template is forbidden', $line);
|
||||
}
|
||||
|
||||
return new Twig_Node_Expression_Parent($this->parser->peekBlockStack(), $line);
|
||||
|
||||
@@ -152,17 +152,25 @@ class Twig_Node_Module extends Twig_Node
|
||||
}
|
||||
|
||||
$compiler
|
||||
->write("\$this->blocks = array_merge(\n")
|
||||
->write("\$this->traits = array_merge(\n")
|
||||
->indent()
|
||||
;
|
||||
|
||||
for ($i = 0; $i < $countTraits; $i++) {
|
||||
$compiler
|
||||
->write(sprintf("\$_trait_%s_blocks,\n", $i))
|
||||
->write(sprintf("\$_trait_%s_blocks".($i == $countTraits - 1 ? '' : ',')."\n", $i))
|
||||
;
|
||||
}
|
||||
|
||||
$compiler
|
||||
->outdent()
|
||||
->write(");\n\n")
|
||||
;
|
||||
|
||||
$compiler
|
||||
->write("\$this->blocks = array_merge(\n")
|
||||
->indent()
|
||||
->write("\$this->traits,\n")
|
||||
->write("array(\n")
|
||||
;
|
||||
} else {
|
||||
|
||||
@@ -234,6 +234,11 @@ class Twig_Parser implements Twig_ParserInterface
|
||||
$this->traits[] = $trait;
|
||||
}
|
||||
|
||||
public function hasTraits()
|
||||
{
|
||||
return count($this->traits) > 0;
|
||||
}
|
||||
|
||||
public function addImportedFunction($alias, $name, Twig_Node_Expression $node)
|
||||
{
|
||||
$this->importedFunctions[0][$alias] = array('name' => $name, 'node' => $node);
|
||||
|
||||
@@ -23,6 +23,7 @@ abstract class Twig_Template implements Twig_TemplateInterface
|
||||
protected $parents;
|
||||
protected $env;
|
||||
protected $blocks;
|
||||
protected $traits;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
@@ -33,6 +34,7 @@ abstract class Twig_Template implements Twig_TemplateInterface
|
||||
{
|
||||
$this->env = $env;
|
||||
$this->blocks = array();
|
||||
$this->traits = array();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -84,10 +86,12 @@ abstract class Twig_Template implements Twig_TemplateInterface
|
||||
*/
|
||||
public function displayParentBlock($name, array $context, array $blocks = array())
|
||||
{
|
||||
if (false !== $parent = $this->getParent($context)) {
|
||||
if (isset($this->traits[$name])) {
|
||||
$this->traits[$name][0]->displayBlock($name, $context, $blocks);
|
||||
} elseif (false !== $parent = $this->getParent($context)) {
|
||||
$parent->displayBlock($name, $context, $blocks);
|
||||
} else {
|
||||
throw new Twig_Error_Runtime('This template has no parent', -1, $this->getTemplateName());
|
||||
throw new Twig_Error_Runtime(sprintf('The template has no parent and no traits defining the "%s" block', $name), -1, $this->getTemplateName());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
--TEST--
|
||||
"parent" tag
|
||||
--TEMPLATE--
|
||||
{% block content %}
|
||||
{{ parent() }}
|
||||
{% endblock %}
|
||||
--EXCEPTION--
|
||||
Twig_Error_Syntax: Calling "parent" on a template that does not extend nor "use" another template is forbidden in "index.twig" at line 3
|
||||
@@ -0,0 +1,14 @@
|
||||
--TEST--
|
||||
"parent" tag
|
||||
--TEMPLATE--
|
||||
{% use 'foo.twig' %}
|
||||
|
||||
{% block content %}
|
||||
{{ parent() }}
|
||||
{% endblock %}
|
||||
--TEMPLATE(foo.twig)--
|
||||
{% block content %}BAR{% endblock %}
|
||||
--DATA--
|
||||
return array()
|
||||
--EXPECT--
|
||||
BAR
|
||||
@@ -0,0 +1,44 @@
|
||||
--TEST--
|
||||
"parent" function
|
||||
--TEMPLATE--
|
||||
{% extends "parent.twig" %}
|
||||
|
||||
{% use "use1.twig" %}
|
||||
{% use "use2.twig" %}
|
||||
|
||||
{% block content_parent %}
|
||||
{{ parent() }}
|
||||
{% endblock %}
|
||||
|
||||
{% block content_use1 %}
|
||||
{{ parent() }}
|
||||
{% endblock %}
|
||||
|
||||
{% block content_use2 %}
|
||||
{{ parent() }}
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{{ block('content_use1_only') }}
|
||||
{{ block('content_use2_only') }}
|
||||
{% endblock %}
|
||||
--TEMPLATE(parent.twig)--
|
||||
{% block content_parent 'content_parent' %}
|
||||
{% block content_use1 'content_parent' %}
|
||||
{% block content_use2 'content_parent' %}
|
||||
{% block content '' %}
|
||||
--TEMPLATE(use1.twig)--
|
||||
{% block content_use1 'content_use1' %}
|
||||
{% block content_use2 'content_use1' %}
|
||||
{% block content_use1_only 'content_use1_only' %}
|
||||
--TEMPLATE(use2.twig)--
|
||||
{% block content_use2 'content_use2' %}
|
||||
{% block content_use2_only 'content_use2_only' %}
|
||||
--DATA--
|
||||
return array()
|
||||
--EXPECT--
|
||||
content_parent
|
||||
content_use1
|
||||
content_use2
|
||||
content_use1_only
|
||||
content_use2_only
|
||||
Reference in New Issue
Block a user