From 3ce06af6b4ca335f889da3f9fff8f3a372005759 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Fri, 11 Nov 2016 09:04:38 -0800 Subject: [PATCH] added 'is defined' support for block() --- CHANGELOG | 1 + doc/functions/block.rst | 9 +++++ doc/tests/block_name.rst | 13 -------- doc/tests/index.rst | 1 - lib/Twig/Extension/Core.php | 1 - lib/Twig/Node/Expression/BlockReference.php | 28 ++++++++++------ lib/Twig/Node/Expression/Test/BlockName.php | 33 ------------------- lib/Twig/Node/Expression/Test/Defined.php | 3 +- ...lock_name.test => defined_for_blocks.test} | 18 +++++----- 9 files changed, 39 insertions(+), 68 deletions(-) delete mode 100644 doc/tests/block_name.rst delete mode 100644 lib/Twig/Node/Expression/Test/BlockName.php rename test/Twig/Tests/Fixtures/tests/{block_name.test => defined_for_blocks.test} (53%) diff --git a/CHANGELOG b/CHANGELOG index 6920bd1fb..1a0807c9f 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,6 @@ * 1.28.0 (2016-XX-XX) + * added "is defined" support for block() * optimized the way attributes are fetched * 1.27.0 (2016-10-25) diff --git a/doc/functions/block.rst b/doc/functions/block.rst index fd571efbc..2f3de2456 100644 --- a/doc/functions/block.rst +++ b/doc/functions/block.rst @@ -12,4 +12,13 @@ times, use the ``block`` function: {% block body %}{% endblock %} +Use the ``defined`` test to check if a block exists in the context of the +current template: + +.. code-block:: jinja + + {% if block("footer") is defined %} + ... + {% endif %} + .. seealso:: :doc:`extends<../tags/extends>`, :doc:`parent<../functions/parent>` diff --git a/doc/tests/block_name.rst b/doc/tests/block_name.rst deleted file mode 100644 index 8cba0cee7..000000000 --- a/doc/tests/block_name.rst +++ /dev/null @@ -1,13 +0,0 @@ -``block name`` -============== - -.. versionadded:: 1.28 - The ``block name`` test was added in Twig 1.28. - -``block name`` checks if a block is defined in the current context of the template. - -.. code-block:: jinja - - {% if 'title' is block name %} - {{ block('title') }}<title> - {% endif %} diff --git a/doc/tests/index.rst b/doc/tests/index.rst index 42655fda9..c63208ee7 100644 --- a/doc/tests/index.rst +++ b/doc/tests/index.rst @@ -4,7 +4,6 @@ Tests .. toctree:: :maxdepth: 1 - block_name constant defined divisibleby diff --git a/lib/Twig/Extension/Core.php b/lib/Twig/Extension/Core.php index ebaf8bfc8..901a3058f 100644 --- a/lib/Twig/Extension/Core.php +++ b/lib/Twig/Extension/Core.php @@ -222,7 +222,6 @@ class Twig_Extension_Core extends Twig_Extension new Twig_SimpleTest('constant', null, array('node_class' => 'Twig_Node_Expression_Test_Constant')), new Twig_SimpleTest('empty', 'twig_test_empty'), new Twig_SimpleTest('iterable', 'twig_test_iterable'), - new Twig_SimpleTest('block name', null, array('node_class' => 'Twig_Node_Expression_Test_BlockName')), ); } diff --git a/lib/Twig/Node/Expression/BlockReference.php b/lib/Twig/Node/Expression/BlockReference.php index 3fe7d0580..d22dd57cc 100644 --- a/lib/Twig/Node/Expression/BlockReference.php +++ b/lib/Twig/Node/Expression/BlockReference.php @@ -26,24 +26,32 @@ class Twig_Node_Expression_BlockReference extends Twig_Node_Expression $tag = func_num_args() > 3 ? func_get_arg(3) : null; } - parent::__construct(array('name' => $name), array('output' => false), $lineno, $tag); + parent::__construct(array('name' => $name), array('is_defined_test' => false, 'output' => false), $lineno, $tag); } public function compile(Twig_Compiler $compiler) { - if ($this->getAttribute('output')) { + if ($this->getAttribute('is_defined_test')) { $compiler - ->addDebugInfo($this) - ->write('$this->displayBlock(') - ->subcompile($this->getNode('name')) - ->raw(", \$context, \$blocks);\n") - ; - } else { - $compiler - ->raw('$this->renderBlock(') + ->raw('$this->blockExists(') ->subcompile($this->getNode('name')) ->raw(', $context, $blocks)') ; + } else { + if ($this->getAttribute('output')) { + $compiler + ->addDebugInfo($this) + ->write('$this->displayBlock(') + ->subcompile($this->getNode('name')) + ->raw(", \$context, \$blocks);\n") + ; + } else { + $compiler + ->raw('$this->renderBlock(') + ->subcompile($this->getNode('name')) + ->raw(', $context, $blocks)') + ; + } } } } diff --git a/lib/Twig/Node/Expression/Test/BlockName.php b/lib/Twig/Node/Expression/Test/BlockName.php deleted file mode 100644 index 8261d0ddf..000000000 --- a/lib/Twig/Node/Expression/Test/BlockName.php +++ /dev/null @@ -1,33 +0,0 @@ -<?php - -/* - * This file is part of Twig. - * - * (c) 2016 Fabien Potencier - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -/** - * Checks whether a block is defined. - * - * <pre> - * {% if 'title' is block name %} - * <title>{{ block('title') }} - * {% endif %} - * - * - * @author Martin HasoĊˆ - */ -class Twig_Node_Expression_Test_BlockName extends Twig_Node_Expression_Test -{ - public function compile(Twig_Compiler $compiler) - { - $compiler - ->raw('$this->blockExists(') - ->subcompile($this->getNode('node')) - ->raw(', $context, $blocks)') - ; - } -} diff --git a/lib/Twig/Node/Expression/Test/Defined.php b/lib/Twig/Node/Expression/Test/Defined.php index c57fe09eb..a8fd74db9 100644 --- a/lib/Twig/Node/Expression/Test/Defined.php +++ b/lib/Twig/Node/Expression/Test/Defined.php @@ -29,8 +29,9 @@ class Twig_Node_Expression_Test_Defined extends Twig_Node_Expression_Test $node->setAttribute('is_defined_test', true); } elseif ($node instanceof Twig_Node_Expression_GetAttr) { $node->setAttribute('is_defined_test', true); - $this->changeIgnoreStrictCheck($node); + } elseif ($node instanceof Twig_Node_Expression_BlockReference) { + $node->setAttribute('is_defined_test', true); } elseif ($node instanceof Twig_Node_Expression_Constant || $node instanceof Twig_Node_Expression_Array) { $node = new Twig_Node_Expression_Constant(true, $node->getTemplateLine()); } else { diff --git a/test/Twig/Tests/Fixtures/tests/block_name.test b/test/Twig/Tests/Fixtures/tests/defined_for_blocks.test similarity index 53% rename from test/Twig/Tests/Fixtures/tests/block_name.test rename to test/Twig/Tests/Fixtures/tests/defined_for_blocks.test index 690f3fa69..64d7d0431 100644 --- a/test/Twig/Tests/Fixtures/tests/block_name.test +++ b/test/Twig/Tests/Fixtures/tests/defined_for_blocks.test @@ -1,14 +1,14 @@ --TEST-- -"block name" test +"defined" support for blocks --TEMPLATE-- {% extends 'parent' %} {% block icon %}icon{% endblock %} {% block body %} {{ parent() }} - {{ 'foo' is block name ? 'ok' : 'ko' }} - {{ 'footer' is block name ? 'ok' : 'ko' }} - {{ 'icon' is block name ? 'ok' : 'ko' }} - {{ 'block1' is block name ? 'ok' : 'ko' }} + {{ block('foo') is defined ? 'ok' : 'ko' }} + {{ block('footer') is defined ? 'ok' : 'ko' }} + {{ block('icon') is defined ? 'ok' : 'ko' }} + {{ block('block1') is defined ? 'ok' : 'ko' }} {%- embed 'embed' %} {% block content %}content{% endblock %} {% endembed %} @@ -16,13 +16,13 @@ {% use 'blocks' %} --TEMPLATE(parent)-- {% block body %} - {{ 'icon' is block name ? 'ok' : 'ko' -}} + {{ block('icon') is defined ? 'ok' : 'ko' -}} {% endblock %} {% block footer %}{% endblock %} --TEMPLATE(embed)-- -{{ 'icon' is block name ? 'ok' : 'ko' }} -{{ 'content' is block name ? 'ok' : 'ko' }} -{{ 'block1' is block name ? 'ok' : 'ko' }} +{{ block('icon') is defined ? 'ok' : 'ko' }} +{{ block('content') is defined ? 'ok' : 'ko' }} +{{ block('block1') is defined ? 'ok' : 'ko' }} --TEMPLATE(blocks)-- {% block block1 %}{%endblock %} --DATA--