Browse code

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

Fabien Potencier authored on 19/11/2016 19:45:49
Showing 13 changed files
... ...
@@ -17,7 +17,15 @@
17 17
  * improved the performance of the filesystem loader
18 18
  * removed features that were deprecated in 1.x
19 19
 
20
-* 1.28.0 (2016-XX-XX)
20
+* 1.28.2 (2016-XX-XX)
21
+
22
+ * n/a
23
+
24
+* 1.28.1 (2016-11-18)
25
+
26
+ * fixed block() function when used with a template argument
27
+
28
+* 1.28.0 (2016-11-17)
21 29
 
22 30
  * added support for the PHP 7 null coalescing operator for the ?? Twig implementation
23 31
  * exposed a way to access template data and methods in a portable way
... ...
@@ -31,7 +31,7 @@
31 31
         "symfony/polyfill-mbstring": "~1.0"
32 32
     },
33 33
     "require-dev": {
34
-        "symfony/phpunit-bridge": "~2.7",
34
+        "symfony/phpunit-bridge": "~3.2@dev",
35 35
         "symfony/debug": "~2.7"
36 36
     },
37 37
     "autoload": {
... ...
@@ -510,18 +510,18 @@ include in your templates:
510 510
     ``interpolateProvider`` service, for instance at the module initialization
511 511
     time:
512 512
 
513
-    ```js
514
-    angular.module('myApp', []).config(function($interpolateProvider) {
515
-        $interpolateProvider.startSymbol('{[').endSymbol(']}');
516
-    });
517
-    ```
513
+    ..code-block:: javascript
514
+
515
+        angular.module('myApp', []).config(function($interpolateProvider) {
516
+            $interpolateProvider.startSymbol('{[').endSymbol(']}');
517
+        });
518 518
 
519 519
   * For Twig, change the delimiters via the ``tag_variable`` Lexer option:
520 520
 
521
-    ```php
522
-    $env->setLexer(new Twig_Lexer($env, array(
523
-        'tag_variable' => array('{[', ']}'),
524
-    )));
525
-    ```
521
+    ..code-block:: php
522
+
523
+        $env->setLexer(new Twig_Lexer($env, array(
524
+            'tag_variable' => array('{[', ']}'),
525
+        )));
526 526
 
527 527
 .. _callback: http://www.php.net/manual/en/function.is-callable.php
... ...
@@ -32,6 +32,8 @@ is equivalent to the following one:
32 32
 By default, the inner scope has access to the outer scope context; you can
33 33
 disable this behavior by appending the ``only`` keyword:
34 34
 
35
+.. code-block:: jinja
36
+
35 37
     {% set bar = 'bar' %}
36 38
     {% with { foo: 42 } only %}
37 39
         {# only foo is defined #}
... ...
@@ -30,46 +30,53 @@ class Twig_Node_Expression_BlockReference extends Twig_Node_Expression
30 30
     public function compile(Twig_Compiler $compiler)
31 31
     {
32 32
         if ($this->getAttribute('is_defined_test')) {
33
-            $compiler
34
-                ->raw('$this->hasBlock(')
35
-                ->subcompile($this->getNode('name'))
36
-                ->raw(', $context, $blocks)')
37
-            ;
33
+            $this->compileTemplateCall($compiler, 'hasBlock');
38 34
         } else {
39 35
             if ($this->getAttribute('output')) {
40 36
                 $compiler->addDebugInfo($this);
41 37
 
42 38
                 $this
43
-                    ->compileTemplateCall($compiler)
44
-                    ->raw('->displayBlock(')
45
-                    ->subcompile($this->getNode('name'))
46
-                    ->raw(", \$context, \$blocks);\n")
47
-                ;
39
+                    ->compileTemplateCall($compiler, 'displayBlock')
40
+                    ->raw(";\n");
48 41
             } else {
49
-                $this
50
-                    ->compileTemplateCall($compiler)
51
-                    ->raw('->renderBlock(')
52
-                    ->subcompile($this->getNode('name'))
53
-                    ->raw(', $context, $blocks)')
54
-                ;
42
+                $this->compileTemplateCall($compiler, 'renderBlock');
55 43
             }
56 44
         }
57 45
     }
58 46
 
59
-    private function compileTemplateCall(Twig_Compiler $compiler)
47
+    private function compileTemplateCall(Twig_Compiler $compiler, $method)
48
+    {
49
+        if (!$this->hasNode('template')) {
50
+            $compiler->write('$this');
51
+        } else {
52
+            $compiler
53
+                ->write('$this->loadTemplate(')
54
+                ->subcompile($this->getNode('template'))
55
+                ->raw(', ')
56
+                ->repr($this->getTemplateName())
57
+                ->raw(', ')
58
+                ->repr($this->getTemplateLine())
59
+                ->raw(')')
60
+            ;
61
+        }
62
+
63
+        $compiler->raw(sprintf('->%s', $method));
64
+        $this->compileBlockArguments($compiler);
65
+
66
+        return $compiler;
67
+    }
68
+
69
+    private function compileBlockArguments(Twig_Compiler $compiler)
60 70
     {
71
+        $compiler
72
+            ->raw('(')
73
+            ->subcompile($this->getNode('name'))
74
+            ->raw(', $context');
75
+
61 76
         if (!$this->hasNode('template')) {
62
-            return $compiler->write('$this');
77
+            $compiler->raw(', $blocks');
63 78
         }
64 79
 
65
-        return $compiler
66
-            ->write('$this->loadTemplate(')
67
-            ->subcompile($this->getNode('template'))
68
-            ->raw(', ')
69
-            ->repr($this->getTemplateName())
70
-            ->raw(', ')
71
-            ->repr($this->getTemplateLine())
72
-            ->raw(')')
73
-        ;
80
+        return $compiler->raw(')');
74 81
     }
75 82
 }
... ...
@@ -88,20 +88,6 @@ final class Twig_TemplateWrapper
88 88
      */
89 89
     public function renderBlock($name, $context = array())
90 90
     {
91
-        ob_start();
92
-        $this->displayBlock($name, $context);
93
-
94
-        return ob_get_clean();
95
-    }
96
-
97
-    /**
98
-     * Displays a template block.
99
-     *
100
-     * @param string $name    The block name to render
101
-     * @param array  $context An array of parameters to pass to the template
102
-     */
103
-    public function displayBlock($name, $context = array())
104
-    {
105 91
         $context = $this->env->mergeGlobals($context);
106 92
         $level = ob_get_level();
107 93
         ob_start();
... ...
@@ -125,6 +111,17 @@ final class Twig_TemplateWrapper
125 111
     }
126 112
 
127 113
     /**
114
+     * Displays a template block.
115
+     *
116
+     * @param string $name    The block name to render
117
+     * @param array  $context An array of parameters to pass to the template
118
+     */
119
+    public function displayBlock($name, $context = array())
120
+    {
121
+        $this->template->displayBlock($name, $this->env->mergeGlobals($context));
122
+    }
123
+
124
+    /**
128 125
      * @return Twig_Source
129 126
      */
130 127
     public function getSourceContext()
... ...
@@ -17,6 +17,14 @@
17 17
     </testsuite>
18 18
   </testsuites>
19 19
 
20
+  <php>
21
+    <ini name="error_reporting" value="-1" />
22
+  </php>
23
+
24
+  <listeners>
25
+    <listener class="Symfony\Bridge\PhpUnit\SymfonyTestsListener" />
26
+  </listeners>
27
+
20 28
   <filter>
21 29
     <whitelist>
22 30
       <directory suffix=".php">./lib/Twig/</directory>
... ...
@@ -485,6 +485,7 @@ class Twig_Tests_EnvironmentTest_Runtime
485 485
     }
486 486
 }
487 487
 
488
+// to be removed in 2.0
488 489
 interface Twig_EnvironmentTestLoaderInterface extends Twig_LoaderInterface, Twig_SourceContextLoaderInterface
489 490
 {
490 491
 }
491 492
new file mode 100644
... ...
@@ -0,0 +1,22 @@
1
+--TEST--
2
+"block" function with a template argument
3
+--TEMPLATE--
4
+{{ block('foo', 'included.twig') }}
5
+{{ block('foo', included_loaded) }}
6
+{{ block('foo', included_loaded_internal) }}
7
+{% set output = block('foo', 'included.twig') %}
8
+{{ output }}
9
+{% block foo %}NOT FOO{% endblock %}
10
+--TEMPLATE(included.twig)--
11
+{% block foo %}FOO{% endblock %}
12
+--DATA--
13
+return array(
14
+    'included_loaded' => $twig->load('included.twig'),
15
+    'included_loaded_internal' => $twig->loadTemplate('included.twig'),
16
+)
17
+--EXPECT--
18
+FOO
19
+FOO
20
+FOO
21
+FOO
22
+NOT FOO
0 23
new file mode 100644
... ...
@@ -0,0 +1,17 @@
1
+--TEST--
2
+"defined" support for blocks with a template argument
3
+--TEMPLATE--
4
+{{ block('foo', 'included.twig') is defined ? 'ok' : 'ko' }}
5
+{{ block('foo', included_loaded) is defined ? 'ok' : 'ko' }}
6
+{{ block('foo', included_loaded_internal) is defined ? 'ok' : 'ko' }}
7
+--TEMPLATE(included.twig)--
8
+{% block foo %}FOO{% endblock %}
9
+--DATA--
10
+return array(
11
+    'included_loaded' => $twig->load('included.twig'),
12
+    'included_loaded_internal' => $twig->loadTemplate('included.twig'),
13
+)
14
+--EXPECT--
15
+ok
16
+ok
17
+ok
... ...
@@ -11,6 +11,9 @@
11 11
 
12 12
 class Twig_Tests_NativeExtensionTest extends PHPUnit_Framework_TestCase
13 13
 {
14
+    /**
15
+     * @requires PHP 5.3
16
+     */
14 17
     public function testGetProperties()
15 18
     {
16 19
         if (defined('HHVM_VERSION')) {
... ...
@@ -350,9 +350,9 @@ class Twig_Tests_TemplateTest extends PHPUnit_Framework_TestCase
350 350
 
351 351
         // tests when input is not an array or object
352 352
         $tests = array_merge($tests, array(
353
-            array(false, null, 42, 'a', array(), $anyType, false, 'Impossible to access an attribute ("a") on a integer variable ("42").'),
354
-            array(false, null, 'string', 'a', array(), $anyType, false, 'Impossible to access an attribute ("a") on a string variable ("string").'),
355
-            array(false, null, array(), 'a', array(), $anyType, false, 'Key "a" does not exist as the array is empty.'),
353
+            array(false, null, 42, 'a', array(), $anyType, false, 'Impossible to access an attribute ("a") on a integer variable ("42") in "index.twig".'),
354
+            array(false, null, 'string', 'a', array(), $anyType, false, 'Impossible to access an attribute ("a") on a string variable ("string") in "index.twig".'),
355
+            array(false, null, array(), 'a', array(), $anyType, false, 'Key "a" does not exist as the array is empty in "index.twig".'),
356 356
         ));
357 357
 
358 358
         // add twig_template_get_attributes tests
... ...
@@ -372,12 +372,14 @@ class Twig_Tests_TemplateTest extends PHPUnit_Framework_TestCase
372 372
 class Twig_TemplateTest extends Twig_Template
373 373
 {
374 374
     protected $useExtGetAttribute = false;
375
+    private $name;
375 376
 
376
-    public function __construct(Twig_Environment $env, $useExtGetAttribute = false)
377
+    public function __construct(Twig_Environment $env, $useExtGetAttribute = false, $name = 'index.twig')
377 378
     {
378 379
         parent::__construct($env);
379 380
         $this->useExtGetAttribute = $useExtGetAttribute;
380 381
         self::$cache = array();
382
+        $this->name = $name;
381 383
     }
382 384
 
383 385
     public function getZero()
... ...
@@ -402,6 +404,7 @@ class Twig_TemplateTest extends Twig_Template
402 404
 
403 405
     public function getTemplateName()
404 406
     {
407
+        return $this->name;
405 408
     }
406 409
 
407 410
     public function getDebugInfo()
... ...
@@ -409,13 +412,9 @@ class Twig_TemplateTest extends Twig_Template
409 412
         return array();
410 413
     }
411 414
 
412
-    public function getSource()
413
-    {
414
-        return '';
415
-    }
416
-
417 415
     protected function doGetParent(array $context)
418 416
     {
417
+        return false;
419 418
     }
420 419
 
421 420
     protected function doDisplay(array $context, array $blocks = array())
... ...
@@ -658,3 +657,8 @@ class CExtDisablingNodeVisitor implements Twig_NodeVisitorInterface
658 657
         return 0;
659 658
     }
660 659
 }
660
+
661
+// to be removed in 2.0
662
+interface Twig_TemplateTestLoaderInterface extends Twig_LoaderInterface, Twig_SourceContextLoaderInterface
663
+{
664
+}
... ...
@@ -35,4 +35,30 @@ class Twig_Tests_TemplateWrapperTest extends PHPUnit_Framework_TestCase
35 35
         $this->assertTrue($wrapper->hasBlock('extended'));
36 36
         $this->assertEquals(array('foo', 'extended'), $wrapper->getBlockNames());
37 37
     }
38
+
39
+    public function testRenderBlock()
40
+    {
41
+        $twig = new Twig_Environment(new Twig_Loader_Array(array(
42
+            'index' => '{% block foo %}{{ foo }}{{ bar }}{% endblock %}',
43
+        )));
44
+        $twig->addGlobal('bar', 'BAR');
45
+
46
+        $wrapper = new Twig_TemplateWrapper($twig, $twig->loadTemplate('index'));
47
+        $this->assertEquals('FOOBAR', $wrapper->renderBlock('foo', array('foo' => 'FOO')));
48
+    }
49
+
50
+    public function testDisplayBlock()
51
+    {
52
+        $twig = new Twig_Environment(new Twig_Loader_Array(array(
53
+            'index' => '{% block foo %}{{ foo }}{{ bar }}{% endblock %}',
54
+        )));
55
+        $twig->addGlobal('bar', 'BAR');
56
+
57
+        $wrapper = new Twig_TemplateWrapper($twig, $twig->loadTemplate('index'));
58
+
59
+        ob_start();
60
+        $wrapper->displayBlock('foo', array('foo' => 'FOO'));
61
+
62
+        $this->assertEquals('FOOBAR', ob_get_clean());
63
+    }
38 64
 }