Merge remote-tracking branch 'jazzdan/dev' into feature/template-inheritance
Conflicts: src/Mustache/Compiler.php test/Mustache/Test/TokenizerTest.php
This commit is contained in:
+114
-8
@@ -16,6 +16,8 @@
|
|||||||
*/
|
*/
|
||||||
class Mustache_Compiler
|
class Mustache_Compiler
|
||||||
{
|
{
|
||||||
|
|
||||||
|
private $pragmas;
|
||||||
private $sections;
|
private $sections;
|
||||||
private $source;
|
private $source;
|
||||||
private $indentNextLine;
|
private $indentNextLine;
|
||||||
@@ -23,7 +25,6 @@ class Mustache_Compiler
|
|||||||
private $entityFlags;
|
private $entityFlags;
|
||||||
private $charset;
|
private $charset;
|
||||||
private $strictCallables;
|
private $strictCallables;
|
||||||
private $pragmas;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compile a Mustache token parse tree into PHP source code.
|
* Compile a Mustache token parse tree into PHP source code.
|
||||||
@@ -93,7 +94,6 @@ class Mustache_Compiler
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case Mustache_Tokenizer::T_PARTIAL:
|
case Mustache_Tokenizer::T_PARTIAL:
|
||||||
case Mustache_Tokenizer::T_PARTIAL_2:
|
|
||||||
$code .= $this->partial(
|
$code .= $this->partial(
|
||||||
$node[Mustache_Tokenizer::NAME],
|
$node[Mustache_Tokenizer::NAME],
|
||||||
isset($node[Mustache_Tokenizer::INDENT]) ? $node[Mustache_Tokenizer::INDENT] : '',
|
isset($node[Mustache_Tokenizer::INDENT]) ? $node[Mustache_Tokenizer::INDENT] : '',
|
||||||
@@ -101,6 +101,39 @@ class Mustache_Compiler
|
|||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case Mustache_Tokenizer::T_PARENT:
|
||||||
|
$code .= $this->parent(
|
||||||
|
$node[Mustache_Tokenizer::NAME],
|
||||||
|
isset($node[Mustache_Tokenizer::INDENT]) ? $node[Mustache_Tokenizer::INDENT] : '',
|
||||||
|
$level,
|
||||||
|
$node[Mustache_Tokenizer::NODES]
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Mustache_Tokenizer::T_BLOCK_ARG:
|
||||||
|
$code .= $this->blockArg(
|
||||||
|
$node[Mustache_Tokenizer::NODES],
|
||||||
|
$node[Mustache_Tokenizer::NAME],
|
||||||
|
$node[Mustache_Tokenizer::INDEX],
|
||||||
|
$node[Mustache_Tokenizer::END],
|
||||||
|
$node[Mustache_Tokenizer::OTAG],
|
||||||
|
$node[Mustache_Tokenizer::CTAG],
|
||||||
|
$level
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Mustache_Tokenizer::T_BLOCK_VAR:
|
||||||
|
$code .= $this->blockVar(
|
||||||
|
$node[Mustache_Tokenizer::NODES],
|
||||||
|
$node[Mustache_Tokenizer::NAME],
|
||||||
|
$node[Mustache_Tokenizer::INDEX],
|
||||||
|
$node[Mustache_Tokenizer::END],
|
||||||
|
$node[Mustache_Tokenizer::OTAG],
|
||||||
|
$node[Mustache_Tokenizer::CTAG],
|
||||||
|
$level
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
|
||||||
case Mustache_Tokenizer::T_UNESCAPED:
|
case Mustache_Tokenizer::T_UNESCAPED:
|
||||||
case Mustache_Tokenizer::T_UNESCAPED_2:
|
case Mustache_Tokenizer::T_UNESCAPED_2:
|
||||||
$code .= $this->variable($node[Mustache_Tokenizer::NAME], false, $level);
|
$code .= $this->variable($node[Mustache_Tokenizer::NAME], false, $level);
|
||||||
@@ -121,7 +154,6 @@ class Mustache_Compiler
|
|||||||
throw new Mustache_Exception_SyntaxException(sprintf('Unknown token type: %s', $node[Mustache_Tokenizer::TYPE]), $node);
|
throw new Mustache_Exception_SyntaxException(sprintf('Unknown token type: %s', $node[Mustache_Tokenizer::TYPE]), $node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $code;
|
return $code;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,6 +167,7 @@ class Mustache_Compiler
|
|||||||
{
|
{
|
||||||
$this->lambdaHelper = new Mustache_LambdaHelper($this->mustache, $context);
|
$this->lambdaHelper = new Mustache_LambdaHelper($this->mustache, $context);
|
||||||
$buffer = \'\';
|
$buffer = \'\';
|
||||||
|
$newContext = array();
|
||||||
%s
|
%s
|
||||||
|
|
||||||
return $buffer;
|
return $buffer;
|
||||||
@@ -149,6 +182,7 @@ class Mustache_Compiler
|
|||||||
public function renderInternal(Mustache_Context $context, $indent = \'\')
|
public function renderInternal(Mustache_Context $context, $indent = \'\')
|
||||||
{
|
{
|
||||||
$buffer = \'\';
|
$buffer = \'\';
|
||||||
|
$newContext = array();
|
||||||
%s
|
%s
|
||||||
|
|
||||||
return $buffer;
|
return $buffer;
|
||||||
@@ -170,11 +204,49 @@ 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;
|
$klass = empty($this->sections) ? 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const BLOCK_VAR = '
|
||||||
|
$value = $this->resolveValue($context->findInBlock(%s), $context, $indent);
|
||||||
|
if($value && !is_array($value) && !is_object($value)) {
|
||||||
|
$buffer .= $value;
|
||||||
|
} else {
|
||||||
|
%s
|
||||||
|
}
|
||||||
|
';
|
||||||
|
|
||||||
|
private function blockVar($nodes, $id, $start, $end, $otag, $ctag, $level)
|
||||||
|
{
|
||||||
|
$id_str = var_export($id, true);
|
||||||
|
|
||||||
|
return sprintf($this->prepare(self::BLOCK_VAR, $level), $id_str, $this->walk($nodes, 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
const BLOCK_ARG = '
|
||||||
|
// %s block_arg
|
||||||
|
$value = $this->section%s($context, $indent, true);
|
||||||
|
$newContext[%s] = %s$value;
|
||||||
|
';
|
||||||
|
|
||||||
|
private function blockArg($nodes, $id, $start, $end, $otag, $ctag, $level)
|
||||||
|
{
|
||||||
|
$key = $this->section($nodes, $id, $start, $end, $otag, $ctag, $level, true);
|
||||||
|
$filters = '';
|
||||||
|
|
||||||
|
if (isset($this->pragmas[Mustache_Engine::PRAGMA_FILTERS])) {
|
||||||
|
list($id, $filters) = $this->getFilters($id, $level);
|
||||||
|
}
|
||||||
|
|
||||||
|
$method = $this->getFindMethod($id);
|
||||||
|
$id = var_export($id, true);
|
||||||
|
|
||||||
|
return sprintf($this->prepare(self::BLOCK_ARG, $level), $id, $key, $id, $this->flushIndent());
|
||||||
|
}
|
||||||
|
|
||||||
const SECTION_CALL = '
|
const SECTION_CALL = '
|
||||||
// %s section
|
// %s section
|
||||||
$value = $context->%s(%s);%s
|
$value = $context->%s(%s);%s
|
||||||
@@ -198,7 +270,8 @@ class Mustache_Compiler
|
|||||||
} elseif (!empty($value)) {
|
} elseif (!empty($value)) {
|
||||||
$values = $this->isIterable($value) ? $value : array($value);
|
$values = $this->isIterable($value) ? $value : array($value);
|
||||||
foreach ($values as $value) {
|
foreach ($values as $value) {
|
||||||
$context->push($value);%s
|
$context->push($value);
|
||||||
|
%s
|
||||||
$context->pop();
|
$context->pop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -219,7 +292,7 @@ class Mustache_Compiler
|
|||||||
*
|
*
|
||||||
* @return string Generated section PHP source code
|
* @return string Generated section PHP source code
|
||||||
*/
|
*/
|
||||||
private function section($nodes, $id, $start, $end, $otag, $ctag, $level)
|
private function section($nodes, $id, $start, $end, $otag, $ctag, $level, $arg=false)
|
||||||
{
|
{
|
||||||
$filters = '';
|
$filters = '';
|
||||||
|
|
||||||
@@ -227,8 +300,6 @@ class Mustache_Compiler
|
|||||||
list($id, $filters) = $this->getFilters($id, $level);
|
list($id, $filters) = $this->getFilters($id, $level);
|
||||||
}
|
}
|
||||||
|
|
||||||
$method = $this->getFindMethod($id);
|
|
||||||
$id = var_export($id, true);
|
|
||||||
$source = var_export(substr($this->source, $start, $end - $start), true);
|
$source = var_export(substr($this->source, $start, $end - $start), true);
|
||||||
$callable = $this->getCallable();
|
$callable = $this->getCallable();
|
||||||
|
|
||||||
@@ -244,7 +315,13 @@ class Mustache_Compiler
|
|||||||
$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, $delims, $this->walk($nodes, 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
return sprintf($this->prepare(self::SECTION_CALL, $level), $id, $method, $id, $filters, $key);
|
if ($arg === true) {
|
||||||
|
return $key;
|
||||||
|
} else {
|
||||||
|
$method = $this->getFindMethod($id);
|
||||||
|
$id = var_export($id, true);
|
||||||
|
return sprintf($this->prepare(self::SECTION_CALL, $level), $id, $method, $id, $filters, $key);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const INVERTED_SECTION = '
|
const INVERTED_SECTION = '
|
||||||
@@ -301,6 +378,35 @@ class Mustache_Compiler
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const PARENT = '
|
||||||
|
|
||||||
|
if ($parent = $this->mustache->LoadPartial(%s)) {
|
||||||
|
$context->pushBlockContext($newContext);
|
||||||
|
$buffer .= $parent->renderInternal($context, $indent);
|
||||||
|
$context->popBlockContext();
|
||||||
|
}
|
||||||
|
';
|
||||||
|
|
||||||
|
private function parent($id, $indent, $level, $children)
|
||||||
|
{
|
||||||
|
$block = '';
|
||||||
|
|
||||||
|
$real_children = array_filter($children, array(__CLASS__, 'return_only_block_args'));
|
||||||
|
|
||||||
|
$block = $this->walk($real_children, $level);
|
||||||
|
|
||||||
|
return $block. sprintf(
|
||||||
|
$this->prepare(self::PARENT, $level),
|
||||||
|
var_export($id, true),
|
||||||
|
var_export($indent, true)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function return_only_block_args($child)
|
||||||
|
{
|
||||||
|
return $child[Mustache_Tokenizer::TYPE] == Mustache_Tokenizer::T_BLOCK_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
const VARIABLE = '
|
const VARIABLE = '
|
||||||
$value = $this->resolveValue($context->%s(%s), $context, $indent);%s
|
$value = $this->resolveValue($context->%s(%s), $context, $indent);%s
|
||||||
$buffer .= %s%s;
|
$buffer .= %s%s;
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
class Mustache_Context
|
class Mustache_Context
|
||||||
{
|
{
|
||||||
private $stack = array();
|
private $stack = array();
|
||||||
|
private $block_stack = array();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mustache rendering Context constructor.
|
* Mustache rendering Context constructor.
|
||||||
@@ -38,6 +39,11 @@ class Mustache_Context
|
|||||||
array_push($this->stack, $value);
|
array_push($this->stack, $value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function pushBlockContext($value)
|
||||||
|
{
|
||||||
|
array_push($this->block_stack, $value);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pop the last Context frame from the stack.
|
* Pop the last Context frame from the stack.
|
||||||
*
|
*
|
||||||
@@ -48,6 +54,11 @@ class Mustache_Context
|
|||||||
return array_pop($this->stack);
|
return array_pop($this->stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function popBlockContext()
|
||||||
|
{
|
||||||
|
return array_pop($this->block_stack);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the last Context frame.
|
* Get the last Context frame.
|
||||||
*
|
*
|
||||||
@@ -120,6 +131,17 @@ class Mustache_Context
|
|||||||
return $value;
|
return $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function findInBlock($id)
|
||||||
|
{
|
||||||
|
foreach($this->block_stack as $context) {
|
||||||
|
if (array_key_exists($id, $context)) {
|
||||||
|
return $context[$id];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper function to find a variable in the Context stack.
|
* Helper function to find a variable in the Context stack.
|
||||||
*
|
*
|
||||||
|
|||||||
+24
-2
@@ -60,11 +60,13 @@ class Mustache_Parser
|
|||||||
|
|
||||||
switch ($token[Mustache_Tokenizer::TYPE]) {
|
switch ($token[Mustache_Tokenizer::TYPE]) {
|
||||||
case Mustache_Tokenizer::T_DELIM_CHANGE:
|
case Mustache_Tokenizer::T_DELIM_CHANGE:
|
||||||
|
$this->checkIfTokenIsAllowedInParent($parent, $token);
|
||||||
$this->clearStandaloneLines($nodes, $tokens);
|
$this->clearStandaloneLines($nodes, $tokens);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Mustache_Tokenizer::T_SECTION:
|
case Mustache_Tokenizer::T_SECTION:
|
||||||
case Mustache_Tokenizer::T_INVERTED:
|
case Mustache_Tokenizer::T_INVERTED:
|
||||||
|
$this->checkIfTokenIsAllowedInParent($parent, $token);
|
||||||
$this->clearStandaloneLines($nodes, $tokens);
|
$this->clearStandaloneLines($nodes, $tokens);
|
||||||
$nodes[] = $this->buildTree($tokens, $token);
|
$nodes[] = $this->buildTree($tokens, $token);
|
||||||
break;
|
break;
|
||||||
@@ -97,14 +99,27 @@ class Mustache_Parser
|
|||||||
return $parent;
|
return $parent;
|
||||||
|
|
||||||
case Mustache_Tokenizer::T_PARTIAL:
|
case Mustache_Tokenizer::T_PARTIAL:
|
||||||
case Mustache_Tokenizer::T_PARTIAL_2:
|
$this->checkIfTokenIsAllowedInParent($parent, $token);
|
||||||
// store the whitespace prefix for laters!
|
//store the whitespace prefix for laters!
|
||||||
if ($indent = $this->clearStandaloneLines($nodes, $tokens)) {
|
if ($indent = $this->clearStandaloneLines($nodes, $tokens)) {
|
||||||
$token[Mustache_Tokenizer::INDENT] = $indent[Mustache_Tokenizer::VALUE];
|
$token[Mustache_Tokenizer::INDENT] = $indent[Mustache_Tokenizer::VALUE];
|
||||||
}
|
}
|
||||||
$nodes[] = $token;
|
$nodes[] = $token;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case Mustache_Tokenizer::T_PARENT:
|
||||||
|
$this->checkIfTokenIsAllowedInParent($parent, $token);
|
||||||
|
$nodes[] = $this->buildTree($tokens, $token);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Mustache_Tokenizer::T_BLOCK_VAR:
|
||||||
|
if ($parent[Mustache_Tokenizer::TYPE] === Mustache_Tokenizer::T_PARENT) {
|
||||||
|
$token[Mustache_Tokenizer::TYPE] = Mustache_Tokenizer::T_BLOCK_ARG;
|
||||||
|
}
|
||||||
|
$this->clearStandaloneLines($nodes, $tokens);
|
||||||
|
$nodes[] = $this->buildTree($tokens, $token);
|
||||||
|
break;
|
||||||
|
|
||||||
case Mustache_Tokenizer::T_PRAGMA:
|
case Mustache_Tokenizer::T_PRAGMA:
|
||||||
case Mustache_Tokenizer::T_COMMENT:
|
case Mustache_Tokenizer::T_COMMENT:
|
||||||
$this->clearStandaloneLines($nodes, $tokens);
|
$this->clearStandaloneLines($nodes, $tokens);
|
||||||
@@ -203,4 +218,11 @@ class Mustache_Parser
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function checkIfTokenIsAllowedInParent($parent, $token)
|
||||||
|
{
|
||||||
|
if ($parent[Mustache_Tokenizer::TYPE] === Mustache_Tokenizer::T_PARENT) {
|
||||||
|
throw new Mustache_Exception_SyntaxException('Illegal content in < parent tag', $token);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,7 +63,9 @@ abstract class Mustache_Template
|
|||||||
*/
|
*/
|
||||||
public function render($context = array())
|
public function render($context = array())
|
||||||
{
|
{
|
||||||
return $this->renderInternal($this->prepareContextStack($context));
|
return $this->renderInternal(
|
||||||
|
$this->prepareContextStack($context)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -27,13 +27,15 @@ class Mustache_Tokenizer
|
|||||||
const T_END_SECTION = '/';
|
const T_END_SECTION = '/';
|
||||||
const T_COMMENT = '!';
|
const T_COMMENT = '!';
|
||||||
const T_PARTIAL = '>';
|
const T_PARTIAL = '>';
|
||||||
const T_PARTIAL_2 = '<';
|
const T_PARENT = '<';
|
||||||
const T_DELIM_CHANGE = '=';
|
const T_DELIM_CHANGE = '=';
|
||||||
const T_ESCAPED = '_v';
|
const T_ESCAPED = '_v';
|
||||||
const T_UNESCAPED = '{';
|
const T_UNESCAPED = '{';
|
||||||
const T_UNESCAPED_2 = '&';
|
const T_UNESCAPED_2 = '&';
|
||||||
const T_TEXT = '_t';
|
const T_TEXT = '_t';
|
||||||
const T_PRAGMA = '%';
|
const T_PRAGMA = '%';
|
||||||
|
const T_BLOCK_VAR = '$';
|
||||||
|
const T_BLOCK_ARG = '$arg';
|
||||||
|
|
||||||
// Valid token types
|
// Valid token types
|
||||||
private static $tagTypes = array(
|
private static $tagTypes = array(
|
||||||
@@ -42,12 +44,13 @@ class Mustache_Tokenizer
|
|||||||
self::T_END_SECTION => true,
|
self::T_END_SECTION => true,
|
||||||
self::T_COMMENT => true,
|
self::T_COMMENT => true,
|
||||||
self::T_PARTIAL => true,
|
self::T_PARTIAL => true,
|
||||||
self::T_PARTIAL_2 => true,
|
self::T_PARENT => true,
|
||||||
self::T_DELIM_CHANGE => true,
|
self::T_DELIM_CHANGE => true,
|
||||||
self::T_ESCAPED => true,
|
self::T_ESCAPED => true,
|
||||||
self::T_UNESCAPED => true,
|
self::T_UNESCAPED => true,
|
||||||
self::T_UNESCAPED_2 => true,
|
self::T_UNESCAPED_2 => true,
|
||||||
self::T_PRAGMA => true,
|
self::T_PRAGMA => true,
|
||||||
|
self::T_BLOCK_VAR => true,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Interpolated tags
|
// Interpolated tags
|
||||||
|
|||||||
@@ -0,0 +1,437 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group inheritance
|
||||||
|
* @group functional
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Mustache_Test_Functional_InheritanceTest extends PHPUnit_Framework_TestCase
|
||||||
|
{
|
||||||
|
private $mustache;
|
||||||
|
|
||||||
|
public function setUp()
|
||||||
|
{
|
||||||
|
$this->mustache = new Mustache_Engine;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getIllegalInheritanceExamples()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
array(
|
||||||
|
array(
|
||||||
|
'foo' => '{{$baz}}default content{{/baz}}',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'bar' => 'set by user'
|
||||||
|
),
|
||||||
|
'{{< foo }}{{# bar }}{{$ baz }}{{/ baz }}{{/ bar }}{{/ foo }}',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
array(
|
||||||
|
'foo' => '{{$baz}}default content{{/baz}}'
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
),
|
||||||
|
'{{<foo}}{{^bar}}{{$baz}}set by template{{/baz}}{{/bar}}{{/foo}}',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
array(
|
||||||
|
'foo' => '{{$baz}}default content{{/baz}}',
|
||||||
|
'qux' => 'I am a partial'
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
),
|
||||||
|
'{{<foo}}{{>qux}}{{$baz}}set by template{{/baz}}{{/foo}}'
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
array(
|
||||||
|
'foo' => '{{$baz}}default content{{/baz}}'
|
||||||
|
),
|
||||||
|
array(),
|
||||||
|
'{{<foo}}{{=<% %>=}}<%={{ }}=%>{{/foo}}'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getLegalInheritanceExamples()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
array(
|
||||||
|
array(
|
||||||
|
'foo' => '{{$baz}}default content{{/baz}}',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'bar' => 'set by user'
|
||||||
|
),
|
||||||
|
'{{<foo}}{{bar}}{{$baz}}override{{/baz}}{{/foo}}',
|
||||||
|
'override'
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
array(
|
||||||
|
'foo' => '{{$baz}}default content{{/baz}}'
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
),
|
||||||
|
'{{<foo}}{{! ignore me }}{{$baz}}set by template{{/baz}}{{/foo}}',
|
||||||
|
'set by template'
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
array(
|
||||||
|
'foo' => '{{$baz}}defualt content{{/baz}}'
|
||||||
|
),
|
||||||
|
array(),
|
||||||
|
'{{<foo}}set by template{{$baz}}also set by template{{/baz}}{{/foo}}',
|
||||||
|
'also set by template'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testDefaultContent()
|
||||||
|
{
|
||||||
|
$tpl = $this->mustache->loadTemplate('{{$title}}Default title{{/title}}');
|
||||||
|
|
||||||
|
$data = array();
|
||||||
|
|
||||||
|
$this->assertEquals('Default title', $tpl->render($data));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testDefaultContentRendersVariables()
|
||||||
|
{
|
||||||
|
$tpl = $this->mustache->loadTemplate('{{$foo}}default {{bar}} content{{/foo}}');
|
||||||
|
|
||||||
|
$data = array(
|
||||||
|
'bar' => 'baz'
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertEquals('default baz content', $tpl->render($data));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testDefaultContentRendersTripleMustacheVariables()
|
||||||
|
{
|
||||||
|
$tpl = $this->mustache->loadTemplate('{{$foo}}default {{{bar}}} content{{/foo}}');
|
||||||
|
|
||||||
|
$data = array(
|
||||||
|
'bar' => '<baz>'
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertEquals('default <baz> content', $tpl->render($data));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testDefaultContentRendersSections()
|
||||||
|
{
|
||||||
|
$tpl = $this->mustache->loadTemplate(
|
||||||
|
'{{$foo}}default {{#bar}}{{baz}}{{/bar}} content{{/foo}}'
|
||||||
|
);
|
||||||
|
|
||||||
|
$data = array(
|
||||||
|
'bar' => array('baz' => 'qux')
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertEquals('default qux content', $tpl->render($data));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testDefaultContentRendersNegativeSections()
|
||||||
|
{
|
||||||
|
$tpl = $this->mustache->loadTemplate(
|
||||||
|
'{{$foo}}default {{^bar}}{{baz}}{{/bar}} content{{/foo}}'
|
||||||
|
);
|
||||||
|
|
||||||
|
$data = array(
|
||||||
|
'foo' => array('bar' => 'qux'),
|
||||||
|
'baz' => 'three'
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertEquals('default three content', $tpl->render($data));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testMustacheInjectionInDefaultContent()
|
||||||
|
{
|
||||||
|
$tpl = $this->mustache->loadTemplate(
|
||||||
|
'{{$foo}}default {{#bar}}{{baz}}{{/bar}} content{{/foo}}'
|
||||||
|
);
|
||||||
|
|
||||||
|
$data = array(
|
||||||
|
'bar' => array('baz' => '{{qux}}')
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertEquals('default {{qux}} content', $tpl->render($data));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testDefaultContentRenderedInsideIncludedTemplates()
|
||||||
|
{
|
||||||
|
$partials = array(
|
||||||
|
'include' => '{{$foo}}default content{{/foo}}'
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->mustache->setPartials($partials);
|
||||||
|
|
||||||
|
$tpl = $this->mustache->loadTemplate(
|
||||||
|
'{{<include}}{{/include}}'
|
||||||
|
);
|
||||||
|
|
||||||
|
$data = array();
|
||||||
|
|
||||||
|
$this->assertEquals('default content', $tpl->render($data));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testOverriddenContent()
|
||||||
|
{
|
||||||
|
$partials = array(
|
||||||
|
'super' => '...{{$title}}Default title{{/title}}...'
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->mustache->setPartials($partials);
|
||||||
|
|
||||||
|
$tpl = $this->mustache->loadTemplate(
|
||||||
|
'{{<super}}{{$title}}sub template title{{/title}}{{/super}}'
|
||||||
|
);
|
||||||
|
|
||||||
|
$data = array();
|
||||||
|
|
||||||
|
$this->assertEquals('...sub template title...', $tpl->render($data));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testOverriddenPartial()
|
||||||
|
{
|
||||||
|
$partials = array(
|
||||||
|
'partial' => '|{{$stuff}}...{{/stuff}}{{$default}} default{{/default}}|'
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->mustache->setPartials($partials);
|
||||||
|
|
||||||
|
$tpl = $this->mustache->loadTemplate(
|
||||||
|
'test {{<partial}}{{$stuff}}override1{{/stuff}}{{/partial}} {{<partial}}{{$stuff}}override2{{/stuff}}{{/partial}}'
|
||||||
|
);
|
||||||
|
|
||||||
|
$data = array();
|
||||||
|
|
||||||
|
$this->assertEquals('test |override1 default| |override2 default|', $tpl->render($data));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testDataDoesNotOverrideBlock()
|
||||||
|
{
|
||||||
|
$partials = array(
|
||||||
|
'include' => '{{$var}}var in include{{/var}}'
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->mustache->setPartials($partials);
|
||||||
|
|
||||||
|
$tpl = $this->mustache->loadTemplate(
|
||||||
|
'{{<include}}{{$var}}var in template{{/var}}{{/include}}'
|
||||||
|
);
|
||||||
|
|
||||||
|
$data = array(
|
||||||
|
'var' => 'var in data'
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertEquals('var in template', $tpl->render($data));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testDataDoesNotOverrideDefaultBlockValue()
|
||||||
|
{
|
||||||
|
$partials = array(
|
||||||
|
'include' => '{{$var}}var in include{{/var}}'
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->mustache->setPartials($partials);
|
||||||
|
|
||||||
|
$tpl = $this->mustache->loadTemplate(
|
||||||
|
'{{<include}}{{/include}}'
|
||||||
|
);
|
||||||
|
|
||||||
|
$data = array(
|
||||||
|
'var' => 'var in data'
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertEquals('var in include', $tpl->render($data));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testOverridePartialWithNewlines()
|
||||||
|
{
|
||||||
|
$partials = array(
|
||||||
|
'partial' => '{{$ballmer}}peaking{{/ballmer}}'
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->mustache->setPartials($partials);
|
||||||
|
|
||||||
|
$tpl = $this->mustache->loadTemplate(
|
||||||
|
"{{<partial}}{{\$ballmer}}\npeaked\n\n:(\n{{/ballmer}}{{/partial}}"
|
||||||
|
);
|
||||||
|
|
||||||
|
$data = array();
|
||||||
|
|
||||||
|
$this->assertEquals("peaked\n\n:(\n", $tpl->render($data));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testInheritIndentationWhenOverridingAPartial()
|
||||||
|
{
|
||||||
|
$partials = array(
|
||||||
|
'partial' =>
|
||||||
|
'stop:
|
||||||
|
{{$nineties}}collaborate and listen{{/nineties}}'
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->mustache->setPartials($partials);
|
||||||
|
|
||||||
|
$tpl = $this->mustache->loadTemplate(
|
||||||
|
'{{<partial}}{{$nineties}}hammer time{{/nineties}}{{/partial}}'
|
||||||
|
);
|
||||||
|
|
||||||
|
$data = array();
|
||||||
|
|
||||||
|
$this->assertEquals(
|
||||||
|
'stop:
|
||||||
|
hammer time',
|
||||||
|
$tpl->render($data)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testOverrideOneSubstitutionButNotTheOther()
|
||||||
|
{
|
||||||
|
$partials = array(
|
||||||
|
'partial' => '{{$stuff}}default one{{/stuff}}, {{$stuff2}}default two{{/stuff2}}'
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->mustache->setPartials($partials);
|
||||||
|
|
||||||
|
$tpl = $this->mustache->loadTemplate(
|
||||||
|
'{{<partial}}{{$stuff2}}override two{{/stuff2}}{{/partial}}'
|
||||||
|
);
|
||||||
|
|
||||||
|
$data = array();
|
||||||
|
|
||||||
|
$this->assertEquals('default one, override two', $tpl->render($data));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testSuperTemplatesWithNoParameters()
|
||||||
|
{
|
||||||
|
$partials = array(
|
||||||
|
'include' => '{{$foo}}default content{{/foo}}'
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->mustache->setPartials($partials);
|
||||||
|
|
||||||
|
$tpl = $this->mustache->loadTemplate(
|
||||||
|
'{{>include}}|{{<include}}{{/include}}'
|
||||||
|
);
|
||||||
|
|
||||||
|
$data = array();
|
||||||
|
|
||||||
|
$this->assertEquals('default content|default content', $tpl->render($data));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testRecursionInInheritedTemplates()
|
||||||
|
{
|
||||||
|
$partials = array(
|
||||||
|
'include' => '{{$foo}}default content{{/foo}} {{$bar}}{{<include2}}{{/include2}}{{/bar}}',
|
||||||
|
'include2' => '{{$foo}}include2 default content{{/foo}} {{<include}}{{$bar}}don\'t recurse{{/bar}}{{/include}}'
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->mustache->setPartials($partials);
|
||||||
|
|
||||||
|
$tpl = $this->mustache->loadTemplate(
|
||||||
|
'{{<include}}{{$foo}}override{{/foo}}{{/include}}'
|
||||||
|
);
|
||||||
|
|
||||||
|
$data = array();
|
||||||
|
|
||||||
|
$this->assertEquals('override override override don\'t recurse', $tpl->render($data));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testTopLevelSubstitutionsTakePrecedenceInMultilevelInheritance()
|
||||||
|
{
|
||||||
|
$partials = array(
|
||||||
|
'parent' => '{{<older}}{{$a}}p{{/a}}{{/older}}',
|
||||||
|
'older' => '{{<grandParent}}{{$a}}o{{/a}}{{/grandParent}}',
|
||||||
|
'grandParent' => '{{$a}}g{{/a}}'
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->mustache->setPartials($partials);
|
||||||
|
|
||||||
|
$tpl = $this->mustache->loadTemplate(
|
||||||
|
'{{<parent}}{{$a}}c{{/a}}{{/parent}}'
|
||||||
|
);
|
||||||
|
|
||||||
|
$data = array();
|
||||||
|
|
||||||
|
$this->assertEquals('c', $tpl->render($data));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testMultiLevelInheritanceNoSubChild()
|
||||||
|
{
|
||||||
|
$partials = array(
|
||||||
|
'parent' => '{{<older}}{{$a}}p{{/a}}{{/older}}',
|
||||||
|
'older' => '{{<grandParent}}{{$a}}o{{/a}}{{/grandParent}}',
|
||||||
|
'grandParent' => '{{$a}}g{{/a}}'
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->mustache->setPartials($partials);
|
||||||
|
|
||||||
|
$tpl = $this->mustache->loadTemplate(
|
||||||
|
'{{<parent}}{{/parent}}'
|
||||||
|
);
|
||||||
|
|
||||||
|
$data = array();
|
||||||
|
|
||||||
|
$this->assertEquals('p', $tpl->render($data));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testIgnoreTextInsideSuperTemplatesButParseArgs()
|
||||||
|
{
|
||||||
|
$partials = array(
|
||||||
|
'include' => '{{$foo}}default content{{/foo}}'
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->mustache->setPartials($partials);
|
||||||
|
|
||||||
|
$tpl = $this->mustache->loadTemplate(
|
||||||
|
'{{<include}} asdfasd {{$foo}}hmm{{/foo}} asdfasdfasdf {{/include}}'
|
||||||
|
);
|
||||||
|
|
||||||
|
$data = array();
|
||||||
|
|
||||||
|
$this->assertEquals('hmm', $tpl->render($data));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testIgnoreTextInsideSuperTemplates()
|
||||||
|
{
|
||||||
|
$partials = array(
|
||||||
|
'include' => '{{$foo}}default content{{/foo}}'
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->mustache->setPartials($partials);
|
||||||
|
|
||||||
|
$tpl = $this->mustache->loadTemplate(
|
||||||
|
'{{<include}} asdfasd asdfasdfasdf {{/include}}'
|
||||||
|
);
|
||||||
|
|
||||||
|
$data = array();
|
||||||
|
|
||||||
|
$this->assertEquals('default content', $tpl->render($data));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider getIllegalInheritanceExamples
|
||||||
|
* @expectedException Mustache_Exception_SyntaxException
|
||||||
|
* @expectedExceptionMessage Illegal content in < parent tag
|
||||||
|
*/
|
||||||
|
public function testIllegalInheritanceExamples($partials, $data, $template)
|
||||||
|
{
|
||||||
|
$this->mustache->setPartials($partials);
|
||||||
|
$tpl = $this->mustache->loadTemplate($template);
|
||||||
|
$tpl->render($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider getLegalInheritanceExamples
|
||||||
|
*/
|
||||||
|
public function testLegalInheritanceExamples($partials, $data, $template, $expect)
|
||||||
|
{
|
||||||
|
$this->mustache->setPartials($partials);
|
||||||
|
$tpl = $this->mustache->loadTemplate($template);
|
||||||
|
$this->assertSame($expect, $tpl->render($data));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -88,6 +88,7 @@ class Mustache_Test_ParserTest extends PHPUnit_Framework_TestCase
|
|||||||
Mustache_Tokenizer::VALUE => 'bar'
|
Mustache_Tokenizer::VALUE => 'bar'
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
array(
|
array(
|
||||||
array(
|
array(
|
||||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
|
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
|
||||||
@@ -116,6 +117,118 @@ class Mustache_Test_ParserTest extends PHPUnit_Framework_TestCase
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
|
array(
|
||||||
|
array(
|
||||||
|
array(
|
||||||
|
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_PARENT,
|
||||||
|
Mustache_Tokenizer::NAME => 'foo',
|
||||||
|
Mustache_Tokenizer::OTAG => '{{',
|
||||||
|
Mustache_Tokenizer::CTAG => '}}',
|
||||||
|
Mustache_Tokenizer::LINE => 0,
|
||||||
|
Mustache_Tokenizer::INDEX => 8
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_BLOCK_VAR,
|
||||||
|
Mustache_Tokenizer::NAME => 'bar',
|
||||||
|
Mustache_Tokenizer::OTAG => '{{',
|
||||||
|
Mustache_Tokenizer::CTAG => '}}',
|
||||||
|
Mustache_Tokenizer::LINE => 0,
|
||||||
|
Mustache_Tokenizer::INDEX => 16
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
|
||||||
|
Mustache_Tokenizer::LINE => 0,
|
||||||
|
Mustache_Tokenizer::VALUE => 'baz'
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_END_SECTION,
|
||||||
|
Mustache_Tokenizer::NAME => 'bar',
|
||||||
|
Mustache_Tokenizer::OTAG => '{{',
|
||||||
|
Mustache_Tokenizer::CTAG => '}}',
|
||||||
|
Mustache_Tokenizer::LINE => 0,
|
||||||
|
Mustache_Tokenizer::INDEX => 19
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_END_SECTION,
|
||||||
|
Mustache_Tokenizer::NAME => 'foo',
|
||||||
|
Mustache_Tokenizer::OTAG => '{{',
|
||||||
|
Mustache_Tokenizer::CTAG => '}}',
|
||||||
|
Mustache_Tokenizer::LINE => 0,
|
||||||
|
Mustache_Tokenizer::INDEX => 27
|
||||||
|
)
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
array(
|
||||||
|
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_PARENT,
|
||||||
|
Mustache_Tokenizer::NAME => 'foo',
|
||||||
|
Mustache_Tokenizer::OTAG => '{{',
|
||||||
|
Mustache_Tokenizer::CTAG => '}}',
|
||||||
|
Mustache_Tokenizer::LINE => 0,
|
||||||
|
Mustache_Tokenizer::INDEX => 8,
|
||||||
|
Mustache_Tokenizer::END => 27,
|
||||||
|
Mustache_Tokenizer::NODES => array(
|
||||||
|
array(
|
||||||
|
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_BLOCK_ARG,
|
||||||
|
Mustache_Tokenizer::NAME => 'bar',
|
||||||
|
Mustache_Tokenizer::OTAG => '{{',
|
||||||
|
Mustache_Tokenizer::CTAG => '}}',
|
||||||
|
Mustache_Tokenizer::LINE => 0,
|
||||||
|
Mustache_Tokenizer::INDEX => 16,
|
||||||
|
Mustache_Tokenizer::END => 19,
|
||||||
|
Mustache_Tokenizer::NODES => array(
|
||||||
|
array(
|
||||||
|
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
|
||||||
|
Mustache_Tokenizer::LINE => 0,
|
||||||
|
Mustache_Tokenizer::VALUE => 'baz'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
|
||||||
|
array(
|
||||||
|
array(
|
||||||
|
array(
|
||||||
|
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_BLOCK_VAR,
|
||||||
|
Mustache_Tokenizer::NAME => 'foo',
|
||||||
|
Mustache_Tokenizer::OTAG => '{{',
|
||||||
|
Mustache_Tokenizer::CTAG => '}}',
|
||||||
|
Mustache_Tokenizer::LINE => 0,
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
|
||||||
|
Mustache_Tokenizer::LINE => 0,
|
||||||
|
Mustache_Tokenizer::VALUE => 'bar'
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_END_SECTION,
|
||||||
|
Mustache_Tokenizer::NAME => 'foo',
|
||||||
|
Mustache_Tokenizer::OTAG => '{{',
|
||||||
|
Mustache_Tokenizer::CTAG => '}}',
|
||||||
|
Mustache_Tokenizer::LINE => 0,
|
||||||
|
Mustache_Tokenizer::INDEX => 11,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
array(
|
||||||
|
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_BLOCK_VAR,
|
||||||
|
Mustache_Tokenizer::NAME => 'foo',
|
||||||
|
Mustache_Tokenizer::OTAG => '{{',
|
||||||
|
Mustache_Tokenizer::CTAG => '}}',
|
||||||
|
Mustache_Tokenizer::LINE => 0,
|
||||||
|
Mustache_Tokenizer::END => 11,
|
||||||
|
Mustache_Tokenizer::NODES => array(
|
||||||
|
array(
|
||||||
|
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
|
||||||
|
Mustache_Tokenizer::LINE => 0,
|
||||||
|
Mustache_Tokenizer::VALUE => 'bar'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -273,6 +273,35 @@ class Mustache_Test_TokenizerTest extends PHPUnit_Framework_TestCase
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
|
|
||||||
|
// Ensure that $arg token is not picked up during tokenization
|
||||||
|
array(
|
||||||
|
'{{$arg}}default{{/arg}}',
|
||||||
|
null,
|
||||||
|
array(
|
||||||
|
array(
|
||||||
|
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_BLOCK_VAR,
|
||||||
|
Mustache_Tokenizer::NAME => 'arg',
|
||||||
|
Mustache_Tokenizer::OTAG => '{{',
|
||||||
|
Mustache_Tokenizer::CTAG => '}}',
|
||||||
|
Mustache_Tokenizer::LINE => 0,
|
||||||
|
Mustache_Tokenizer::INDEX => 8
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
|
||||||
|
Mustache_Tokenizer::LINE => 0,
|
||||||
|
Mustache_Tokenizer::VALUE => "default",
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_END_SECTION,
|
||||||
|
Mustache_Tokenizer::NAME => 'arg',
|
||||||
|
Mustache_Tokenizer::OTAG => '{{',
|
||||||
|
Mustache_Tokenizer::CTAG => '}}',
|
||||||
|
Mustache_Tokenizer::LINE => 0,
|
||||||
|
Mustache_Tokenizer::INDEX => 15,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user