Merge branch '1.x' into 2.x

* 1.x:
  fixed message
  improved a deprecation notice
  bumped version to 1.28.2-DEV
  prepared the 1.28.1 release
  added tests for block() when using a template argument
  fixed block() is defined call when using a template argument
  Bugfix: When rendering blocks of other templates, don't pass the local blocks array.
  fixed doc issues
  fixed typo in the docs
  fix wrong __CLASS__ constant
  bumped version to 1.28.1-DEV
  prepared the 1.28.0 release
  fixed render block with template wrapper
This commit is contained in:
Fabien Potencier
2016-11-19 11:45:49 -08:00
13 changed files with 157 additions and 62 deletions
+9 -1
View File
@@ -17,7 +17,15 @@
* improved the performance of the filesystem loader
* removed features that were deprecated in 1.x
* 1.28.0 (2016-XX-XX)
* 1.28.2 (2016-XX-XX)
* n/a
* 1.28.1 (2016-11-18)
* fixed block() function when used with a template argument
* 1.28.0 (2016-11-17)
* added support for the PHP 7 null coalescing operator for the ?? Twig implementation
* exposed a way to access template data and methods in a portable way
+1 -1
View File
@@ -31,7 +31,7 @@
"symfony/polyfill-mbstring": "~1.0"
},
"require-dev": {
"symfony/phpunit-bridge": "~2.7",
"symfony/phpunit-bridge": "~3.2@dev",
"symfony/debug": "~2.7"
},
"autoload": {
+10 -10
View File
@@ -510,18 +510,18 @@ include in your templates:
``interpolateProvider`` service, for instance at the module initialization
time:
```js
angular.module('myApp', []).config(function($interpolateProvider) {
$interpolateProvider.startSymbol('{[').endSymbol(']}');
});
```
..code-block:: javascript
angular.module('myApp', []).config(function($interpolateProvider) {
$interpolateProvider.startSymbol('{[').endSymbol(']}');
});
* For Twig, change the delimiters via the ``tag_variable`` Lexer option:
```php
$env->setLexer(new Twig_Lexer($env, array(
'tag_variable' => array('{[', ']}'),
)));
```
..code-block:: php
$env->setLexer(new Twig_Lexer($env, array(
'tag_variable' => array('{[', ']}'),
)));
.. _callback: http://www.php.net/manual/en/function.is-callable.php
+2
View File
@@ -32,6 +32,8 @@ is equivalent to the following one:
By default, the inner scope has access to the outer scope context; you can
disable this behavior by appending the ``only`` keyword:
.. code-block:: jinja
{% set bar = 'bar' %}
{% with { foo: 42 } only %}
{# only foo is defined #}
+34 -27
View File
@@ -30,46 +30,53 @@ class Twig_Node_Expression_BlockReference extends Twig_Node_Expression
public function compile(Twig_Compiler $compiler)
{
if ($this->getAttribute('is_defined_test')) {
$compiler
->raw('$this->hasBlock(')
->subcompile($this->getNode('name'))
->raw(', $context, $blocks)')
;
$this->compileTemplateCall($compiler, 'hasBlock');
} else {
if ($this->getAttribute('output')) {
$compiler->addDebugInfo($this);
$this
->compileTemplateCall($compiler)
->raw('->displayBlock(')
->subcompile($this->getNode('name'))
->raw(", \$context, \$blocks);\n")
;
->compileTemplateCall($compiler, 'displayBlock')
->raw(";\n");
} else {
$this
->compileTemplateCall($compiler)
->raw('->renderBlock(')
->subcompile($this->getNode('name'))
->raw(', $context, $blocks)')
;
$this->compileTemplateCall($compiler, 'renderBlock');
}
}
}
private function compileTemplateCall(Twig_Compiler $compiler)
private function compileTemplateCall(Twig_Compiler $compiler, $method)
{
if (!$this->hasNode('template')) {
return $compiler->write('$this');
$compiler->write('$this');
} else {
$compiler
->write('$this->loadTemplate(')
->subcompile($this->getNode('template'))
->raw(', ')
->repr($this->getTemplateName())
->raw(', ')
->repr($this->getTemplateLine())
->raw(')')
;
}
return $compiler
->write('$this->loadTemplate(')
->subcompile($this->getNode('template'))
->raw(', ')
->repr($this->getTemplateName())
->raw(', ')
->repr($this->getTemplateLine())
->raw(')')
;
$compiler->raw(sprintf('->%s', $method));
$this->compileBlockArguments($compiler);
return $compiler;
}
private function compileBlockArguments(Twig_Compiler $compiler)
{
$compiler
->raw('(')
->subcompile($this->getNode('name'))
->raw(', $context');
if (!$this->hasNode('template')) {
$compiler->raw(', $blocks');
}
return $compiler->raw(')');
}
}
+11 -14
View File
@@ -87,20 +87,6 @@ final class Twig_TemplateWrapper
* @return string The rendered block
*/
public function renderBlock($name, $context = array())
{
ob_start();
$this->displayBlock($name, $context);
return ob_get_clean();
}
/**
* Displays a template block.
*
* @param string $name The block name to render
* @param array $context An array of parameters to pass to the template
*/
public function displayBlock($name, $context = array())
{
$context = $this->env->mergeGlobals($context);
$level = ob_get_level();
@@ -124,6 +110,17 @@ final class Twig_TemplateWrapper
return ob_get_clean();
}
/**
* Displays a template block.
*
* @param string $name The block name to render
* @param array $context An array of parameters to pass to the template
*/
public function displayBlock($name, $context = array())
{
$this->template->displayBlock($name, $this->env->mergeGlobals($context));
}
/**
* @return Twig_Source
*/
+8
View File
@@ -17,6 +17,14 @@
</testsuite>
</testsuites>
<php>
<ini name="error_reporting" value="-1" />
</php>
<listeners>
<listener class="Symfony\Bridge\PhpUnit\SymfonyTestsListener" />
</listeners>
<filter>
<whitelist>
<directory suffix=".php">./lib/Twig/</directory>
+1
View File
@@ -485,6 +485,7 @@ class Twig_Tests_EnvironmentTest_Runtime
}
}
// to be removed in 2.0
interface Twig_EnvironmentTestLoaderInterface extends Twig_LoaderInterface, Twig_SourceContextLoaderInterface
{
}
@@ -0,0 +1,22 @@
--TEST--
"block" function with a template argument
--TEMPLATE--
{{ block('foo', 'included.twig') }}
{{ block('foo', included_loaded) }}
{{ block('foo', included_loaded_internal) }}
{% set output = block('foo', 'included.twig') %}
{{ output }}
{% block foo %}NOT FOO{% endblock %}
--TEMPLATE(included.twig)--
{% block foo %}FOO{% endblock %}
--DATA--
return array(
'included_loaded' => $twig->load('included.twig'),
'included_loaded_internal' => $twig->loadTemplate('included.twig'),
)
--EXPECT--
FOO
FOO
FOO
FOO
NOT FOO
@@ -0,0 +1,17 @@
--TEST--
"defined" support for blocks with a template argument
--TEMPLATE--
{{ block('foo', 'included.twig') is defined ? 'ok' : 'ko' }}
{{ block('foo', included_loaded) is defined ? 'ok' : 'ko' }}
{{ block('foo', included_loaded_internal) is defined ? 'ok' : 'ko' }}
--TEMPLATE(included.twig)--
{% block foo %}FOO{% endblock %}
--DATA--
return array(
'included_loaded' => $twig->load('included.twig'),
'included_loaded_internal' => $twig->loadTemplate('included.twig'),
)
--EXPECT--
ok
ok
ok
+3
View File
@@ -11,6 +11,9 @@
class Twig_Tests_NativeExtensionTest extends PHPUnit_Framework_TestCase
{
/**
* @requires PHP 5.3
*/
public function testGetProperties()
{
if (defined('HHVM_VERSION')) {
+13 -9
View File
@@ -350,9 +350,9 @@ class Twig_Tests_TemplateTest extends PHPUnit_Framework_TestCase
// tests when input is not an array or object
$tests = array_merge($tests, array(
array(false, null, 42, 'a', array(), $anyType, false, 'Impossible to access an attribute ("a") on a integer variable ("42").'),
array(false, null, 'string', 'a', array(), $anyType, false, 'Impossible to access an attribute ("a") on a string variable ("string").'),
array(false, null, array(), 'a', array(), $anyType, false, 'Key "a" does not exist as the array is empty.'),
array(false, null, 42, 'a', array(), $anyType, false, 'Impossible to access an attribute ("a") on a integer variable ("42") in "index.twig".'),
array(false, null, 'string', 'a', array(), $anyType, false, 'Impossible to access an attribute ("a") on a string variable ("string") in "index.twig".'),
array(false, null, array(), 'a', array(), $anyType, false, 'Key "a" does not exist as the array is empty in "index.twig".'),
));
// add twig_template_get_attributes tests
@@ -372,12 +372,14 @@ class Twig_Tests_TemplateTest extends PHPUnit_Framework_TestCase
class Twig_TemplateTest extends Twig_Template
{
protected $useExtGetAttribute = false;
private $name;
public function __construct(Twig_Environment $env, $useExtGetAttribute = false)
public function __construct(Twig_Environment $env, $useExtGetAttribute = false, $name = 'index.twig')
{
parent::__construct($env);
$this->useExtGetAttribute = $useExtGetAttribute;
self::$cache = array();
$this->name = $name;
}
public function getZero()
@@ -402,6 +404,7 @@ class Twig_TemplateTest extends Twig_Template
public function getTemplateName()
{
return $this->name;
}
public function getDebugInfo()
@@ -409,13 +412,9 @@ class Twig_TemplateTest extends Twig_Template
return array();
}
public function getSource()
{
return '';
}
protected function doGetParent(array $context)
{
return false;
}
protected function doDisplay(array $context, array $blocks = array())
@@ -658,3 +657,8 @@ class CExtDisablingNodeVisitor implements Twig_NodeVisitorInterface
return 0;
}
}
// to be removed in 2.0
interface Twig_TemplateTestLoaderInterface extends Twig_LoaderInterface, Twig_SourceContextLoaderInterface
{
}
+26
View File
@@ -35,4 +35,30 @@ class Twig_Tests_TemplateWrapperTest extends PHPUnit_Framework_TestCase
$this->assertTrue($wrapper->hasBlock('extended'));
$this->assertEquals(array('foo', 'extended'), $wrapper->getBlockNames());
}
public function testRenderBlock()
{
$twig = new Twig_Environment(new Twig_Loader_Array(array(
'index' => '{% block foo %}{{ foo }}{{ bar }}{% endblock %}',
)));
$twig->addGlobal('bar', 'BAR');
$wrapper = new Twig_TemplateWrapper($twig, $twig->loadTemplate('index'));
$this->assertEquals('FOOBAR', $wrapper->renderBlock('foo', array('foo' => 'FOO')));
}
public function testDisplayBlock()
{
$twig = new Twig_Environment(new Twig_Loader_Array(array(
'index' => '{% block foo %}{{ foo }}{{ bar }}{% endblock %}',
)));
$twig->addGlobal('bar', 'BAR');
$wrapper = new Twig_TemplateWrapper($twig, $twig->loadTemplate('index'));
ob_start();
$wrapper->displayBlock('foo', array('foo' => 'FOO'));
$this->assertEquals('FOOBAR', ob_get_clean());
}
}