Ver Fonte

Add passthrough optimization for lambda sections.

Higher order sections which return mustache-free strings don’t need to be re-parsed, compiled and rendered. Just use the string, silly!

Fixes #141
Justin Hileman há 12 anos atrás
pai
commit
6b7f33c78d

+ 8 - 3
src/Mustache/Compiler.php

@@ -188,9 +188,14 @@ class Mustache_Compiler
             $buffer = \'\';
             if (%s) {
                 $source = %s;
-                $buffer .= $this->mustache
-                    ->loadLambda((string) call_user_func($value, $source, $this->lambdaHelper)%s)
-                    ->renderInternal($context);
+                $result = call_user_func($value, $source, $this->lambdaHelper);
+                if (strpos($result, \'{{\') === false) {
+                    $buffer .= $result;
+                } else {
+                    $buffer .= $this->mustache
+                        ->loadLambda((string) $result%s)
+                        ->renderInternal($context);
+                }
             } elseif (!empty($value)) {
                 $values = $this->isIterable($value) ? $value : array($value);
                 foreach ($values as $value) {

+ 29 - 0
test/Mustache/Test/Functional/HigherOrderSectionsTest.php

@@ -71,6 +71,35 @@ class Mustache_Test_Functional_HigherOrderSectionsTest extends PHPUnit_Framework
         $dracula->name  = 'Dracula';
         $this->assertEquals('Count Dracula', $tpl->render($dracula));
     }
+
+    public function testPassthroughOptimization()
+    {
+        $mustache = $this->getMock('Mustache_Engine', array('loadLambda'));
+        $mustache->expects($this->never())
+            ->method('loadLambda');
+
+        $tpl = $mustache->loadTemplate('{{#wrap}}NAME{{/wrap}}');
+
+        $foo = new Mustache_Test_Functional_Foo;
+        $foo->wrap = array($foo, 'wrapWithEm');
+
+        $this->assertEquals('<em>NAME</em>', $tpl->render($foo));
+    }
+
+    public function testWithoutPassthroughOptimization()
+    {
+        $mustache = $this->getMock('Mustache_Engine', array('loadLambda'));
+        $mustache->expects($this->once())
+            ->method('loadLambda')
+            ->will($this->returnValue($mustache->loadTemplate('<em>{{ name }}</em>')));
+
+        $tpl = $mustache->loadTemplate('{{#wrap}}{{name}}{{/wrap}}');
+
+        $foo = new Mustache_Test_Functional_Foo;
+        $foo->wrap = array($foo, 'wrapWithEm');
+
+        $this->assertEquals('<em>' . $foo->name . '</em>', $tpl->render($foo));
+    }
 }
 
 class Mustache_Test_Functional_Foo