mirror of
https://github.com/twigphp/Twig.git
synced 2026-09-17 04:46:49 +00:00
Local macros auto-import
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
* 2.11.0 (2019-XX-XX)
|
* 2.11.0 (2019-XX-XX)
|
||||||
|
|
||||||
|
* macros are now auto-imported in the template they are defined (under the ``_self`` variable)
|
||||||
* added support for macros on "is defined" tests
|
* added support for macros on "is defined" tests
|
||||||
* fixed macros "import" when using the same name in the parent and child templates
|
* fixed macros "import" when using the same name in the parent and child templates
|
||||||
* fixed recursive macros
|
* fixed recursive macros
|
||||||
|
|||||||
+14
-1
@@ -74,7 +74,20 @@ via the ``from`` tag:
|
|||||||
|
|
||||||
.. tip::
|
.. tip::
|
||||||
|
|
||||||
To import macros from the current file, use the special ``_self`` variable:
|
When macro usages and definitions are in the same template, you don't need to
|
||||||
|
import the macros as they are automatically available under the special
|
||||||
|
``_self`` variable:
|
||||||
|
|
||||||
|
.. code-block:: twig
|
||||||
|
|
||||||
|
<p>{{ _self.input('password', '', 'password') }}</p>
|
||||||
|
|
||||||
|
{% macro input(name, value, type = "text", size = 20) %}
|
||||||
|
<input type="{{ type }}" name="{{ name }}" value="{{ value|e }}" size="{{ size }}" />
|
||||||
|
{% endmacro %}
|
||||||
|
|
||||||
|
Auto-import is only available as of Twig 2.11. For older versions, import
|
||||||
|
macros using the special ``_self`` variable for the template name:
|
||||||
|
|
||||||
.. code-block:: twig
|
.. code-block:: twig
|
||||||
|
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ use Twig\Node\Expression\Test\SameasTest;
|
|||||||
use Twig\Node\Expression\Unary\NegUnary;
|
use Twig\Node\Expression\Unary\NegUnary;
|
||||||
use Twig\Node\Expression\Unary\NotUnary;
|
use Twig\Node\Expression\Unary\NotUnary;
|
||||||
use Twig\Node\Expression\Unary\PosUnary;
|
use Twig\Node\Expression\Unary\PosUnary;
|
||||||
|
use Twig\NodeVisitor\MacroAutoImportNodeVisitor;
|
||||||
use Twig\TokenParser\ApplyTokenParser;
|
use Twig\TokenParser\ApplyTokenParser;
|
||||||
use Twig\TokenParser\BlockTokenParser;
|
use Twig\TokenParser\BlockTokenParser;
|
||||||
use Twig\TokenParser\DeprecatedTokenParser;
|
use Twig\TokenParser\DeprecatedTokenParser;
|
||||||
@@ -281,6 +282,11 @@ final class CoreExtension extends AbstractExtension
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getNodeVisitors()
|
||||||
|
{
|
||||||
|
return [new MacroAutoImportNodeVisitor()];
|
||||||
|
}
|
||||||
|
|
||||||
public function getOperators()
|
public function getOperators()
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
|
|||||||
@@ -0,0 +1,75 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of Twig.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Twig\NodeVisitor;
|
||||||
|
|
||||||
|
use Twig\Environment;
|
||||||
|
use Twig\Node\Expression\AssignNameExpression;
|
||||||
|
use Twig\Node\Expression\ConstantExpression;
|
||||||
|
use Twig\Node\Expression\GetAttrExpression;
|
||||||
|
use Twig\Node\Expression\MethodCallExpression;
|
||||||
|
use Twig\Node\Expression\NameExpression;
|
||||||
|
use Twig\Node\ImportNode;
|
||||||
|
use Twig\Node\ModuleNode;
|
||||||
|
use Twig\Node\Node;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fabien Potencier <fabien@symfony.com>
|
||||||
|
*/
|
||||||
|
final class MacroAutoImportNodeVisitor implements NodeVisitorInterface
|
||||||
|
{
|
||||||
|
private $inAModule = false;
|
||||||
|
private $hasMacroCalls = false;
|
||||||
|
|
||||||
|
public function enterNode(Node $node, Environment $env)
|
||||||
|
{
|
||||||
|
if ($node instanceof ModuleNode) {
|
||||||
|
$this->inAModule = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $node;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function leaveNode(Node $node, Environment $env)
|
||||||
|
{
|
||||||
|
if ($node instanceof ModuleNode) {
|
||||||
|
$this->inAModule = false;
|
||||||
|
if ($this->hasMacroCalls) {
|
||||||
|
$body = [new ImportNode(new NameExpression('_self', 0), new AssignNameExpression('_self', 0), 0, 'import', true)];
|
||||||
|
foreach ($node->getNode('body') as $n) {
|
||||||
|
$body[] = $n;
|
||||||
|
}
|
||||||
|
$node->setNode('body', new Node($body));
|
||||||
|
}
|
||||||
|
} elseif ($this->inAModule) {
|
||||||
|
if (
|
||||||
|
$node instanceof GetAttrExpression &&
|
||||||
|
$node->getNode('node') instanceof NameExpression &&
|
||||||
|
'_self' === $node->getNode('node')->getAttribute('name') &&
|
||||||
|
$node->getNode('attribute') instanceof ConstantExpression
|
||||||
|
) {
|
||||||
|
$this->hasMacroCalls = true;
|
||||||
|
|
||||||
|
$name = $node->getNode('attribute')->getAttribute('value');
|
||||||
|
$node = new MethodCallExpression($node->getNode('node'), 'macro_'.$name, $node->getNode('arguments'), $node->getTemplateLine());
|
||||||
|
$node->setAttribute('safe', true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $node;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPriority()
|
||||||
|
{
|
||||||
|
// we must be ran before auto-escaping
|
||||||
|
return -10;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
--TEST--
|
||||||
|
"macro" tag
|
||||||
|
--TEMPLATE--
|
||||||
|
{{ _self.hello('Fabien') }}
|
||||||
|
|
||||||
|
{% macro hello(name) -%}
|
||||||
|
Hello {{ _self.up(name) }}
|
||||||
|
{% endmacro %}
|
||||||
|
|
||||||
|
{% macro up(name) -%}
|
||||||
|
{{ name|upper }}
|
||||||
|
{% endmacro %}
|
||||||
|
--DATA--
|
||||||
|
return []
|
||||||
|
--EXPECT--
|
||||||
|
Hello FABIEN
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
--TEST--
|
||||||
|
"macro" tag
|
||||||
|
--TEMPLATE--
|
||||||
|
{% block content %}
|
||||||
|
{{ _self.hello('Fabien') }}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% macro hello(name) -%}
|
||||||
|
Hello {{ _self.up(name) }}
|
||||||
|
{% endmacro %}
|
||||||
|
|
||||||
|
{% macro up(name) -%}
|
||||||
|
{{ name|upper }}
|
||||||
|
{% endmacro %}
|
||||||
|
--DATA--
|
||||||
|
return []
|
||||||
|
--EXPECT--
|
||||||
|
Hello FABIEN
|
||||||
Reference in New Issue
Block a user