Merge remote-tracking branch 'damyon/PULL_264' into dev

This commit is contained in:
Justin Hileman
2015-07-18 01:11:59 -07:00
2 changed files with 93 additions and 11 deletions
+41 -10
View File
@@ -19,6 +19,7 @@ class Mustache_Compiler
private $pragmas; private $pragmas;
private $defaultPragmas = array(); private $defaultPragmas = array();
private $sections; private $sections;
private $blocks;
private $source; private $source;
private $indentNextLine; private $indentNextLine;
private $customEscape; private $customEscape;
@@ -43,6 +44,7 @@ class Mustache_Compiler
{ {
$this->pragmas = $this->defaultPragmas; $this->pragmas = $this->defaultPragmas;
$this->sections = array(); $this->sections = array();
$this->blocks = array();
$this->source = $source; $this->source = $source;
$this->indentNextLine = true; $this->indentNextLine = true;
$this->customEscape = $customEscape; $this->customEscape = $customEscape;
@@ -195,6 +197,7 @@ class Mustache_Compiler
return $buffer; return $buffer;
} }
%s %s
%s
}'; }';
const KLASS_NO_LAMBDAS = '<?php const KLASS_NO_LAMBDAS = '<?php
@@ -225,17 +228,18 @@ class Mustache_Compiler
{ {
$code = $this->walk($tree); $code = $this->walk($tree);
$sections = implode("\n", $this->sections); $sections = implode("\n", $this->sections);
$klass = empty($this->sections) ? self::KLASS_NO_LAMBDAS : self::KLASS; $blocks = implode("\n", $this->blocks);
$klass = empty($this->sections) && empty($this->blocks) ? self::KLASS_NO_LAMBDAS : self::KLASS;
$callable = $this->strictCallables ? $this->prepare(self::STRICT_CALLABLE) : ''; $callable = $this->strictCallables ? $this->prepare(self::STRICT_CALLABLE) : '';
return sprintf($this->prepare($klass, 0, false, true), $name, $callable, $code, $sections); return sprintf($this->prepare($klass, 0, false, true), $name, $callable, $code, $sections, $blocks);
} }
const BLOCK_VAR = ' const BLOCK_VAR = '
$value = $this->resolveValue($context->findInBlock(%s), $context, $indent); $blockFunction = $context->findInBlock(%s);
if ($value && !is_array($value) && !is_object($value)) { if (is_callable($blockFunction)) {
$buffer .= $value; $buffer .= call_user_func($blockFunction, $context);
} else { } else {
%s %s
} }
@@ -258,13 +262,12 @@ class Mustache_Compiler
{ {
$id = var_export($id, true); $id = var_export($id, true);
return sprintf($this->prepare(self::BLOCK_VAR, $level), $id, $this->walk($nodes, 2)); return sprintf($this->prepare(self::BLOCK_VAR, $level), $id, $this->walk($nodes, $level));
} }
const BLOCK_ARG = ' const BLOCK_ARG = '
// %s block_arg // %s block_arg
$value = $this->section%s($context, \'\', true); $newContext[%s] = array($this, \'block%s\');
$newContext[%s] = %s$value;
'; ';
/** /**
@@ -282,10 +285,38 @@ class Mustache_Compiler
*/ */
private function blockArg($nodes, $id, $start, $end, $otag, $ctag, $level) private function blockArg($nodes, $id, $start, $end, $otag, $ctag, $level)
{ {
$key = $this->section($nodes, $id, array(), $start, $end, $otag, $ctag, $level, true); $key = $this->block($nodes);
$keystr = var_export($key, true);
$id = var_export($id, true); $id = var_export($id, true);
return sprintf($this->prepare(self::BLOCK_ARG, $level), $id, $key, $id, $this->flushIndent()); return sprintf($this->prepare(self::BLOCK_ARG, 1), $keystr, $id, $key);
}
const BLOCK_FUNCTION = 'public function block%s($context) {
$indent = $buffer = \'\';
%s
return $buffer;
}';
/**
* Generate Mustache Template inheritance block function PHP source.
*
* @param array $nodes Array of child tokens
*
* @return string key of new block function
*/
private function block($nodes)
{
$code = $this->walk($nodes, 1);
$key = ucfirst(md5($code));
if (!isset($this->blocks[$key])) {
$this->blocks[$key] = sprintf($this->prepare(self::BLOCK_FUNCTION, 1), $key, $code);
}
return $key;
} }
const SECTION_CALL = ' const SECTION_CALL = '
@@ -433,6 +433,57 @@ class Mustache_Test_Functional_InheritanceTest extends PHPUnit_Framework_TestCas
$this->assertEquals('default content', $tpl->render($data)); $this->assertEquals('default content', $tpl->render($data));
} }
public function testInheritanceWithLazyEvaluation()
{
$partials = array(
'parent' => '{{#items}}{{$value}}ignored{{/value}}{{/items}}',
);
$this->mustache->setPartials($partials);
$tpl = $this->mustache->loadTemplate(
'{{<parent}}{{$value}}<{{ . }}>{{/value}}{{/parent}}'
);
$data = array('items' => array(1, 2, 3));
$this->assertEquals('<1><2><3>', $tpl->render($data));
}
public function testInheritanceWithLazyEvaluationWhitespaceIgnored()
{
$partials = array(
'parent' => '{{#items}}{{$value}}\n\nignored\n\n{{/value}}{{/items}}',
);
$this->mustache->setPartials($partials);
$tpl = $this->mustache->loadTemplate(
'{{<parent}}\n\n\n{{$value}}<{{ . }}>{{/value}}\n\n{{/parent}}'
);
$data = array('items' => array(1, 2, 3));
$this->assertEquals('<1><2><3>', $tpl->render($data));
}
public function testInheritanceWithLazyEvaluationAndSections()
{
$partials = array(
'parent' => '{{#items}}{{$value}}\n\nignored {{.}} {{#more}} there is more {{/more}}\n\n{{/value}}{{/items}}',
);
$this->mustache->setPartials($partials);
$tpl = $this->mustache->loadTemplate(
'{{<parent}}\n\n\n{{$value}}<{{ . }}>{{#more}} there is less {{/more}}{{/value}}\n\n{{/parent}}'
);
$data = array('items' => array(1, 2, 3), 'more' => 'stuff');
$this->assertEquals('<1> there is less <2> there is less <3> there is less ', $tpl->render($data));
}
/** /**
* @dataProvider getIllegalInheritanceExamples * @dataProvider getIllegalInheritanceExamples
* @expectedException Mustache_Exception_SyntaxException * @expectedException Mustache_Exception_SyntaxException