mirror of
https://github.com/twigphp/Twig.git
synced 2026-09-14 11:27:00 +00:00
Merge branch '1.x' into 2.x
* 1.x: added some more tests added 'is defined' support for constant added 'is defined' support for block() Add test to check if a block exists
This commit is contained in:
@@ -19,6 +19,7 @@
|
||||
|
||||
* 1.28.0 (2016-XX-XX)
|
||||
|
||||
* added "is defined" support for block() and constant()
|
||||
* optimized the way attributes are fetched
|
||||
|
||||
* 1.27.0 (2016-10-25)
|
||||
|
||||
@@ -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>`
|
||||
|
||||
@@ -13,3 +13,11 @@ You can read constants from object instances as well:
|
||||
.. code-block:: jinja
|
||||
|
||||
{{ constant('RSS', date) }}
|
||||
|
||||
Use the ``defined`` test to check if a constant is defined:
|
||||
|
||||
.. code-block:: jinja
|
||||
|
||||
{% if constant('SOME_CONST') is defined %}
|
||||
...
|
||||
{% endif %}
|
||||
|
||||
@@ -1275,6 +1275,23 @@ function twig_constant($constant, $object = null)
|
||||
return constant($constant);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a constant exists.
|
||||
*
|
||||
* @param string $constant The name of the constant
|
||||
* @param null|object $object The object to get the constant from
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
function twig_constant_is_defined($constant, $object = null)
|
||||
{
|
||||
if (null !== $object) {
|
||||
$constant = get_class($object).'::'.$constant;
|
||||
}
|
||||
|
||||
return defined($constant);
|
||||
}
|
||||
|
||||
/**
|
||||
* Batches item.
|
||||
*
|
||||
|
||||
@@ -19,24 +19,32 @@ class Twig_Node_Expression_BlockReference extends Twig_Node_Expression
|
||||
{
|
||||
public function __construct(Twig_Node $name, $lineno, $tag = 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)')
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ class Twig_Node_Expression_Function extends Twig_Node_Expression_Call
|
||||
{
|
||||
public function __construct($name, Twig_Node $arguments, $lineno)
|
||||
{
|
||||
parent::__construct(array('arguments' => $arguments), array('name' => $name), $lineno);
|
||||
parent::__construct(array('arguments' => $arguments), array('name' => $name, 'is_defined_test' => false), $lineno);
|
||||
}
|
||||
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
@@ -25,7 +25,11 @@ class Twig_Node_Expression_Function extends Twig_Node_Expression_Call
|
||||
$this->setAttribute('needs_environment', $function->needsEnvironment());
|
||||
$this->setAttribute('needs_context', $function->needsContext());
|
||||
$this->setAttribute('arguments', $function->getArguments());
|
||||
$this->setAttribute('callable', $function->getCallable());
|
||||
$callable = $function->getCallable();
|
||||
if ('constant' === $name && $this->getAttribute('is_defined_test')) {
|
||||
$callable = 'twig_constant_is_defined';
|
||||
}
|
||||
$this->setAttribute('callable', $callable);
|
||||
$this->setAttribute('is_variadic', $function->isVariadic());
|
||||
|
||||
$this->compileCallable($compiler);
|
||||
|
||||
@@ -29,8 +29,11 @@ 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_Function && 'constant' === $node->getAttribute('name')) {
|
||||
$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 {
|
||||
|
||||
@@ -255,6 +255,8 @@ abstract class Twig_Template
|
||||
*
|
||||
* @return bool true if the block exists, false otherwise
|
||||
*
|
||||
* @see blockExists
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public function hasBlock($name)
|
||||
@@ -600,4 +602,37 @@ abstract class Twig_Template
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether a block exists or not in the current context of the template.
|
||||
*
|
||||
* This method checks blocks defined in the current template
|
||||
* or defined in "used" traits or defined in parent templates.
|
||||
*
|
||||
* @param string $name The block name
|
||||
* @param array $context The context
|
||||
* @param array $blocks The current set of blocks
|
||||
*
|
||||
* @return bool true if the block exists, false otherwise
|
||||
*
|
||||
* @see hasBlock
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
protected function blockExists($name, array $context, array $blocks = array())
|
||||
{
|
||||
if (isset($blocks[$name])) {
|
||||
return $blocks[$name][0] instanceof self;
|
||||
}
|
||||
|
||||
if (isset($this->blocks[$name])) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (false !== $parent = $this->getParent($context)) {
|
||||
return $parent->blockExists($name, $context);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
--TEST--
|
||||
"defined" support for attribute
|
||||
--TEMPLATE--
|
||||
{{ attribute(nested, "definedVar") is defined ? 'ok' : 'ko' }}
|
||||
{{ attribute(nested, "undefinedVar") is not defined ? 'ok' : 'ko' }}
|
||||
{{ attribute(nested, definedVarName) is defined ? 'ok' : 'ko' }}
|
||||
{{ attribute(nested, undefinedVarName) is not defined ? 'ok' : 'ko' }}
|
||||
--DATA--
|
||||
return array(
|
||||
'nested' => array(
|
||||
'definedVar' => 'defined',
|
||||
),
|
||||
'definedVarName' => 'definedVar',
|
||||
'undefinedVarName' => 'undefinedVar',
|
||||
);
|
||||
--EXPECT--
|
||||
ok
|
||||
ok
|
||||
ok
|
||||
ok
|
||||
--DATA--
|
||||
return array(
|
||||
'nested' => array(
|
||||
'definedVar' => 'defined',
|
||||
),
|
||||
'definedVarName' => 'definedVar',
|
||||
'undefinedVarName' => 'undefinedVar',
|
||||
);
|
||||
--CONFIG--
|
||||
return array('strict_variables' => false)
|
||||
--EXPECT--
|
||||
ok
|
||||
ok
|
||||
ok
|
||||
ok
|
||||
@@ -0,0 +1,38 @@
|
||||
--TEST--
|
||||
"defined" support for blocks
|
||||
--TEMPLATE--
|
||||
{% extends 'parent' %}
|
||||
{% block icon %}icon{% endblock %}
|
||||
{% block body %}
|
||||
{{ parent() }}
|
||||
{{ 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 %}
|
||||
{% endblock %}
|
||||
{% use 'blocks' %}
|
||||
--TEMPLATE(parent)--
|
||||
{% block body %}
|
||||
{{ block('icon') is defined ? 'ok' : 'ko' -}}
|
||||
{% endblock %}
|
||||
{% block footer %}{% endblock %}
|
||||
--TEMPLATE(embed)--
|
||||
{{ block('icon') is defined ? 'ok' : 'ko' }}
|
||||
{{ block('content') is defined ? 'ok' : 'ko' }}
|
||||
{{ block('block1') is defined ? 'ok' : 'ko' }}
|
||||
--TEMPLATE(blocks)--
|
||||
{% block block1 %}{%endblock %}
|
||||
--DATA--
|
||||
return array()
|
||||
--EXPECT--
|
||||
ok
|
||||
ko
|
||||
ok
|
||||
ok
|
||||
ok
|
||||
ko
|
||||
ok
|
||||
ko
|
||||
@@ -0,0 +1,14 @@
|
||||
--TEST--
|
||||
"defined" support for constants
|
||||
--TEMPLATE--
|
||||
{{ constant('DATE_W3C') is defined ? 'ok' : 'ko' }}
|
||||
{{ constant('ARRAY_AS_PROPS', object) is defined ? 'ok' : 'ko' }}
|
||||
{{ constant('FOOBAR') is not defined ? 'ok' : 'ko' }}
|
||||
{{ constant('FOOBAR', object) is not defined ? 'ok' : 'ko' }}
|
||||
--DATA--
|
||||
return array('expect' => DATE_W3C, 'object' => new ArrayObject(array('hi')));
|
||||
--EXPECT--
|
||||
ok
|
||||
ok
|
||||
ok
|
||||
ok
|
||||
Reference in New Issue
Block a user