Merge branch 'release/2.7.0'
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
<?php
|
||||
|
||||
$config = new Symfony\CS\Config\Config();
|
||||
$config->getFinder()->in(__DIR__)->exclude('bin');
|
||||
|
||||
return $config;
|
||||
+8
-4
@@ -1,4 +1,12 @@
|
||||
language: php
|
||||
|
||||
before_script:
|
||||
- curl http://cs.sensiolabs.org/get/php-cs-fixer.phar -o php-cs-fixer.phar
|
||||
|
||||
script:
|
||||
- phpunit
|
||||
- if [[ `php -r "echo version_compare(PHP_VERSION, '5.3.6', '>=');"` ]]; then php php-cs-fixer.phar --dry-run -v fix .; fi
|
||||
|
||||
php:
|
||||
- 5.2
|
||||
- 5.3
|
||||
@@ -6,7 +14,3 @@ php:
|
||||
- 5.5
|
||||
- 5.6
|
||||
- hhvm
|
||||
|
||||
matrix:
|
||||
allow_failures:
|
||||
- php: hhvm # See https://github.com/facebook/hhvm/pull/1860
|
||||
+6
-4
@@ -5,13 +5,15 @@
|
||||
|
||||
1. [Fork the repo on GitHub](https://github.com/bobthecow/mustache.php).
|
||||
|
||||
2. Run the test suite. We only take pull requests with passing tests, and it's great to know that you have a clean slate. Make sure you have PHPUnit 3.5+, then run `phpunit` from the project directory.
|
||||
2. Update submodules: `git submodule update --init`
|
||||
|
||||
3. Add tests for your change. Only refactoring and documentation changes require no new tests. If you are adding functionality or fixing a bug, add a test!
|
||||
3. Run the test suite. We only take pull requests with passing tests, and it's great to know that you have a clean slate. Make sure you have PHPUnit 3.5+, then run `phpunit` from the project directory.
|
||||
|
||||
4. Make the tests pass.
|
||||
4. Add tests for your change. Only refactoring and documentation changes require no new tests. If you are adding functionality or fixing a bug, add a test!
|
||||
|
||||
5. Push your fork to GitHub and submit a pull request against the `dev` branch.
|
||||
5. Make the tests pass.
|
||||
|
||||
6. Push your fork to GitHub and submit a pull request against the `dev` branch.
|
||||
|
||||
|
||||
### You can do some things to increase the chance that your pull request is accepted the first time:
|
||||
|
||||
@@ -95,10 +95,10 @@ EOS;
|
||||
/**
|
||||
* Loads a list of classes and caches them in one big file.
|
||||
*
|
||||
* @param array $classes An array of classes to load
|
||||
* @param string $cacheDir A cache directory
|
||||
* @param string $name The cache name prefix
|
||||
* @param string $extension File extension of the resulting file
|
||||
* @param array $classes An array of classes to load
|
||||
* @param string $cacheDir A cache directory
|
||||
* @param string $name The cache name prefix
|
||||
* @param string $extension File extension of the resulting file
|
||||
*
|
||||
* @throws InvalidArgumentException When class can't be loaded
|
||||
*/
|
||||
|
||||
+232
-79
@@ -16,6 +16,9 @@
|
||||
*/
|
||||
class Mustache_Compiler
|
||||
{
|
||||
|
||||
private $pragmas;
|
||||
private $defaultPragmas = array();
|
||||
private $sections;
|
||||
private $source;
|
||||
private $indentNextLine;
|
||||
@@ -23,7 +26,6 @@ class Mustache_Compiler
|
||||
private $entityFlags;
|
||||
private $charset;
|
||||
private $strictCallables;
|
||||
private $pragmas;
|
||||
|
||||
/**
|
||||
* Compile a Mustache token parse tree into PHP source code.
|
||||
@@ -40,7 +42,7 @@ class Mustache_Compiler
|
||||
*/
|
||||
public function compile($source, array $tree, $name, $customEscape = false, $charset = 'UTF-8', $strictCallables = false, $entityFlags = ENT_COMPAT)
|
||||
{
|
||||
$this->pragmas = array();
|
||||
$this->pragmas = $this->defaultPragmas;
|
||||
$this->sections = array();
|
||||
$this->source = $source;
|
||||
$this->indentNextLine = true;
|
||||
@@ -52,6 +54,23 @@ class Mustache_Compiler
|
||||
return $this->writeCode($tree, $name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable pragmas across all templates, regardless of the presence of pragma
|
||||
* tags in the individual templates.
|
||||
*
|
||||
* @internal Users should set global pragmas in Mustache_Engine, not here :)
|
||||
*
|
||||
* @param string[] $pragmas
|
||||
*/
|
||||
public function setPragmas(array $pragmas)
|
||||
{
|
||||
$this->pragmas = array();
|
||||
foreach ($pragmas as $pragma) {
|
||||
$this->pragmas[$pragma] = true;
|
||||
}
|
||||
$this->defaultPragmas = $this->pragmas;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function for walking the Mustache token parse tree.
|
||||
*
|
||||
@@ -76,6 +95,7 @@ class Mustache_Compiler
|
||||
$code .= $this->section(
|
||||
$node[Mustache_Tokenizer::NODES],
|
||||
$node[Mustache_Tokenizer::NAME],
|
||||
isset($node[Mustache_Tokenizer::FILTERS]) ? $node[Mustache_Tokenizer::FILTERS] : array(),
|
||||
$node[Mustache_Tokenizer::INDEX],
|
||||
$node[Mustache_Tokenizer::END],
|
||||
$node[Mustache_Tokenizer::OTAG],
|
||||
@@ -88,12 +108,12 @@ class Mustache_Compiler
|
||||
$code .= $this->invertedSection(
|
||||
$node[Mustache_Tokenizer::NODES],
|
||||
$node[Mustache_Tokenizer::NAME],
|
||||
isset($node[Mustache_Tokenizer::FILTERS]) ? $node[Mustache_Tokenizer::FILTERS] : array(),
|
||||
$level
|
||||
);
|
||||
break;
|
||||
|
||||
case Mustache_Tokenizer::T_PARTIAL:
|
||||
case Mustache_Tokenizer::T_PARTIAL_2:
|
||||
$code .= $this->partial(
|
||||
$node[Mustache_Tokenizer::NAME],
|
||||
isset($node[Mustache_Tokenizer::INDENT]) ? $node[Mustache_Tokenizer::INDENT] : '',
|
||||
@@ -101,16 +121,51 @@ class Mustache_Compiler
|
||||
);
|
||||
break;
|
||||
|
||||
case Mustache_Tokenizer::T_UNESCAPED:
|
||||
case Mustache_Tokenizer::T_UNESCAPED_2:
|
||||
$code .= $this->variable($node[Mustache_Tokenizer::NAME], false, $level);
|
||||
case Mustache_Tokenizer::T_PARENT:
|
||||
$code .= $this->parent(
|
||||
$node[Mustache_Tokenizer::NAME],
|
||||
isset($node[Mustache_Tokenizer::INDENT]) ? $node[Mustache_Tokenizer::INDENT] : '',
|
||||
$node[Mustache_Tokenizer::NODES],
|
||||
$level
|
||||
);
|
||||
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_COMMENT:
|
||||
break;
|
||||
|
||||
case Mustache_Tokenizer::T_ESCAPED:
|
||||
$code .= $this->variable($node[Mustache_Tokenizer::NAME], true, $level);
|
||||
case Mustache_Tokenizer::T_UNESCAPED:
|
||||
case Mustache_Tokenizer::T_UNESCAPED_2:
|
||||
$code .= $this->variable(
|
||||
$node[Mustache_Tokenizer::NAME],
|
||||
isset($node[Mustache_Tokenizer::FILTERS]) ? $node[Mustache_Tokenizer::FILTERS] : array(),
|
||||
$node[Mustache_Tokenizer::TYPE] === Mustache_Tokenizer::T_ESCAPED,
|
||||
$level
|
||||
);
|
||||
break;
|
||||
|
||||
case Mustache_Tokenizer::T_TEXT:
|
||||
@@ -135,6 +190,7 @@ class Mustache_Compiler
|
||||
{
|
||||
$this->lambdaHelper = new Mustache_LambdaHelper($this->mustache, $context);
|
||||
$buffer = \'\';
|
||||
$newContext = array();
|
||||
%s
|
||||
|
||||
return $buffer;
|
||||
@@ -149,6 +205,7 @@ class Mustache_Compiler
|
||||
public function renderInternal(Mustache_Context $context, $indent = \'\')
|
||||
{
|
||||
$buffer = \'\';
|
||||
$newContext = array();
|
||||
%s
|
||||
|
||||
return $buffer;
|
||||
@@ -170,11 +227,68 @@ class Mustache_Compiler
|
||||
$code = $this->walk($tree);
|
||||
$sections = implode("\n", $this->sections);
|
||||
$klass = empty($this->sections) ? self::KLASS_NO_LAMBDAS : self::KLASS;
|
||||
|
||||
$callable = $this->strictCallables ? $this->prepare(self::STRICT_CALLABLE) : '';
|
||||
|
||||
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
|
||||
}
|
||||
';
|
||||
|
||||
/**
|
||||
* Generate Mustache Template inheritance block variable PHP source.
|
||||
*
|
||||
* @param array $nodes Array of child tokens
|
||||
* @param string $id Section name
|
||||
* @param int $start Section start offset
|
||||
* @param int $end Section end offset
|
||||
* @param string $otag Current Mustache opening tag
|
||||
* @param string $ctag Current Mustache closing tag
|
||||
* @param int $level
|
||||
*
|
||||
* @return string Generated PHP source code
|
||||
*/
|
||||
private function blockVar($nodes, $id, $start, $end, $otag, $ctag, $level)
|
||||
{
|
||||
$id = var_export($id, true);
|
||||
|
||||
return sprintf($this->prepare(self::BLOCK_VAR, $level), $id, $this->walk($nodes, 2));
|
||||
}
|
||||
|
||||
const BLOCK_ARG = '
|
||||
// %s block_arg
|
||||
$value = $this->section%s($context, $indent, true);
|
||||
$newContext[%s] = %s$value;
|
||||
';
|
||||
|
||||
/**
|
||||
* Generate Mustache Template inheritance block argument PHP source.
|
||||
*
|
||||
* @param array $nodes Array of child tokens
|
||||
* @param string $id Section name
|
||||
* @param int $start Section start offset
|
||||
* @param int $end Section end offset
|
||||
* @param string $otag Current Mustache opening tag
|
||||
* @param string $ctag Current Mustache closing tag
|
||||
* @param int $level
|
||||
*
|
||||
* @return string Generated PHP source code
|
||||
*/
|
||||
private function blockArg($nodes, $id, $start, $end, $otag, $ctag, $level)
|
||||
{
|
||||
$key = $this->section($nodes, $id, array(), $start, $end, $otag, $ctag, $level, true);
|
||||
$id = var_export($id, true);
|
||||
|
||||
return sprintf($this->prepare(self::BLOCK_ARG, $level), $id, $key, $id, $this->flushIndent());
|
||||
}
|
||||
|
||||
const SECTION_CALL = '
|
||||
// %s section
|
||||
$value = $context->%s(%s);%s
|
||||
@@ -198,7 +312,8 @@ class Mustache_Compiler
|
||||
} elseif (!empty($value)) {
|
||||
$values = $this->isIterable($value) ? $value : array($value);
|
||||
foreach ($values as $value) {
|
||||
$context->push($value);%s
|
||||
$context->push($value);
|
||||
%s
|
||||
$context->pop();
|
||||
}
|
||||
}
|
||||
@@ -209,26 +324,20 @@ class Mustache_Compiler
|
||||
/**
|
||||
* Generate Mustache Template section PHP source.
|
||||
*
|
||||
* @param array $nodes Array of child tokens
|
||||
* @param string $id Section name
|
||||
* @param int $start Section start offset
|
||||
* @param int $end Section end offset
|
||||
* @param string $otag Current Mustache opening tag
|
||||
* @param string $ctag Current Mustache closing tag
|
||||
* @param int $level
|
||||
* @param array $nodes Array of child tokens
|
||||
* @param string $id Section name
|
||||
* @param string[] $filters Array of filters
|
||||
* @param int $start Section start offset
|
||||
* @param int $end Section end offset
|
||||
* @param string $otag Current Mustache opening tag
|
||||
* @param string $ctag Current Mustache closing tag
|
||||
* @param int $level
|
||||
* @param bool $arg (default: false)
|
||||
*
|
||||
* @return string Generated section PHP source code
|
||||
*/
|
||||
private function section($nodes, $id, $start, $end, $otag, $ctag, $level)
|
||||
private function section($nodes, $id, $filters, $start, $end, $otag, $ctag, $level, $arg = false)
|
||||
{
|
||||
$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);
|
||||
$source = var_export(substr($this->source, $start, $end - $start), true);
|
||||
$callable = $this->getCallable();
|
||||
|
||||
@@ -238,13 +347,21 @@ class Mustache_Compiler
|
||||
$delims = '';
|
||||
}
|
||||
|
||||
$key = ucfirst(md5($delims."\n".$source));
|
||||
$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));
|
||||
}
|
||||
|
||||
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);
|
||||
$filters = $this->getFilters($filters, $level);
|
||||
|
||||
return sprintf($this->prepare(self::SECTION_CALL, $level), $id, $method, $id, $filters, $key);
|
||||
}
|
||||
}
|
||||
|
||||
const INVERTED_SECTION = '
|
||||
@@ -257,29 +374,26 @@ class Mustache_Compiler
|
||||
/**
|
||||
* Generate Mustache Template inverted section PHP source.
|
||||
*
|
||||
* @param array $nodes Array of child tokens
|
||||
* @param string $id Section name
|
||||
* @param int $level
|
||||
* @param array $nodes Array of child tokens
|
||||
* @param string $id Section name
|
||||
* @param string[] $filters Array of filters
|
||||
* @param int $level
|
||||
*
|
||||
* @return string Generated inverted section PHP source code
|
||||
*/
|
||||
private function invertedSection($nodes, $id, $level)
|
||||
private function invertedSection($nodes, $id, $filters, $level)
|
||||
{
|
||||
$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);
|
||||
$method = $this->getFindMethod($id);
|
||||
$id = var_export($id, true);
|
||||
$filters = $this->getFilters($filters, $level);
|
||||
|
||||
return sprintf($this->prepare(self::INVERTED_SECTION, $level), $id, $method, $id, $filters, $this->walk($nodes, $level));
|
||||
}
|
||||
|
||||
const PARTIAL_INDENT = ', $indent . %s';
|
||||
const PARTIAL = '
|
||||
if ($partial = $this->mustache->loadPartial(%s)) {
|
||||
$buffer .= $partial->renderInternal($context, $indent . %s);
|
||||
$buffer .= $partial->renderInternal($context%s);
|
||||
}
|
||||
';
|
||||
|
||||
@@ -294,13 +408,63 @@ class Mustache_Compiler
|
||||
*/
|
||||
private function partial($id, $indent, $level)
|
||||
{
|
||||
if ($indent !== '') {
|
||||
$indentParam = sprintf(self::PARTIAL_INDENT, var_export($indent, true));
|
||||
} else {
|
||||
$indentParam = '';
|
||||
}
|
||||
|
||||
return sprintf(
|
||||
$this->prepare(self::PARTIAL, $level),
|
||||
var_export($id, true),
|
||||
$indentParam
|
||||
);
|
||||
}
|
||||
|
||||
const PARENT = '
|
||||
%s
|
||||
|
||||
if ($parent = $this->mustache->LoadPartial(%s)) {
|
||||
$context->pushBlockContext($newContext);
|
||||
$buffer .= $parent->renderInternal($context, $indent);
|
||||
$context->popBlockContext();
|
||||
}
|
||||
';
|
||||
|
||||
/**
|
||||
* Generate Mustache Template inheritance parent call PHP source.
|
||||
*
|
||||
* @param string $id Parent tag name
|
||||
* @param string $indent Whitespace indent to apply to parent
|
||||
* @param array $children Child nodes
|
||||
* @param int $level
|
||||
*
|
||||
* @return string Generated PHP source code
|
||||
*/
|
||||
private function parent($id, $indent, array $children, $level)
|
||||
{
|
||||
$realChildren = array_filter($children, array(__CLASS__, 'onlyBlockArgs'));
|
||||
|
||||
return sprintf(
|
||||
$this->prepare(self::PARENT, $level),
|
||||
$this->walk($realChildren, $level),
|
||||
var_export($id, true),
|
||||
var_export($indent, true)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method for filtering out non-block-arg tokens.
|
||||
*
|
||||
* @param array $node
|
||||
*
|
||||
* @return boolean True if $node is a block arg token.
|
||||
*/
|
||||
private static function onlyBlockArgs(array $node)
|
||||
{
|
||||
return $node[Mustache_Tokenizer::TYPE] === Mustache_Tokenizer::T_BLOCK_ARG;
|
||||
}
|
||||
|
||||
const VARIABLE = '
|
||||
$value = $this->resolveValue($context->%s(%s), $context, $indent);%s
|
||||
$buffer .= %s%s;
|
||||
@@ -309,43 +473,23 @@ class Mustache_Compiler
|
||||
/**
|
||||
* Generate Mustache Template variable interpolation PHP source.
|
||||
*
|
||||
* @param string $id Variable name
|
||||
* @param boolean $escape Escape the variable value for output?
|
||||
* @param int $level
|
||||
* @param string $id Variable name
|
||||
* @param string[] $filters Array of filters
|
||||
* @param boolean $escape Escape the variable value for output?
|
||||
* @param int $level
|
||||
*
|
||||
* @return string Generated variable interpolation PHP source
|
||||
*/
|
||||
private function variable($id, $escape, $level)
|
||||
private function variable($id, $filters, $escape, $level)
|
||||
{
|
||||
$filters = '';
|
||||
|
||||
if (isset($this->pragmas[Mustache_Engine::PRAGMA_FILTERS])) {
|
||||
list($id, $filters) = $this->getFilters($id, $level);
|
||||
}
|
||||
|
||||
$method = $this->getFindMethod($id);
|
||||
$id = ($method !== 'last') ? var_export($id, true) : '';
|
||||
$value = $escape ? $this->getEscape() : '$value';
|
||||
$method = $this->getFindMethod($id);
|
||||
$id = ($method !== 'last') ? var_export($id, true) : '';
|
||||
$filters = $this->getFilters($filters, $level);
|
||||
$value = $escape ? $this->getEscape() : '$value';
|
||||
|
||||
return sprintf($this->prepare(self::VARIABLE, $level), $method, $id, $filters, $this->flushIndent(), $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate Mustache Template variable filtering PHP source.
|
||||
*
|
||||
* @param string $id Variable name
|
||||
* @param int $level
|
||||
*
|
||||
* @return string Generated variable filtering PHP source
|
||||
*/
|
||||
private function getFilters($id, $level)
|
||||
{
|
||||
$filters = array_map('trim', explode('|', $id));
|
||||
$id = array_shift($filters);
|
||||
|
||||
return array($id, $this->getFilter($filters, $level));
|
||||
}
|
||||
|
||||
const FILTER = '
|
||||
$filter = $context->%s(%s);
|
||||
if (!(%s)) {
|
||||
@@ -355,14 +499,14 @@ class Mustache_Compiler
|
||||
';
|
||||
|
||||
/**
|
||||
* Generate PHP source for a single filter.
|
||||
* Generate Mustache Template variable filtering PHP source.
|
||||
*
|
||||
* @param array $filters
|
||||
* @param int $level
|
||||
* @param string[] $filters Array of filters
|
||||
* @param int $level
|
||||
*
|
||||
* @return string Generated filter PHP source
|
||||
*/
|
||||
private function getFilter(array $filters, $level)
|
||||
private function getFilters(array $filters, $level)
|
||||
{
|
||||
if (empty($filters)) {
|
||||
return '';
|
||||
@@ -374,7 +518,7 @@ class Mustache_Compiler
|
||||
$callable = $this->getCallable('$filter');
|
||||
$msg = var_export($name, true);
|
||||
|
||||
return sprintf($this->prepare(self::FILTER, $level), $method, $filter, $callable, $msg, $this->getFilter($filters, $level));
|
||||
return sprintf($this->prepare(self::FILTER, $level), $method, $filter, $callable, $msg, $this->getFilters($filters, $level));
|
||||
}
|
||||
|
||||
const LINE = '$buffer .= "\n";';
|
||||
@@ -434,9 +578,9 @@ class Mustache_Compiler
|
||||
{
|
||||
if ($this->customEscape) {
|
||||
return sprintf(self::CUSTOM_ESCAPE, $value);
|
||||
} else {
|
||||
return sprintf(self::DEFAULT_ESCAPE, $value, var_export($this->entityFlags, true), var_export($this->charset, true));
|
||||
}
|
||||
|
||||
return sprintf(self::DEFAULT_ESCAPE, $value, var_export($this->entityFlags, true), var_export($this->charset, true));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -456,16 +600,25 @@ class Mustache_Compiler
|
||||
{
|
||||
if ($id === '.') {
|
||||
return 'last';
|
||||
} elseif (strpos($id, '.') === false) {
|
||||
return 'find';
|
||||
} else {
|
||||
return 'findDot';
|
||||
}
|
||||
|
||||
if (strpos($id, '.') === false) {
|
||||
return 'find';
|
||||
}
|
||||
|
||||
return 'findDot';
|
||||
}
|
||||
|
||||
const IS_CALLABLE = '!is_string(%s) && is_callable(%s)';
|
||||
const STRICT_IS_CALLABLE = 'is_object(%s) && is_callable(%s)';
|
||||
|
||||
/**
|
||||
* Helper function to compile strict vs lax "is callable" logic.
|
||||
*
|
||||
* @param string $variable (default: '$value')
|
||||
*
|
||||
* @return string "is callable" logic
|
||||
*/
|
||||
private function getCallable($variable = '$value')
|
||||
{
|
||||
$tpl = $this->strictCallables ? self::STRICT_IS_CALLABLE : self::IS_CALLABLE;
|
||||
|
||||
+65
-13
@@ -14,7 +14,8 @@
|
||||
*/
|
||||
class Mustache_Context
|
||||
{
|
||||
private $stack = array();
|
||||
private $stack = array();
|
||||
private $blockStack = array();
|
||||
|
||||
/**
|
||||
* Mustache rendering Context constructor.
|
||||
@@ -38,6 +39,16 @@ class Mustache_Context
|
||||
array_push($this->stack, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Push a new Context frame onto the block context stack.
|
||||
*
|
||||
* @param mixed $value Object or array to use for block context
|
||||
*/
|
||||
public function pushBlockContext($value)
|
||||
{
|
||||
array_push($this->blockStack, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pop the last Context frame from the stack.
|
||||
*
|
||||
@@ -48,6 +59,16 @@ class Mustache_Context
|
||||
return array_pop($this->stack);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pop the last block Context frame from the stack.
|
||||
*
|
||||
* @return mixed Last block Context frame (object or array)
|
||||
*/
|
||||
public function popBlockContext()
|
||||
{
|
||||
return array_pop($this->blockStack);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the last Context frame.
|
||||
*
|
||||
@@ -120,6 +141,24 @@ class Mustache_Context
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find an argument in the block context stack.
|
||||
*
|
||||
* @param string $id
|
||||
*
|
||||
* @return mixed Variable value, or '' if not found.
|
||||
*/
|
||||
public function findInBlock($id)
|
||||
{
|
||||
foreach ($this->blockStack as $context) {
|
||||
if (array_key_exists($id, $context)) {
|
||||
return $context[$id];
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to find a variable in the Context stack.
|
||||
*
|
||||
@@ -133,19 +172,32 @@ class Mustache_Context
|
||||
private function findVariableInStack($id, array $stack)
|
||||
{
|
||||
for ($i = count($stack) - 1; $i >= 0; $i--) {
|
||||
if (is_object($stack[$i]) && !($stack[$i] instanceof Closure)) {
|
||||
$frame = &$stack[$i];
|
||||
|
||||
// Note that is_callable() *will not work here*
|
||||
// See https://github.com/bobthecow/mustache.php/wiki/Magic-Methods
|
||||
if (method_exists($stack[$i], $id)) {
|
||||
return $stack[$i]->$id();
|
||||
} elseif (isset($stack[$i]->$id)) {
|
||||
return $stack[$i]->$id;
|
||||
} elseif ($stack[$i] instanceof ArrayAccess && isset($stack[$i][$id])) {
|
||||
return $stack[$i][$id];
|
||||
}
|
||||
} elseif (is_array($stack[$i]) && array_key_exists($id, $stack[$i])) {
|
||||
return $stack[$i][$id];
|
||||
switch (gettype($frame)) {
|
||||
case 'object':
|
||||
if (!($frame instanceof Closure)) {
|
||||
// Note that is_callable() *will not work here*
|
||||
// See https://github.com/bobthecow/mustache.php/wiki/Magic-Methods
|
||||
if (method_exists($frame, $id)) {
|
||||
return $frame->$id();
|
||||
}
|
||||
|
||||
if (isset($frame->$id)) {
|
||||
return $frame->$id;
|
||||
}
|
||||
|
||||
if ($frame instanceof ArrayAccess && isset($frame[$id])) {
|
||||
return $frame[$id];
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'array':
|
||||
if (array_key_exists($id, $frame)) {
|
||||
return $frame[$id];
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+49
-11
@@ -23,10 +23,17 @@
|
||||
*/
|
||||
class Mustache_Engine
|
||||
{
|
||||
const VERSION = '2.6.1';
|
||||
const VERSION = '2.7.0';
|
||||
const SPEC_VERSION = '1.1.2';
|
||||
|
||||
const PRAGMA_FILTERS = 'FILTERS';
|
||||
const PRAGMA_BLOCKS = 'BLOCKS';
|
||||
|
||||
// Known pragmas
|
||||
private static $knownPragmas = array(
|
||||
self::PRAGMA_FILTERS => true,
|
||||
self::PRAGMA_BLOCKS => true,
|
||||
);
|
||||
|
||||
// Template cache
|
||||
private $templates = array();
|
||||
@@ -44,6 +51,7 @@ class Mustache_Engine
|
||||
private $charset = 'UTF-8';
|
||||
private $logger;
|
||||
private $strictCallables = false;
|
||||
private $pragmas = array();
|
||||
|
||||
// Services
|
||||
private $tokenizer;
|
||||
@@ -110,6 +118,10 @@ class Mustache_Engine
|
||||
* // helps protect against arbitrary code execution when user input is passed directly into the template.
|
||||
* // This currently defaults to false, but will default to true in v3.0.
|
||||
* 'strict_callables' => true,
|
||||
*
|
||||
* // Enable pragmas across all templates, regardless of the presence of pragma tags in the individual
|
||||
* // templates.
|
||||
* 'pragmas' => [Mustache_Engine::PRAGMA_FILTERS],
|
||||
* );
|
||||
*
|
||||
* @throws Mustache_Exception_InvalidArgumentException If `escape` option is not callable.
|
||||
@@ -176,6 +188,15 @@ class Mustache_Engine
|
||||
if (isset($options['strict_callables'])) {
|
||||
$this->strictCallables = $options['strict_callables'];
|
||||
}
|
||||
|
||||
if (isset($options['pragmas'])) {
|
||||
foreach ($options['pragmas'] as $pragma) {
|
||||
if (!isset(self::$knownPragmas[$pragma])) {
|
||||
throw new Mustache_Exception_InvalidArgumentException(sprintf('Unknown pragma: "%s".', $pragma));
|
||||
}
|
||||
$this->pragmas[$pragma] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -226,6 +247,16 @@ class Mustache_Engine
|
||||
return $this->charset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current globally enabled pragmas.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getPragmas()
|
||||
{
|
||||
return array_keys($this->pragmas);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the Mustache template Loader instance.
|
||||
*
|
||||
@@ -247,7 +278,7 @@ class Mustache_Engine
|
||||
public function getLoader()
|
||||
{
|
||||
if (!isset($this->loader)) {
|
||||
$this->loader = new Mustache_Loader_StringLoader;
|
||||
$this->loader = new Mustache_Loader_StringLoader();
|
||||
}
|
||||
|
||||
return $this->loader;
|
||||
@@ -274,7 +305,7 @@ class Mustache_Engine
|
||||
public function getPartialsLoader()
|
||||
{
|
||||
if (!isset($this->partialsLoader)) {
|
||||
$this->partialsLoader = new Mustache_Loader_ArrayLoader;
|
||||
$this->partialsLoader = new Mustache_Loader_ArrayLoader();
|
||||
}
|
||||
|
||||
return $this->partialsLoader;
|
||||
@@ -290,7 +321,7 @@ class Mustache_Engine
|
||||
public function setPartials(array $partials = array())
|
||||
{
|
||||
if (!isset($this->partialsLoader)) {
|
||||
$this->partialsLoader = new Mustache_Loader_ArrayLoader;
|
||||
$this->partialsLoader = new Mustache_Loader_ArrayLoader();
|
||||
}
|
||||
|
||||
if (!$this->partialsLoader instanceof Mustache_Loader_MutableLoader) {
|
||||
@@ -334,7 +365,7 @@ class Mustache_Engine
|
||||
public function getHelpers()
|
||||
{
|
||||
if (!isset($this->helpers)) {
|
||||
$this->helpers = new Mustache_HelperCollection;
|
||||
$this->helpers = new Mustache_HelperCollection();
|
||||
}
|
||||
|
||||
return $this->helpers;
|
||||
@@ -443,7 +474,7 @@ class Mustache_Engine
|
||||
public function getTokenizer()
|
||||
{
|
||||
if (!isset($this->tokenizer)) {
|
||||
$this->tokenizer = new Mustache_Tokenizer;
|
||||
$this->tokenizer = new Mustache_Tokenizer();
|
||||
}
|
||||
|
||||
return $this->tokenizer;
|
||||
@@ -469,7 +500,7 @@ class Mustache_Engine
|
||||
public function getParser()
|
||||
{
|
||||
if (!isset($this->parser)) {
|
||||
$this->parser = new Mustache_Parser;
|
||||
$this->parser = new Mustache_Parser();
|
||||
}
|
||||
|
||||
return $this->parser;
|
||||
@@ -495,7 +526,7 @@ class Mustache_Engine
|
||||
public function getCompiler()
|
||||
{
|
||||
if (!isset($this->compiler)) {
|
||||
$this->compiler = new Mustache_Compiler;
|
||||
$this->compiler = new Mustache_Compiler();
|
||||
}
|
||||
|
||||
return $this->compiler;
|
||||
@@ -563,12 +594,13 @@ class Mustache_Engine
|
||||
public function getTemplateClassName($source)
|
||||
{
|
||||
return $this->templateClassPrefix . md5(sprintf(
|
||||
'version:%s,escape:%s,entity_flags:%i,charset:%s,strict_callables:%s,source:%s',
|
||||
'version:%s,escape:%s,entity_flags:%i,charset:%s,strict_callables:%s,pragmas:%s,source:%s',
|
||||
self::VERSION,
|
||||
isset($this->escape) ? 'custom' : 'default',
|
||||
$this->entityFlags,
|
||||
$this->charset,
|
||||
$this->strictCallables ? 'true' : 'false',
|
||||
implode(' ', $this->getPragmas()),
|
||||
$source
|
||||
));
|
||||
}
|
||||
@@ -705,7 +737,10 @@ class Mustache_Engine
|
||||
*/
|
||||
private function parse($source)
|
||||
{
|
||||
return $this->getParser()->parse($this->tokenize($source));
|
||||
$parser = $this->getParser();
|
||||
$parser->setPragmas($this->getPragmas());
|
||||
|
||||
return $parser->parse($this->tokenize($source));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -728,7 +763,10 @@ class Mustache_Engine
|
||||
array('className' => $name)
|
||||
);
|
||||
|
||||
return $this->getCompiler()->compile($source, $tree, $name, isset($this->escape), $this->charset, $this->strictCallables, $this->entityFlags);
|
||||
$compiler = $this->getCompiler();
|
||||
$compiler->setPragmas($this->getPragmas());
|
||||
|
||||
return $compiler->compile($source, $tree, $name, isset($this->escape), $this->charset, $this->strictCallables, $this->entityFlags);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -49,7 +49,7 @@ class Mustache_Loader_FilesystemLoader implements Mustache_Loader
|
||||
{
|
||||
$this->baseDir = $baseDir;
|
||||
|
||||
if (strpos($this->baseDir, '://') === -1) {
|
||||
if (strpos($this->baseDir, '://') === false) {
|
||||
$this->baseDir = realpath($this->baseDir);
|
||||
}
|
||||
|
||||
|
||||
+115
-4
@@ -18,6 +18,11 @@ class Mustache_Parser
|
||||
{
|
||||
private $lineNum;
|
||||
private $lineTokens;
|
||||
private $pragmas;
|
||||
private $defaultPragmas = array();
|
||||
|
||||
private $pragmaFilters;
|
||||
private $pragmaBlocks;
|
||||
|
||||
/**
|
||||
* Process an array of Mustache tokens and convert them into a parse tree.
|
||||
@@ -30,10 +35,31 @@ class Mustache_Parser
|
||||
{
|
||||
$this->lineNum = -1;
|
||||
$this->lineTokens = 0;
|
||||
$this->pragmas = $this->defaultPragmas;
|
||||
|
||||
$this->pragmaFilters = isset($this->pragmas[Mustache_Engine::PRAGMA_FILTERS]);
|
||||
$this->pragmaBlocks = isset($this->pragmas[Mustache_Engine::PRAGMA_BLOCKS]);
|
||||
|
||||
return $this->buildTree($tokens);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable pragmas across all templates, regardless of the presence of pragma
|
||||
* tags in the individual templates.
|
||||
*
|
||||
* @internal Users should set global pragmas in Mustache_Engine, not here :)
|
||||
*
|
||||
* @param string[] $pragmas
|
||||
*/
|
||||
public function setPragmas(array $pragmas)
|
||||
{
|
||||
$this->pragmas = array();
|
||||
foreach ($pragmas as $pragma) {
|
||||
$this->enablePragma($pragma);
|
||||
}
|
||||
$this->defaultPragmas = $this->pragmas;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method for recursively building a parse tree.
|
||||
*
|
||||
@@ -58,13 +84,23 @@ class Mustache_Parser
|
||||
$this->lineTokens = 0;
|
||||
}
|
||||
|
||||
if ($this->pragmaFilters && isset($token[Mustache_Tokenizer::NAME])) {
|
||||
list($name, $filters) = $this->getNameAndFilters($token[Mustache_Tokenizer::NAME]);
|
||||
if (!empty($filters)) {
|
||||
$token[Mustache_Tokenizer::NAME] = $name;
|
||||
$token[Mustache_Tokenizer::FILTERS] = $filters;
|
||||
}
|
||||
}
|
||||
|
||||
switch ($token[Mustache_Tokenizer::TYPE]) {
|
||||
case Mustache_Tokenizer::T_DELIM_CHANGE:
|
||||
$this->checkIfTokenIsAllowedInParent($parent, $token);
|
||||
$this->clearStandaloneLines($nodes, $tokens);
|
||||
break;
|
||||
|
||||
case Mustache_Tokenizer::T_SECTION:
|
||||
case Mustache_Tokenizer::T_INVERTED:
|
||||
$this->checkIfTokenIsAllowedInParent($parent, $token);
|
||||
$this->clearStandaloneLines($nodes, $tokens);
|
||||
$nodes[] = $this->buildTree($tokens, $token);
|
||||
break;
|
||||
@@ -97,15 +133,40 @@ class Mustache_Parser
|
||||
return $parent;
|
||||
|
||||
case Mustache_Tokenizer::T_PARTIAL:
|
||||
case Mustache_Tokenizer::T_PARTIAL_2:
|
||||
// store the whitespace prefix for laters!
|
||||
$this->checkIfTokenIsAllowedInParent($parent, $token);
|
||||
//store the whitespace prefix for laters!
|
||||
if ($indent = $this->clearStandaloneLines($nodes, $tokens)) {
|
||||
$token[Mustache_Tokenizer::INDENT] = $indent[Mustache_Tokenizer::VALUE];
|
||||
}
|
||||
$nodes[] = $token;
|
||||
break;
|
||||
|
||||
case Mustache_Tokenizer::T_PARENT:
|
||||
$this->checkIfTokenIsAllowedInParent($parent, $token);
|
||||
$nodes[] = $this->buildTree($tokens, $token);
|
||||
break;
|
||||
|
||||
case Mustache_Tokenizer::T_BLOCK_VAR:
|
||||
if ($this->pragmaBlocks) {
|
||||
// BLOCKS pragma is enabled, let's do this!
|
||||
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);
|
||||
} else {
|
||||
// pretend this was just a normal "escaped" token...
|
||||
$token[Mustache_Tokenizer::TYPE] = Mustache_Tokenizer::T_ESCAPED;
|
||||
// TODO: figure out how to figure out if there was a space after this dollar:
|
||||
$token[Mustache_Tokenizer::NAME] = '$' . $token[Mustache_Tokenizer::NAME];
|
||||
$nodes[] = $token;
|
||||
}
|
||||
break;
|
||||
|
||||
case Mustache_Tokenizer::T_PRAGMA:
|
||||
$this->enablePragma($token[Mustache_Tokenizer::NAME]);
|
||||
// no break
|
||||
|
||||
case Mustache_Tokenizer::T_COMMENT:
|
||||
$this->clearStandaloneLines($nodes, $tokens);
|
||||
$nodes[] = $token;
|
||||
@@ -137,7 +198,7 @@ class Mustache_Parser
|
||||
* @param array $nodes Parsed nodes.
|
||||
* @param array $tokens Tokens to be parsed.
|
||||
*
|
||||
* @return array Resulting indent token, if any.
|
||||
* @return array|null Resulting indent token, if any.
|
||||
*/
|
||||
private function clearStandaloneLines(array &$nodes, array &$tokens)
|
||||
{
|
||||
@@ -197,10 +258,60 @@ class Mustache_Parser
|
||||
*/
|
||||
private function tokenIsWhitespace(array $token)
|
||||
{
|
||||
if ($token[Mustache_Tokenizer::TYPE] == Mustache_Tokenizer::T_TEXT) {
|
||||
if ($token[Mustache_Tokenizer::TYPE] === Mustache_Tokenizer::T_TEXT) {
|
||||
return preg_match('/^\s*$/', $token[Mustache_Tokenizer::VALUE]);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether a token is allowed inside a parent tag.
|
||||
*
|
||||
* @throws Mustache_Exception_SyntaxException if an invalid token is found inside a parent tag.
|
||||
*
|
||||
* @param array|null $parent
|
||||
* @param array $token
|
||||
*/
|
||||
private function checkIfTokenIsAllowedInParent($parent, array $token)
|
||||
{
|
||||
if ($parent[Mustache_Tokenizer::TYPE] === Mustache_Tokenizer::T_PARENT) {
|
||||
throw new Mustache_Exception_SyntaxException('Illegal content in < parent tag', $token);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Split a tag name into name and filters.
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return array [Tag name, Array of filters]
|
||||
*/
|
||||
private function getNameAndFilters($name)
|
||||
{
|
||||
$filters = array_map('trim', explode('|', $name));
|
||||
$name = array_shift($filters);
|
||||
|
||||
return array($name, $filters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable a pragma.
|
||||
*
|
||||
* @param string $name
|
||||
*/
|
||||
private function enablePragma($name)
|
||||
{
|
||||
$this->pragmas[$name] = true;
|
||||
|
||||
switch ($name) {
|
||||
case Mustache_Engine::PRAGMA_BLOCKS:
|
||||
$this->pragmaBlocks = true;
|
||||
break;
|
||||
|
||||
case Mustache_Engine::PRAGMA_FILTERS:
|
||||
$this->pragmaFilters = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+19
-14
@@ -63,7 +63,9 @@ abstract class Mustache_Template
|
||||
*/
|
||||
public function render($context = array())
|
||||
{
|
||||
return $this->renderInternal($this->prepareContextStack($context));
|
||||
return $this->renderInternal(
|
||||
$this->prepareContextStack($context)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -111,19 +113,22 @@ abstract class Mustache_Template
|
||||
*/
|
||||
protected function isIterable($value)
|
||||
{
|
||||
if (is_object($value)) {
|
||||
return $value instanceof Traversable;
|
||||
} elseif (is_array($value)) {
|
||||
$i = 0;
|
||||
foreach ($value as $k => $v) {
|
||||
if ($k !== $i++) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
switch (gettype($value)) {
|
||||
case 'object':
|
||||
return $value instanceof Traversable;
|
||||
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
case 'array':
|
||||
$i = 0;
|
||||
foreach ($value as $k => $v) {
|
||||
if ($k !== $i++) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,7 +143,7 @@ abstract class Mustache_Template
|
||||
*/
|
||||
protected function prepareContextStack($context = null)
|
||||
{
|
||||
$stack = new Mustache_Context;
|
||||
$stack = new Mustache_Context();
|
||||
|
||||
$helpers = $this->mustache->getHelpers();
|
||||
if (!$helpers->isEmpty()) {
|
||||
|
||||
+19
-15
@@ -27,13 +27,15 @@ class Mustache_Tokenizer
|
||||
const T_END_SECTION = '/';
|
||||
const T_COMMENT = '!';
|
||||
const T_PARTIAL = '>';
|
||||
const T_PARTIAL_2 = '<';
|
||||
const T_PARENT = '<';
|
||||
const T_DELIM_CHANGE = '=';
|
||||
const T_ESCAPED = '_v';
|
||||
const T_UNESCAPED = '{';
|
||||
const T_UNESCAPED_2 = '&';
|
||||
const T_TEXT = '_t';
|
||||
const T_PRAGMA = '%';
|
||||
const T_BLOCK_VAR = '$';
|
||||
const T_BLOCK_ARG = '$arg';
|
||||
|
||||
// Valid token types
|
||||
private static $tagTypes = array(
|
||||
@@ -42,32 +44,34 @@ class Mustache_Tokenizer
|
||||
self::T_END_SECTION => true,
|
||||
self::T_COMMENT => true,
|
||||
self::T_PARTIAL => true,
|
||||
self::T_PARTIAL_2 => true,
|
||||
self::T_PARENT => true,
|
||||
self::T_DELIM_CHANGE => true,
|
||||
self::T_ESCAPED => true,
|
||||
self::T_UNESCAPED => true,
|
||||
self::T_UNESCAPED_2 => true,
|
||||
self::T_PRAGMA => true,
|
||||
self::T_BLOCK_VAR => true,
|
||||
);
|
||||
|
||||
// Interpolated tags
|
||||
private static $interpolatedTags = array(
|
||||
self::T_ESCAPED => true,
|
||||
self::T_UNESCAPED => true,
|
||||
self::T_UNESCAPED_2 => true,
|
||||
self::T_ESCAPED => true,
|
||||
self::T_UNESCAPED => true,
|
||||
self::T_UNESCAPED_2 => true,
|
||||
);
|
||||
|
||||
// Token properties
|
||||
const TYPE = 'type';
|
||||
const NAME = 'name';
|
||||
const OTAG = 'otag';
|
||||
const CTAG = 'ctag';
|
||||
const LINE = 'line';
|
||||
const INDEX = 'index';
|
||||
const END = 'end';
|
||||
const INDENT = 'indent';
|
||||
const NODES = 'nodes';
|
||||
const VALUE = 'value';
|
||||
const TYPE = 'type';
|
||||
const NAME = 'name';
|
||||
const OTAG = 'otag';
|
||||
const CTAG = 'ctag';
|
||||
const LINE = 'line';
|
||||
const INDEX = 'index';
|
||||
const END = 'end';
|
||||
const INDENT = 'indent';
|
||||
const NODES = 'nodes';
|
||||
const VALUE = 'value';
|
||||
const FILTERS = 'filters';
|
||||
|
||||
private $state;
|
||||
private $tagType;
|
||||
|
||||
@@ -20,7 +20,7 @@ class Mustache_Test_CompilerTest extends PHPUnit_Framework_TestCase
|
||||
*/
|
||||
public function testCompile($source, array $tree, $name, $customEscaper, $entityFlags, $charset, $expected)
|
||||
{
|
||||
$compiler = new Mustache_Compiler;
|
||||
$compiler = new Mustache_Compiler();
|
||||
|
||||
$compiled = $compiler->compile($source, $tree, $name, $customEscaper, $charset, false, $entityFlags);
|
||||
foreach ($expected as $contains) {
|
||||
@@ -138,7 +138,7 @@ class Mustache_Test_CompilerTest extends PHPUnit_Framework_TestCase
|
||||
*/
|
||||
public function testCompilerThrowsSyntaxException()
|
||||
{
|
||||
$compiler = new Mustache_Compiler;
|
||||
$compiler = new Mustache_Compiler();
|
||||
$compiler->compile('', array(array(Mustache_Tokenizer::TYPE => 'invalid')), 'SomeClass');
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ class Mustache_Test_ContextTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testConstructor()
|
||||
{
|
||||
$one = new Mustache_Context;
|
||||
$one = new Mustache_Context();
|
||||
$this->assertSame('', $one->find('foo'));
|
||||
$this->assertSame('', $one->find('bar'));
|
||||
|
||||
@@ -27,7 +27,7 @@ class Mustache_Test_ContextTest extends PHPUnit_Framework_TestCase
|
||||
$this->assertEquals('FOO', $two->find('foo'));
|
||||
$this->assertEquals('<BAR>', $two->find('bar'));
|
||||
|
||||
$obj = new StdClass;
|
||||
$obj = new StdClass();
|
||||
$obj->name = 'NAME';
|
||||
$three = new Mustache_Context($obj);
|
||||
$this->assertSame($obj, $three->last());
|
||||
@@ -36,16 +36,16 @@ class Mustache_Test_ContextTest extends PHPUnit_Framework_TestCase
|
||||
|
||||
public function testPushPopAndLast()
|
||||
{
|
||||
$context = new Mustache_Context;
|
||||
$context = new Mustache_Context();
|
||||
$this->assertFalse($context->last());
|
||||
|
||||
$dummy = new Mustache_Test_TestDummy;
|
||||
$dummy = new Mustache_Test_TestDummy();
|
||||
$context->push($dummy);
|
||||
$this->assertSame($dummy, $context->last());
|
||||
$this->assertSame($dummy, $context->pop());
|
||||
$this->assertFalse($context->last());
|
||||
|
||||
$obj = new StdClass;
|
||||
$obj = new StdClass();
|
||||
$context->push($dummy);
|
||||
$this->assertSame($dummy, $context->last());
|
||||
$context->push($obj);
|
||||
@@ -57,11 +57,11 @@ class Mustache_Test_ContextTest extends PHPUnit_Framework_TestCase
|
||||
|
||||
public function testFind()
|
||||
{
|
||||
$context = new Mustache_Context;
|
||||
$context = new Mustache_Context();
|
||||
|
||||
$dummy = new Mustache_Test_TestDummy;
|
||||
$dummy = new Mustache_Test_TestDummy();
|
||||
|
||||
$obj = new StdClass;
|
||||
$obj = new StdClass();
|
||||
$obj->name = 'obj';
|
||||
|
||||
$arr = array(
|
||||
@@ -112,7 +112,7 @@ class Mustache_Test_ContextTest extends PHPUnit_Framework_TestCase
|
||||
|
||||
public function testAccessorPriority()
|
||||
{
|
||||
$context = new Mustache_Context(new Mustache_Test_AllTheThings);
|
||||
$context = new Mustache_Context(new Mustache_Test_AllTheThings());
|
||||
|
||||
$this->assertEquals('win', $context->find('foo'), 'method beats property');
|
||||
$this->assertEquals('win', $context->find('bar'), 'property beats ArrayAccess');
|
||||
|
||||
@@ -17,8 +17,8 @@ class Mustache_Test_EngineTest extends Mustache_Test_FunctionalTestCase
|
||||
public function testConstructor()
|
||||
{
|
||||
$logger = new Mustache_Logger_StreamLogger(tmpfile());
|
||||
$loader = new Mustache_Loader_StringLoader;
|
||||
$partialsLoader = new Mustache_Loader_ArrayLoader;
|
||||
$loader = new Mustache_Loader_StringLoader();
|
||||
$partialsLoader = new Mustache_Loader_ArrayLoader();
|
||||
$mustache = new Mustache_Engine(array(
|
||||
'template_class_prefix' => '__whot__',
|
||||
'cache' => self::$tempDir,
|
||||
@@ -36,6 +36,7 @@ class Mustache_Test_EngineTest extends Mustache_Test_FunctionalTestCase
|
||||
'escape' => 'strtoupper',
|
||||
'entity_flags' => ENT_QUOTES,
|
||||
'charset' => 'ISO-8859-1',
|
||||
'pragmas' => array(Mustache_Engine::PRAGMA_FILTERS),
|
||||
));
|
||||
|
||||
$this->assertSame($logger, $mustache->getLogger());
|
||||
@@ -50,6 +51,7 @@ class Mustache_Test_EngineTest extends Mustache_Test_FunctionalTestCase
|
||||
$this->assertTrue($mustache->hasHelper('bar'));
|
||||
$this->assertFalse($mustache->hasHelper('baz'));
|
||||
$this->assertInstanceOf('Mustache_Cache_FilesystemCache', $mustache->getCache());
|
||||
$this->assertEquals(array(Mustache_Engine::PRAGMA_FILTERS), $mustache->getPragmas());
|
||||
}
|
||||
|
||||
public static function getFoo()
|
||||
@@ -67,7 +69,7 @@ class Mustache_Test_EngineTest extends Mustache_Test_FunctionalTestCase
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$mustache = new MustacheStub;
|
||||
$mustache = new MustacheStub();
|
||||
$mustache->template = $template;
|
||||
|
||||
$template->expects($this->once())
|
||||
@@ -82,11 +84,11 @@ class Mustache_Test_EngineTest extends Mustache_Test_FunctionalTestCase
|
||||
public function testSettingServices()
|
||||
{
|
||||
$logger = new Mustache_Logger_StreamLogger(tmpfile());
|
||||
$loader = new Mustache_Loader_StringLoader;
|
||||
$tokenizer = new Mustache_Tokenizer;
|
||||
$parser = new Mustache_Parser;
|
||||
$compiler = new Mustache_Compiler;
|
||||
$mustache = new Mustache_Engine;
|
||||
$loader = new Mustache_Loader_StringLoader();
|
||||
$tokenizer = new Mustache_Tokenizer();
|
||||
$parser = new Mustache_Parser();
|
||||
$compiler = new Mustache_Compiler();
|
||||
$mustache = new Mustache_Engine();
|
||||
$cache = new Mustache_Cache_FilesystemCache(self::$tempDir);
|
||||
|
||||
$this->assertNotSame($logger, $mustache->getLogger());
|
||||
@@ -179,7 +181,7 @@ class Mustache_Test_EngineTest extends Mustache_Test_FunctionalTestCase
|
||||
public function testImmutablePartialsLoadersThrowException()
|
||||
{
|
||||
$mustache = new Mustache_Engine(array(
|
||||
'partials_loader' => new Mustache_Loader_StringLoader,
|
||||
'partials_loader' => new Mustache_Loader_StringLoader(),
|
||||
));
|
||||
|
||||
$mustache->setPartials(array('foo' => '{{ foo }}'));
|
||||
@@ -243,7 +245,7 @@ class Mustache_Test_EngineTest extends Mustache_Test_FunctionalTestCase
|
||||
*/
|
||||
public function testSetHelpersThrowsExceptions()
|
||||
{
|
||||
$mustache = new Mustache_Engine;
|
||||
$mustache = new Mustache_Engine();
|
||||
$mustache->setHelpers('monkeymonkeymonkey');
|
||||
}
|
||||
|
||||
@@ -252,8 +254,8 @@ class Mustache_Test_EngineTest extends Mustache_Test_FunctionalTestCase
|
||||
*/
|
||||
public function testSetLoggerThrowsExceptions()
|
||||
{
|
||||
$mustache = new Mustache_Engine;
|
||||
$mustache->setLogger(new StdClass);
|
||||
$mustache = new Mustache_Engine();
|
||||
$mustache->setLogger(new StdClass());
|
||||
}
|
||||
|
||||
public function testLoadPartialCascading()
|
||||
@@ -319,6 +321,16 @@ class Mustache_Test_EngineTest extends Mustache_Test_FunctionalTestCase
|
||||
$this->assertContains("WARNING: Partial not found: \"bar\"", $log);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException Mustache_Exception_InvalidArgumentException
|
||||
*/
|
||||
public function testUnknownPragmaThrowsException()
|
||||
{
|
||||
new Mustache_Engine(array(
|
||||
'pragmas' => array('UNKNOWN')
|
||||
));
|
||||
}
|
||||
|
||||
private function getLoggedMustache($level = Mustache_Logger::ERROR)
|
||||
{
|
||||
$name = tempnam(sys_get_temp_dir(), 'mustache-test');
|
||||
|
||||
@@ -19,7 +19,7 @@ class Mustache_Test_FiveThree_Functional_ClosureQuirksTest extends PHPUnit_Frame
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
$this->mustache = new Mustache_Engine;
|
||||
$this->mustache = new Mustache_Engine();
|
||||
}
|
||||
|
||||
public function testClosuresDontLikeItWhenYouTouchTheirProperties()
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Mustache.php.
|
||||
*
|
||||
* (c) 2010-2014 Justin Hileman
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @group pragmas
|
||||
* @group functional
|
||||
*/
|
||||
class Mustache_Test_FiveThree_Functional_EngineTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider pragmaData
|
||||
*/
|
||||
public function testPragmasConstructorOption($pragmas, $helpers, $data, $tpl, $expect)
|
||||
{
|
||||
$mustache = new Mustache_Engine(array(
|
||||
'pragmas' => $pragmas,
|
||||
'helpers' => $helpers,
|
||||
));
|
||||
|
||||
$this->assertEquals($expect, $mustache->render($tpl, $data));
|
||||
}
|
||||
|
||||
public function pragmaData()
|
||||
{
|
||||
$helpers = array(
|
||||
'longdate' => function (\DateTime $value) {
|
||||
return $value->format('Y-m-d h:m:s');
|
||||
}
|
||||
);
|
||||
|
||||
$data = array(
|
||||
'date' => new DateTime('1/1/2000', new DateTimeZone('UTC')),
|
||||
);
|
||||
|
||||
$tpl = '{{ date | longdate }}';
|
||||
|
||||
return array(
|
||||
array(array(Mustache_Engine::PRAGMA_FILTERS), $helpers, $data, $tpl, '2000-01-01 12:01:00'),
|
||||
array(array(), $helpers, $data, $tpl, '' ),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -19,7 +19,7 @@ class Mustache_Test_FiveThree_Functional_FiltersTest extends PHPUnit_Framework_T
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
$this->mustache = new Mustache_Engine;
|
||||
$this->mustache = new Mustache_Engine();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -71,7 +71,7 @@ class Mustache_Test_FiveThree_Functional_FiltersTest extends PHPUnit_Framework_T
|
||||
return sprintf('[[%s]]', $value);
|
||||
});
|
||||
|
||||
$foo = new \StdClass;
|
||||
$foo = new \StdClass();
|
||||
$foo->date = new DateTime('1/1/2000', new DateTimeZone("UTC"));
|
||||
|
||||
$this->assertEquals('[[2000-01-01 12:01:00]]', $tpl->render($foo));
|
||||
|
||||
@@ -19,14 +19,14 @@ class Mustache_Test_FiveThree_Functional_HigherOrderSectionsTest extends PHPUnit
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
$this->mustache = new Mustache_Engine;
|
||||
$this->mustache = new Mustache_Engine();
|
||||
}
|
||||
|
||||
public function testAnonymousFunctionSectionCallback()
|
||||
{
|
||||
$tpl = $this->mustache->loadTemplate('{{#wrapper}}{{name}}{{/wrapper}}');
|
||||
|
||||
$foo = new Mustache_Test_FiveThree_Functional_Foo;
|
||||
$foo = new Mustache_Test_FiveThree_Functional_Foo();
|
||||
$foo->name = 'Mario';
|
||||
$foo->wrapper = function ($text) {
|
||||
return sprintf('<div class="anonymous">%s</div>', $text);
|
||||
@@ -40,7 +40,7 @@ class Mustache_Test_FiveThree_Functional_HigherOrderSectionsTest extends PHPUnit
|
||||
$one = $this->mustache->loadTemplate('{{name}}');
|
||||
$two = $this->mustache->loadTemplate('{{#wrap}}{{name}}{{/wrap}}');
|
||||
|
||||
$foo = new Mustache_Test_FiveThree_Functional_Foo;
|
||||
$foo = new Mustache_Test_FiveThree_Functional_Foo();
|
||||
$foo->name = 'Luigi';
|
||||
|
||||
$this->assertEquals($foo->name, $one->render($foo));
|
||||
|
||||
@@ -19,7 +19,7 @@ class Mustache_Test_FiveThree_Functional_LambdaHelperTest extends PHPUnit_Framew
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
$this->mustache = new Mustache_Engine;
|
||||
$this->mustache = new Mustache_Engine();
|
||||
}
|
||||
|
||||
public function testSectionLambdaHelper()
|
||||
@@ -27,7 +27,7 @@ class Mustache_Test_FiveThree_Functional_LambdaHelperTest extends PHPUnit_Framew
|
||||
$one = $this->mustache->loadTemplate('{{name}}');
|
||||
$two = $this->mustache->loadTemplate('{{#lambda}}{{name}}{{/lambda}}');
|
||||
|
||||
$foo = new StdClass;
|
||||
$foo = new StdClass();
|
||||
$foo->name = 'Mario';
|
||||
$foo->lambda = function ($text, $mustache) {
|
||||
return strtoupper($mustache->render($text));
|
||||
|
||||
@@ -23,7 +23,7 @@ class Mustache_Test_FiveThree_Functional_StrictCallablesTest extends PHPUnit_Fra
|
||||
$mustache = new Mustache_Engine(array('strict_callables' => $strict));
|
||||
$tpl = $mustache->loadTemplate('{{# section }}{{ name }}{{/ section }}');
|
||||
|
||||
$data = new StdClass;
|
||||
$data = new StdClass();
|
||||
$data->name = $name;
|
||||
$data->section = $section;
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ class Mustache_Test_Functional_CallTest extends PHPUnit_Framework_TestCase
|
||||
|
||||
public function testCallEatsContext()
|
||||
{
|
||||
$m = new Mustache_Engine;
|
||||
$m = new Mustache_Engine();
|
||||
$tpl = $m->loadTemplate('{{# foo }}{{ label }}: {{ name }}{{/ foo }}');
|
||||
|
||||
$foo = new Mustache_Test_Functional_ClassWithCall();
|
||||
|
||||
@@ -92,8 +92,9 @@ class Mustache_Test_Functional_ExamplesTest extends PHPUnit_Framework_TestCase
|
||||
// load other files
|
||||
switch ($info['extension']) {
|
||||
case 'php':
|
||||
require_once($fullpath);
|
||||
$context = new $info['filename'];
|
||||
require_once $fullpath;
|
||||
$className = $info['filename'];
|
||||
$context = new $className();
|
||||
break;
|
||||
|
||||
case 'mustache':
|
||||
|
||||
@@ -19,7 +19,7 @@ class Mustache_Test_Functional_HigherOrderSectionsTest extends Mustache_Test_Fun
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
$this->mustache = new Mustache_Engine;
|
||||
$this->mustache = new Mustache_Engine();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -32,10 +32,10 @@ class Mustache_Test_Functional_HigherOrderSectionsTest extends Mustache_Test_Fun
|
||||
|
||||
public function sectionCallbackData()
|
||||
{
|
||||
$foo = new Mustache_Test_Functional_Foo;
|
||||
$foo = new Mustache_Test_Functional_Foo();
|
||||
$foo->doublewrap = array($foo, 'wrapWithBoth');
|
||||
|
||||
$bar = new Mustache_Test_Functional_Foo;
|
||||
$bar = new Mustache_Test_Functional_Foo();
|
||||
$bar->trimmer = array(get_class($bar), 'staticTrim');
|
||||
|
||||
return array(
|
||||
@@ -48,7 +48,7 @@ class Mustache_Test_Functional_HigherOrderSectionsTest extends Mustache_Test_Fun
|
||||
{
|
||||
$tpl = $this->mustache->loadTemplate('{{#trim}} {{name}} {{/trim}}');
|
||||
|
||||
$foo = new Mustache_Test_Functional_Foo;
|
||||
$foo = new Mustache_Test_Functional_Foo();
|
||||
|
||||
$data = array(
|
||||
'name' => 'Bob',
|
||||
@@ -81,7 +81,7 @@ class Mustache_Test_Functional_HigherOrderSectionsTest extends Mustache_Test_Fun
|
||||
|
||||
$tpl = $mustache->loadTemplate('{{#wrap}}NAME{{/wrap}}');
|
||||
|
||||
$foo = new Mustache_Test_Functional_Foo;
|
||||
$foo = new Mustache_Test_Functional_Foo();
|
||||
$foo->wrap = array($foo, 'wrapWithEm');
|
||||
|
||||
$this->assertEquals('<em>NAME</em>', $tpl->render($foo));
|
||||
@@ -96,7 +96,7 @@ class Mustache_Test_Functional_HigherOrderSectionsTest extends Mustache_Test_Fun
|
||||
|
||||
$tpl = $mustache->loadTemplate('{{#wrap}}{{name}}{{/wrap}}');
|
||||
|
||||
$foo = new Mustache_Test_Functional_Foo;
|
||||
$foo = new Mustache_Test_Functional_Foo();
|
||||
$foo->wrap = array($foo, 'wrapWithEm');
|
||||
|
||||
$this->assertEquals('<em>' . $foo->name . '</em>', $tpl->render($foo));
|
||||
@@ -115,7 +115,7 @@ class Mustache_Test_Functional_HigherOrderSectionsTest extends Mustache_Test_Fun
|
||||
));
|
||||
|
||||
$tpl = $mustache->loadTemplate('{{#wrap}}{{name}}{{/wrap}}');
|
||||
$foo = new Mustache_Test_Functional_Foo;
|
||||
$foo = new Mustache_Test_Functional_Foo();
|
||||
$foo->wrap = array($foo, 'wrapWithEm');
|
||||
$this->assertEquals('<em>' . $foo->name . '</em>', $tpl->render($foo));
|
||||
$this->assertCount($expect, glob($cacheDir . '/*.php'));
|
||||
|
||||
@@ -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(array(
|
||||
'pragmas' => array(Mustache_Engine::PRAGMA_BLOCKS),
|
||||
));
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
@@ -20,7 +20,7 @@ class Mustache_Test_Functional_MustacheInjectionTest extends PHPUnit_Framework_T
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
$this->mustache = new Mustache_Engine;
|
||||
$this->mustache = new Mustache_Engine();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Mustache.php.
|
||||
*
|
||||
* (c) 2010-2014 Justin Hileman
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @group functional
|
||||
* @group partials
|
||||
*/
|
||||
class Mustache_Test_Functional_NestedPartialIndentTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider partialsAndStuff
|
||||
*/
|
||||
public function testNestedPartialsAreIndentedProperly($src, array $partials, $expected)
|
||||
{
|
||||
$m = new Mustache_Engine(array(
|
||||
'partials' => $partials
|
||||
));
|
||||
$tpl = $m->loadTemplate($src);
|
||||
$this->assertEquals($expected, $tpl->render());
|
||||
}
|
||||
|
||||
public function partialsAndStuff()
|
||||
{
|
||||
$partials = array(
|
||||
'a' => ' {{> b }}',
|
||||
'b' => ' {{> d }}',
|
||||
'c' => ' {{> d }}{{> d }}',
|
||||
'd' => 'D!',
|
||||
);
|
||||
|
||||
return array(
|
||||
array(' {{> a }}', $partials, ' D!'),
|
||||
array(' {{> b }}', $partials, ' D!'),
|
||||
array(' {{> c }}', $partials, ' D!D!'),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -19,13 +19,13 @@ class Mustache_Test_Functional_ObjectSectionTest extends PHPUnit_Framework_TestC
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
$this->mustache = new Mustache_Engine;
|
||||
$this->mustache = new Mustache_Engine();
|
||||
}
|
||||
|
||||
public function testBasicObject()
|
||||
{
|
||||
$tpl = $this->mustache->loadTemplate('{{#foo}}{{name}}{{/foo}}');
|
||||
$this->assertEquals('Foo', $tpl->render(new Mustache_Test_Functional_Alpha));
|
||||
$this->assertEquals('Foo', $tpl->render(new Mustache_Test_Functional_Alpha()));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -34,7 +34,7 @@ class Mustache_Test_Functional_ObjectSectionTest extends PHPUnit_Framework_TestC
|
||||
public function testObjectWithGet()
|
||||
{
|
||||
$tpl = $this->mustache->loadTemplate('{{#foo}}{{name}}{{/foo}}');
|
||||
$this->assertEquals('Foo', $tpl->render(new Mustache_Test_Functional_Beta));
|
||||
$this->assertEquals('Foo', $tpl->render(new Mustache_Test_Functional_Beta()));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -43,14 +43,14 @@ class Mustache_Test_Functional_ObjectSectionTest extends PHPUnit_Framework_TestC
|
||||
public function testSectionObjectWithGet()
|
||||
{
|
||||
$tpl = $this->mustache->loadTemplate('{{#bar}}{{#foo}}{{name}}{{/foo}}{{/bar}}');
|
||||
$this->assertEquals('Foo', $tpl->render(new Mustache_Test_Functional_Gamma));
|
||||
$this->assertEquals('Foo', $tpl->render(new Mustache_Test_Functional_Gamma()));
|
||||
}
|
||||
|
||||
public function testSectionObjectWithFunction()
|
||||
{
|
||||
$tpl = $this->mustache->loadTemplate('{{#foo}}{{name}}{{/foo}}');
|
||||
$alpha = new Mustache_Test_Functional_Alpha;
|
||||
$alpha->foo = new Mustache_Test_Functional_Delta;
|
||||
$alpha = new Mustache_Test_Functional_Alpha();
|
||||
$alpha->foo = new Mustache_Test_Functional_Delta();
|
||||
$this->assertEquals('Foo', $tpl->render($alpha));
|
||||
}
|
||||
}
|
||||
@@ -95,7 +95,7 @@ class Mustache_Test_Functional_Gamma
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->bar = new Mustache_Test_Functional_Beta;
|
||||
$this->bar = new Mustache_Test_Functional_Beta();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ class Mustache_Test_HelperCollectionTest extends PHPUnit_Framework_TestCase
|
||||
$foo = array($this, 'getFoo');
|
||||
$bar = 'BAR';
|
||||
|
||||
$helpers = new Mustache_HelperCollection;
|
||||
$helpers = new Mustache_HelperCollection();
|
||||
$this->assertTrue($helpers->isEmpty());
|
||||
$this->assertFalse($helpers->has('foo'));
|
||||
$this->assertFalse($helpers->has('bar'));
|
||||
@@ -61,7 +61,7 @@ class Mustache_Test_HelperCollectionTest extends PHPUnit_Framework_TestCase
|
||||
$foo = array($this, 'getFoo');
|
||||
$bar = 'BAR';
|
||||
|
||||
$helpers = new Mustache_HelperCollection;
|
||||
$helpers = new Mustache_HelperCollection();
|
||||
$this->assertTrue($helpers->isEmpty());
|
||||
$this->assertFalse($helpers->has('foo'));
|
||||
$this->assertFalse($helpers->has('bar'));
|
||||
|
||||
@@ -46,7 +46,7 @@ class Mustache_Test_Loader_ArrayLoaderTest extends PHPUnit_Framework_TestCase
|
||||
*/
|
||||
public function testMissingTemplatesThrowExceptions()
|
||||
{
|
||||
$loader = new Mustache_Loader_ArrayLoader;
|
||||
$loader = new Mustache_Loader_ArrayLoader();
|
||||
$loader->load('not_a_real_template');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ class Mustache_Test_Loader_StringLoaderTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testLoadTemplates()
|
||||
{
|
||||
$loader = new Mustache_Loader_StringLoader;
|
||||
$loader = new Mustache_Loader_StringLoader();
|
||||
|
||||
$this->assertEquals('foo', $loader->load('foo'));
|
||||
$this->assertEquals('{{ bar }}', $loader->load('{{ bar }}'));
|
||||
|
||||
@@ -16,7 +16,7 @@ class Mustache_Test_Logger_AbstractLoggerTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testEverything()
|
||||
{
|
||||
$logger = new Mustache_Test_Logger_TestLogger;
|
||||
$logger = new Mustache_Test_Logger_TestLogger();
|
||||
|
||||
$logger->emergency('emergency message');
|
||||
$logger->alert('alert message');
|
||||
|
||||
@@ -20,7 +20,7 @@ class Mustache_Test_ParserTest extends PHPUnit_Framework_TestCase
|
||||
*/
|
||||
public function testParse($tokens, $expected)
|
||||
{
|
||||
$parser = new Mustache_Parser;
|
||||
$parser = new Mustache_Parser();
|
||||
$this->assertEquals($expected, $parser->parse($tokens));
|
||||
}
|
||||
|
||||
@@ -88,6 +88,7 @@ class Mustache_Test_ParserTest extends PHPUnit_Framework_TestCase
|
||||
Mustache_Tokenizer::VALUE => 'bar'
|
||||
),
|
||||
),
|
||||
|
||||
array(
|
||||
array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
|
||||
@@ -116,6 +117,202 @@ class Mustache_Test_ParserTest extends PHPUnit_Framework_TestCase
|
||||
),
|
||||
),
|
||||
|
||||
// This *would* be an invalid inheritance parse tree, but that pragma
|
||||
// isn't enabled so it'll thunk it back into an "escaped" token:
|
||||
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(
|
||||
array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_ESCAPED,
|
||||
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(
|
||||
array(
|
||||
array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
|
||||
Mustache_Tokenizer::LINE => 0,
|
||||
Mustache_Tokenizer::VALUE => " ",
|
||||
),
|
||||
array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_DELIM_CHANGE,
|
||||
Mustache_Tokenizer::LINE => 0,
|
||||
),
|
||||
array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
|
||||
Mustache_Tokenizer::LINE => 0,
|
||||
Mustache_Tokenizer::VALUE => " \n",
|
||||
),
|
||||
array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_ESCAPED,
|
||||
Mustache_Tokenizer::NAME => 'foo',
|
||||
Mustache_Tokenizer::OTAG => '[[',
|
||||
Mustache_Tokenizer::CTAG => ']]',
|
||||
Mustache_Tokenizer::LINE => 1,
|
||||
),
|
||||
),
|
||||
array(
|
||||
array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_ESCAPED,
|
||||
Mustache_Tokenizer::NAME => 'foo',
|
||||
Mustache_Tokenizer::OTAG => '[[',
|
||||
Mustache_Tokenizer::CTAG => ']]',
|
||||
Mustache_Tokenizer::LINE => 1,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getInheritanceTokenSets
|
||||
*/
|
||||
public function testParseWithInheritance($tokens, $expected)
|
||||
{
|
||||
$parser = new Mustache_Parser();
|
||||
$parser->setPragmas(array(Mustache_Engine::PRAGMA_BLOCKS));
|
||||
$this->assertEquals($expected, $parser->parse($tokens));
|
||||
}
|
||||
|
||||
public function getInheritanceTokenSets()
|
||||
{
|
||||
return array(
|
||||
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'
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -125,7 +322,7 @@ class Mustache_Test_ParserTest extends PHPUnit_Framework_TestCase
|
||||
*/
|
||||
public function testParserThrowsExceptions($tokens)
|
||||
{
|
||||
$parser = new Mustache_Parser;
|
||||
$parser = new Mustache_Parser();
|
||||
$parser->parse($tokens);
|
||||
}
|
||||
|
||||
@@ -197,6 +394,33 @@ class Mustache_Test_ParserTest extends PHPUnit_Framework_TestCase
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
// This *would* be a valid inheritance parse tree, but that pragma
|
||||
// isn't enabled here so it's going to fail :)
|
||||
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,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ abstract class Mustache_Test_SpecTestCase extends PHPUnit_Framework_TestCase
|
||||
|
||||
public static function setUpBeforeClass()
|
||||
{
|
||||
self::$mustache = new Mustache_Engine;
|
||||
self::$mustache = new Mustache_Engine();
|
||||
}
|
||||
|
||||
protected static function loadTemplate($source, $partials)
|
||||
@@ -42,7 +42,7 @@ abstract class Mustache_Test_SpecTestCase extends PHPUnit_Framework_TestCase
|
||||
}
|
||||
|
||||
$data = array();
|
||||
$yaml = new sfYamlParser;
|
||||
$yaml = new sfYamlParser();
|
||||
$file = file_get_contents($filename);
|
||||
|
||||
// @hack: pre-process the 'lambdas' spec so the Symfony YAML parser doesn't complain.
|
||||
|
||||
@@ -16,7 +16,7 @@ class Mustache_Test_TemplateTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testConstructor()
|
||||
{
|
||||
$mustache = new Mustache_Engine;
|
||||
$mustache = new Mustache_Engine();
|
||||
$template = new Mustache_Test_TemplateStub($mustache);
|
||||
$this->assertSame($mustache, $template->getMustache());
|
||||
}
|
||||
@@ -24,10 +24,10 @@ class Mustache_Test_TemplateTest extends PHPUnit_Framework_TestCase
|
||||
public function testRendering()
|
||||
{
|
||||
$rendered = '<< wheee >>';
|
||||
$mustache = new Mustache_Engine;
|
||||
$mustache = new Mustache_Engine();
|
||||
$template = new Mustache_Test_TemplateStub($mustache);
|
||||
$template->rendered = $rendered;
|
||||
$context = new Mustache_Context;
|
||||
$context = new Mustache_Context();
|
||||
|
||||
if (version_compare(PHP_VERSION, '5.3.0', '>=')) {
|
||||
$this->assertEquals($rendered, $template());
|
||||
|
||||
@@ -20,7 +20,7 @@ class Mustache_Test_TokenizerTest extends PHPUnit_Framework_TestCase
|
||||
*/
|
||||
public function testScan($text, $delimiters, $expected)
|
||||
{
|
||||
$tokenizer = new Mustache_Tokenizer;
|
||||
$tokenizer = new Mustache_Tokenizer();
|
||||
$this->assertSame($expected, $tokenizer->scan($text, $delimiters));
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ class Mustache_Test_TokenizerTest extends PHPUnit_Framework_TestCase
|
||||
*/
|
||||
public function testUnevenBracesThrowExceptions()
|
||||
{
|
||||
$tokenizer = new Mustache_Tokenizer;
|
||||
$tokenizer = new Mustache_Tokenizer();
|
||||
|
||||
$text = "{{{ name }}";
|
||||
$tokenizer->scan($text, null);
|
||||
@@ -40,7 +40,7 @@ class Mustache_Test_TokenizerTest extends PHPUnit_Framework_TestCase
|
||||
*/
|
||||
public function testUnevenBracesWithCustomDelimiterThrowExceptions()
|
||||
{
|
||||
$tokenizer = new Mustache_Tokenizer;
|
||||
$tokenizer = new Mustache_Tokenizer();
|
||||
|
||||
$text = "<%{ name %>";
|
||||
$tokenizer->scan($text, "<% %>");
|
||||
@@ -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,
|
||||
)
|
||||
)
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
|
||||
class Filters
|
||||
{
|
||||
public $states = array(
|
||||
'al' => 'Alabama',
|
||||
'ak' => 'Alaska',
|
||||
'az' => 'Arizona',
|
||||
'ar' => 'Arkansas',
|
||||
'ca' => 'California',
|
||||
'co' => 'Colorado',
|
||||
'ct' => 'Connecticut',
|
||||
'de' => 'Delaware',
|
||||
'fl' => 'Florida',
|
||||
'ga' => 'Georgia',
|
||||
'hi' => 'Hawaii',
|
||||
'id' => 'Idaho',
|
||||
'il' => 'Illinois',
|
||||
'in' => 'Indiana',
|
||||
'ia' => 'Iowa',
|
||||
'ks' => 'Kansas',
|
||||
'ky' => 'Kentucky',
|
||||
'la' => 'Louisiana',
|
||||
'me' => 'Maine',
|
||||
'md' => 'Maryland',
|
||||
'ma' => 'Massachusetts',
|
||||
'mi' => 'Michigan',
|
||||
'mn' => 'Minnesota',
|
||||
'ms' => 'Mississippi',
|
||||
'mo' => 'Missouri',
|
||||
'mt' => 'Montana',
|
||||
'ne' => 'Nebraska',
|
||||
'nv' => 'Nevada',
|
||||
'nh' => 'New Hampshire',
|
||||
'nj' => 'New Jersey',
|
||||
'nm' => 'New Mexico',
|
||||
'ny' => 'New York',
|
||||
'nc' => 'North Carolina',
|
||||
'nd' => 'North Dakota',
|
||||
'oh' => 'Ohio',
|
||||
'ok' => 'Oklahoma',
|
||||
'or' => 'Oregon',
|
||||
'pa' => 'Pennsylvania',
|
||||
'ri' => 'Rhode Island',
|
||||
'sc' => 'South Carolina',
|
||||
'sd' => 'South Dakota',
|
||||
'tn' => 'Tennessee',
|
||||
'tx' => 'Texas',
|
||||
'ut' => 'Utah',
|
||||
'vt' => 'Vermont',
|
||||
'va' => 'Virginia',
|
||||
'wa' => 'Washington',
|
||||
'wv' => 'West Virginia',
|
||||
'wi' => 'Wisconsin',
|
||||
'wy' => 'Wyoming',
|
||||
);
|
||||
|
||||
// The next few functions are ugly, because they have to work in PHP 5.2...
|
||||
// for everyone who doesn't have to support 5.2, please, for the love, make
|
||||
// your ViewModel return closures rather than `array($this, '...')`
|
||||
//
|
||||
// :)
|
||||
|
||||
public function upcase()
|
||||
{
|
||||
return array($this, '_upcase');
|
||||
}
|
||||
|
||||
public function _upcase($val)
|
||||
{
|
||||
return strtoupper($val);
|
||||
}
|
||||
|
||||
public function eachPair()
|
||||
{
|
||||
return array($this, '_eachPair');
|
||||
}
|
||||
|
||||
public function _eachPair($val)
|
||||
{
|
||||
$ret = array();
|
||||
foreach ($val as $key => $value) {
|
||||
array_push($ret, compact('key', 'value'));
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{{%FILTERS}}
|
||||
{{# states | eachPair }}
|
||||
{{ key | upcase }}: {{ value }}
|
||||
{{/ states }}
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
AL: Alabama
|
||||
AK: Alaska
|
||||
AZ: Arizona
|
||||
AR: Arkansas
|
||||
CA: California
|
||||
CO: Colorado
|
||||
CT: Connecticut
|
||||
DE: Delaware
|
||||
FL: Florida
|
||||
GA: Georgia
|
||||
HI: Hawaii
|
||||
ID: Idaho
|
||||
IL: Illinois
|
||||
IN: Indiana
|
||||
IA: Iowa
|
||||
KS: Kansas
|
||||
KY: Kentucky
|
||||
LA: Louisiana
|
||||
ME: Maine
|
||||
MD: Maryland
|
||||
MA: Massachusetts
|
||||
MI: Michigan
|
||||
MN: Minnesota
|
||||
MS: Mississippi
|
||||
MO: Missouri
|
||||
MT: Montana
|
||||
NE: Nebraska
|
||||
NV: Nevada
|
||||
NH: New Hampshire
|
||||
NJ: New Jersey
|
||||
NM: New Mexico
|
||||
NY: New York
|
||||
NC: North Carolina
|
||||
ND: North Dakota
|
||||
OH: Ohio
|
||||
OK: Oklahoma
|
||||
OR: Oregon
|
||||
PA: Pennsylvania
|
||||
RI: Rhode Island
|
||||
SC: South Carolina
|
||||
SD: South Dakota
|
||||
TN: Tennessee
|
||||
TX: Texas
|
||||
UT: Utah
|
||||
VT: Vermont
|
||||
VA: Virginia
|
||||
WA: Washington
|
||||
WV: West Virginia
|
||||
WI: Wisconsin
|
||||
WY: Wyoming
|
||||
@@ -21,7 +21,7 @@ class MagicObject
|
||||
|
||||
public function __get($key)
|
||||
{
|
||||
return isset($this->_data[$key]) ? $this->_data[$key] : NULL;
|
||||
return isset($this->_data[$key]) ? $this->_data[$key] : null;
|
||||
}
|
||||
|
||||
public function __isset($key)
|
||||
|
||||
@@ -6,7 +6,7 @@ class SectionObjects
|
||||
|
||||
public function middle()
|
||||
{
|
||||
return new SectionObject;
|
||||
return new SectionObject();
|
||||
}
|
||||
|
||||
public $final = "Then, surprisingly, it worked the final time.";
|
||||
|
||||
Reference in New Issue
Block a user