mirror of
https://github.com/twigphp/Twig.git
synced 2026-08-17 11:41:37 +00:00
Keep captured block definitions supported
This commit is contained in:
@@ -301,13 +301,6 @@ Templates
|
|||||||
in ``Environment::resolveTemplate()`` and ``Environment::load()``); pass
|
in ``Environment::resolveTemplate()`` and ``Environment::load()``); pass
|
||||||
instances of ``Twig\TemplateWrapper`` instead.
|
instances of ``Twig\TemplateWrapper`` instead.
|
||||||
|
|
||||||
* Having a "block" definition nested in another node that captures the output
|
|
||||||
(like "set") in a child template is deprecated in Twig 3.14 and will throw
|
|
||||||
in Twig 4.0. In Twig 4.0, root-level "block" definitions in child
|
|
||||||
templates must be direct children of the template body. Blocks nested in a
|
|
||||||
capture inside another block body or in a template that does not extend
|
|
||||||
another one are not affected.
|
|
||||||
|
|
||||||
* Using a ``macro``, ``extends``, or ``use`` tag outside the root of a template
|
* Using a ``macro``, ``extends``, or ``use`` tag outside the root of a template
|
||||||
(for instance nested under an ``if`` or inside a ``block`` or ``macro``) is
|
(for instance nested under an ``if`` or inside a ``block`` or ``macro``) is
|
||||||
deprecated as of Twig 3.27 and will throw in Twig 4.0. These tags have a
|
deprecated as of Twig 3.27 and will throw in Twig 4.0. These tags have a
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ final class CorrectnessNodeVisitor implements NodeVisitorInterface
|
|||||||
private bool $hasParent = false;
|
private bool $hasParent = false;
|
||||||
private int $blockDepth = 0;
|
private int $blockDepth = 0;
|
||||||
private int $macroDepth = 0;
|
private int $macroDepth = 0;
|
||||||
|
private int $capturingNodeDepth = 0;
|
||||||
private bool $hasExtends = false;
|
private bool $hasExtends = false;
|
||||||
|
|
||||||
public function enterNode(Node $node, Environment $env): Node
|
public function enterNode(Node $node, Environment $env): Node
|
||||||
@@ -104,6 +105,7 @@ final class CorrectnessNodeVisitor implements NodeVisitorInterface
|
|||||||
$this->hasParent = false;
|
$this->hasParent = false;
|
||||||
$this->blockDepth = 0;
|
$this->blockDepth = 0;
|
||||||
$this->macroDepth = 0;
|
$this->macroDepth = 0;
|
||||||
|
$this->capturingNodeDepth = 0;
|
||||||
$this->hasExtends = false;
|
$this->hasExtends = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -122,6 +124,10 @@ final class CorrectnessNodeVisitor implements NodeVisitorInterface
|
|||||||
|
|
||||||
private function enterScope(Node $node): void
|
private function enterScope(Node $node): void
|
||||||
{
|
{
|
||||||
|
if ($node instanceof NodeCaptureInterface) {
|
||||||
|
++$this->capturingNodeDepth;
|
||||||
|
}
|
||||||
|
|
||||||
if ($node instanceof BlockNode) {
|
if ($node instanceof BlockNode) {
|
||||||
++$this->blockDepth;
|
++$this->blockDepth;
|
||||||
} elseif ($node instanceof MacroNode) {
|
} elseif ($node instanceof MacroNode) {
|
||||||
@@ -133,6 +139,10 @@ final class CorrectnessNodeVisitor implements NodeVisitorInterface
|
|||||||
|
|
||||||
private function leaveScope(Node $node): void
|
private function leaveScope(Node $node): void
|
||||||
{
|
{
|
||||||
|
if ($node instanceof NodeCaptureInterface) {
|
||||||
|
--$this->capturingNodeDepth;
|
||||||
|
}
|
||||||
|
|
||||||
if ($node instanceof BlockNode) {
|
if ($node instanceof BlockNode) {
|
||||||
--$this->blockDepth;
|
--$this->blockDepth;
|
||||||
} elseif ($node instanceof MacroNode) {
|
} elseif ($node instanceof MacroNode) {
|
||||||
@@ -173,20 +183,14 @@ final class CorrectnessNodeVisitor implements NodeVisitorInterface
|
|||||||
{
|
{
|
||||||
// A "block" definition nested under an output-wrapping tag is registered globally
|
// A "block" definition nested under an output-wrapping tag is registered globally
|
||||||
// regardless of that tag, so the nesting is misleading. This only matters at the root
|
// regardless of that tag, so the nesting is misleading. This only matters at the root
|
||||||
// of a child template's body: once inside a block or a macro (or in a standalone
|
// of a child template's body: once inside a block, a macro, an output capture, or in
|
||||||
// template), the block is rendered in place and behaves like any other, so there is
|
// a standalone template, the block is rendered in place and behaves like any other.
|
||||||
// no restriction.
|
if (!$this->hasParent || $this->blockDepth || $this->macroDepth || $this->capturingNodeDepth || !$this->tagStack) {
|
||||||
if (!$this->hasParent || $this->blockDepth || $this->macroDepth || !$this->tagStack) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$tag = $this->tagStack[array_key_last($this->tagStack)];
|
$tag = $this->tagStack[array_key_last($this->tagStack)];
|
||||||
if (!$tag instanceof NodeCaptureInterface) {
|
throw new SyntaxError(\sprintf('A "block" tag cannot be under a "%s" tag (line %d).', $tag->getNodeTag(), $tag->getTemplateLine()), $node->getTemplateLine(), $node->getSourceContext());
|
||||||
throw new SyntaxError(\sprintf('A "block" tag cannot be under a "%s" tag (line %d).', $tag->getNodeTag(), $tag->getTemplateLine()), $node->getTemplateLine(), $node->getSourceContext());
|
|
||||||
}
|
|
||||||
|
|
||||||
// capturing tags (e.g. "set") used to allow this, so only deprecate it
|
|
||||||
trigger_deprecation('twig/twig', '3.14', \sprintf('Having a "block" tag under a "%s" tag (line %d) is deprecated in %s at line %d.', $tag->getNodeTag(), $tag->getTemplateLine(), $node->getSourceContext()->getName(), $node->getTemplateLine()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,19 +0,0 @@
|
|||||||
--TEST--
|
|
||||||
capturing "block" tag with "extends" tag
|
|
||||||
--DEPRECATION--
|
|
||||||
Since twig/twig 3.14: Having a "block" tag under a "set" tag (line 4) is deprecated in index.twig at line 5.
|
|
||||||
--TEMPLATE--
|
|
||||||
{% extends "layout.twig" %}
|
|
||||||
|
|
||||||
{% set foo %}
|
|
||||||
{%- block content %}FOO{% endblock %}
|
|
||||||
{% endset %}
|
|
||||||
|
|
||||||
{% block content1 %}BAR{{ foo }}{% endblock %}
|
|
||||||
--TEMPLATE(layout.twig)--
|
|
||||||
{% block content %}{% endblock %}
|
|
||||||
{% block content1 %}{% endblock %}
|
|
||||||
--DATA--
|
|
||||||
return []
|
|
||||||
--EXPECT--
|
|
||||||
FOOBARFOO
|
|
||||||
@@ -3,10 +3,8 @@ capturing "block" tag with "extends" tag
|
|||||||
--TEMPLATE--
|
--TEMPLATE--
|
||||||
{% extends "layout.twig" %}
|
{% extends "layout.twig" %}
|
||||||
|
|
||||||
{% block content %}FOO{% endblock %}
|
{% set foo %}
|
||||||
|
{%- block content %}FOO{% endblock %}
|
||||||
{% set foo -%}
|
|
||||||
{{ block('content') }}
|
|
||||||
{% endset %}
|
{% endset %}
|
||||||
|
|
||||||
{% block content1 %}BAR{{ foo }}{% endblock %}
|
{% block content1 %}BAR{{ foo }}{% endblock %}
|
||||||
|
|||||||
+1
-3
@@ -1,7 +1,5 @@
|
|||||||
--TEST--
|
--TEST--
|
||||||
capturing "block" tag is still detected after a sibling tag at the same level
|
capturing "block" tag still works after a sibling tag at the same level
|
||||||
--DEPRECATION--
|
|
||||||
Since twig/twig 3.14: Having a "block" tag under a "set" tag (line 3) is deprecated in index.twig at line 3.
|
|
||||||
--TEMPLATE--
|
--TEMPLATE--
|
||||||
{% extends "layout.twig" %}
|
{% extends "layout.twig" %}
|
||||||
{% set foo %}{% if true %}{% endif %}{% block content %}FOO{% endblock %}{% endset %}
|
{% set foo %}{% if true %}{% endif %}{% block content %}FOO{% endblock %}{% endset %}
|
||||||
Reference in New Issue
Block a user