diff --git a/composer.json b/composer.json
index 388a940..f2ba0f9 100644
--- a/composer.json
+++ b/composer.json
@@ -16,7 +16,7 @@
"php": ">=5.2.4"
},
"require-dev": {
- "phpunit/phpunit": "~3.7|~4.0",
+ "phpunit/phpunit": "~3.7|~4.0|~5.0",
"fabpot/php-cs-fixer": "~1.6"
},
"autoload": {
diff --git a/src/Mustache/Compiler.php b/src/Mustache/Compiler.php
index 7d5c96b..76e580c 100644
--- a/src/Mustache/Compiler.php
+++ b/src/Mustache/Compiler.php
@@ -328,7 +328,7 @@ class Mustache_Compiler
$buffer = \'\';
if (%s) {
$source = %s;
- $result = call_user_func($value, $source, $this->lambdaHelper);
+ $result = call_user_func($value, $source, %s);
if (strpos($result, \'{{\') === false) {
$buffer .= $result;
} else {
@@ -370,15 +370,18 @@ class Mustache_Compiler
$callable = $this->getCallable();
if ($otag !== '{{' || $ctag !== '}}') {
- $delims = ', ' . var_export(sprintf('{{= %s %s =}}', $otag, $ctag), true);
+ $delimTag = var_export(sprintf('{{= %s %s =}}', $otag, $ctag), true);
+ $helper = sprintf('$this->lambdaHelper->withDelimiters(%s)', $delimTag);
+ $delims = ', ' . $delimTag;
} else {
+ $helper = '$this->lambdaHelper';
$delims = '';
}
$key = ucfirst(md5($delims . "\n" . $source));
if (!isset($this->sections[$key])) {
- $this->sections[$key] = sprintf($this->prepare(self::SECTION), $key, $callable, $source, $delims, $this->walk($nodes, 2));
+ $this->sections[$key] = sprintf($this->prepare(self::SECTION), $key, $callable, $source, $helper, $delims, $this->walk($nodes, 2));
}
if ($arg === true) {
@@ -495,7 +498,7 @@ class Mustache_Compiler
}
const VARIABLE = '
- $value = $this->resolveValue($context->%s(%s), $context, $indent);%s
+ $value = $this->resolveValue($context->%s(%s), $context);%s
$buffer .= %s%s;
';
diff --git a/src/Mustache/Engine.php b/src/Mustache/Engine.php
index 08bcc81..fe11912 100644
--- a/src/Mustache/Engine.php
+++ b/src/Mustache/Engine.php
@@ -23,7 +23,7 @@
*/
class Mustache_Engine
{
- const VERSION = '2.9.0';
+ const VERSION = '2.10.0';
const SPEC_VERSION = '1.1.2';
const PRAGMA_FILTERS = 'FILTERS';
diff --git a/src/Mustache/LambdaHelper.php b/src/Mustache/LambdaHelper.php
index de48fd6..cb8e966 100644
--- a/src/Mustache/LambdaHelper.php
+++ b/src/Mustache/LambdaHelper.php
@@ -20,17 +20,20 @@ class Mustache_LambdaHelper
{
private $mustache;
private $context;
+ private $delims;
/**
* Mustache Lambda Helper constructor.
*
* @param Mustache_Engine $mustache Mustache engine instance.
* @param Mustache_Context $context Rendering context.
+ * @param string $delims Optional custom delimiters, in the format `{{= <% %> =}}`. (default: null)
*/
- public function __construct(Mustache_Engine $mustache, Mustache_Context $context)
+ public function __construct(Mustache_Engine $mustache, Mustache_Context $context, $delims = null)
{
$this->mustache = $mustache;
$this->context = $context;
+ $this->delims = $delims;
}
/**
@@ -43,7 +46,31 @@ class Mustache_LambdaHelper
public function render($string)
{
return $this->mustache
- ->loadLambda((string) $string)
+ ->loadLambda((string) $string, $this->delims)
->renderInternal($this->context);
}
+
+ /**
+ * Render a string as a Mustache template with the current rendering context.
+ *
+ * @param string $string
+ *
+ * @return string Rendered template
+ */
+ public function __invoke($string)
+ {
+ return $this->render($string);
+ }
+
+ /**
+ * Get a Lambda Helper with custom delimiters.
+ *
+ * @param string $delims Custom delimiters, in the format `{{= <% %> =}}`.
+ *
+ * @return Mustache_LambdaHelper
+ */
+ public function withDelimiters($delims)
+ {
+ return new self($this->mustache, $this->context, $delims);
+ }
}
diff --git a/src/Mustache/Template.php b/src/Mustache/Template.php
index 91074c4..f2d198f 100644
--- a/src/Mustache/Template.php
+++ b/src/Mustache/Template.php
@@ -164,16 +164,15 @@ abstract class Mustache_Template
*
* @param mixed $value
* @param Mustache_Context $context
- * @param string $indent
*
* @return string
*/
- protected function resolveValue($value, Mustache_Context $context, $indent = '')
+ protected function resolveValue($value, Mustache_Context $context)
{
if (($this->strictCallables ? is_object($value) : !is_string($value)) && is_callable($value)) {
return $this->mustache
->loadLambda((string) call_user_func($value))
- ->renderInternal($context, $indent);
+ ->renderInternal($context);
}
return $value;
diff --git a/test/Mustache/Test/CompilerTest.php b/test/Mustache/Test/CompilerTest.php
index d981249..e11bd98 100644
--- a/test/Mustache/Test/CompilerTest.php
+++ b/test/Mustache/Test/CompilerTest.php
@@ -55,7 +55,7 @@ class Mustache_Test_CompilerTest extends PHPUnit_Framework_TestCase
'ISO-8859-1',
array(
"\nclass Monkey extends Mustache_Template",
- '$value = $this->resolveValue($context->find(\'name\'), $context, $indent);',
+ '$value = $this->resolveValue($context->find(\'name\'), $context);',
'$buffer .= $indent . call_user_func($this->mustache->getEscape(), $value);',
'return $buffer;',
),
@@ -75,7 +75,7 @@ class Mustache_Test_CompilerTest extends PHPUnit_Framework_TestCase
'ISO-8859-1',
array(
"\nclass Monkey extends Mustache_Template",
- '$value = $this->resolveValue($context->find(\'name\'), $context, $indent);',
+ '$value = $this->resolveValue($context->find(\'name\'), $context);',
'$buffer .= $indent . htmlspecialchars($value, ' . ENT_COMPAT . ', \'ISO-8859-1\');',
'return $buffer;',
),
@@ -95,7 +95,7 @@ class Mustache_Test_CompilerTest extends PHPUnit_Framework_TestCase
'ISO-8859-1',
array(
"\nclass Monkey extends Mustache_Template",
- '$value = $this->resolveValue($context->find(\'name\'), $context, $indent);',
+ '$value = $this->resolveValue($context->find(\'name\'), $context);',
'$buffer .= $indent . htmlspecialchars($value, ' . ENT_QUOTES . ', \'ISO-8859-1\');',
'return $buffer;',
),
@@ -122,9 +122,9 @@ class Mustache_Test_CompilerTest extends PHPUnit_Framework_TestCase
array(
"\nclass Monkey extends Mustache_Template",
"\$buffer .= \$indent . 'foo\n';",
- '$value = $this->resolveValue($context->find(\'name\'), $context, $indent);',
+ '$value = $this->resolveValue($context->find(\'name\'), $context);',
'$buffer .= htmlspecialchars($value, ' . ENT_COMPAT . ', \'UTF-8\');',
- '$value = $this->resolveValue($context->last(), $context, $indent);',
+ '$value = $this->resolveValue($context->last(), $context);',
'$buffer .= \'\\\'bar\\\'\';',
'return $buffer;',
),
diff --git a/test/Mustache/Test/FiveThree/Functional/LambdaHelperTest.php b/test/Mustache/Test/FiveThree/Functional/LambdaHelperTest.php
index fcc1cd9..48f2465 100644
--- a/test/Mustache/Test/FiveThree/Functional/LambdaHelperTest.php
+++ b/test/Mustache/Test/FiveThree/Functional/LambdaHelperTest.php
@@ -36,4 +36,32 @@ class Mustache_Test_FiveThree_Functional_LambdaHelperTest extends PHPUnit_Framew
$this->assertEquals('Mario', $one->render($foo));
$this->assertEquals('MARIO', $two->render($foo));
}
+
+ public function testSectionLambdaHelperRespectsDelimiterChanges()
+ {
+ $tpl = $this->mustache->loadTemplate("{{=<% %>=}}\n<%# bang %><% value %><%/ bang %>");
+
+ $data = new StdClass();
+ $data->value = 'hello world';
+ $data->bang = function ($text, $mustache) {
+ return $mustache->render($text) . '!';
+ };
+
+ $this->assertEquals('hello world!', $tpl->render($data));
+ }
+
+ public function testLambdaHelperIsInvokable()
+ {
+ $one = $this->mustache->loadTemplate('{{name}}');
+ $two = $this->mustache->loadTemplate('{{#lambda}}{{name}}{{/lambda}}');
+
+ $foo = new StdClass();
+ $foo->name = 'Mario';
+ $foo->lambda = function ($text, $render) {
+ return strtoupper($render($text));
+ };
+
+ $this->assertEquals('Mario', $one->render($foo));
+ $this->assertEquals('MARIO', $two->render($foo));
+ }
}
diff --git a/test/Mustache/Test/FiveThree/Functional/PartialLambdaIndentTest.php b/test/Mustache/Test/FiveThree/Functional/PartialLambdaIndentTest.php
index 1ed93b6..8fcfc04 100644
--- a/test/Mustache/Test/FiveThree/Functional/PartialLambdaIndentTest.php
+++ b/test/Mustache/Test/FiveThree/Functional/PartialLambdaIndentTest.php
@@ -33,6 +33,36 @@ EOS;
+EOS;
+
+ $m = new Mustache_Engine(array(
+ 'partials' => array('input' => $partial),
+ ));
+
+ $tpl = $m->loadTemplate($src);
+
+ $data = new Mustache_Test_FiveThree_Functional_ClassWithLambda();
+ $this->assertEquals($expected, $tpl->render($data));
+ }
+
+ public function testLambdaInterpolationsInsidePartialsAreIndentedProperly()
+ {
+ $src = <<
+ {{> input }}
+
+
+EOS;
+ $partial = <<
+
+EOS;
+
+ $expected = <<
+
+
+
EOS;
$m = new Mustache_Engine(array(
@@ -54,4 +84,11 @@ class Mustache_Test_FiveThree_Functional_ClassWithLambda
return strtoupper($val);
};
}
+
+ public function placeholder()
+ {
+ return function () {
+ return 'Enter your name';
+ };
+ }
}