Merge branch 'dev' into feature/higher-order-sections

Conflicts:
	Mustache.php
This commit is contained in:
Justin Hileman
2010-08-09 09:41:40 -04:00
16 changed files with 323 additions and 33 deletions
+74 -20
View File
@@ -33,7 +33,45 @@ class Mustache {
// Override charset passed to htmlentities() and htmlspecialchars(). Defaults to UTF-8.
protected $_charset = 'UTF-8';
const PRAGMA_DOT_NOTATION = 'DOT-NOTATION';
/**
* Pragmas are macro-like directives that, when invoked, change the behavior or
* syntax of Mustache.
*
* They should be considered extremely experimental. Most likely their implementation
* will change in the future.
*/
/**
* The {{%DOT-NOTATION}} pragma allows context traversal via dots. Given the following context:
*
* $context = array('foo' => array('bar' => array('baz' => 'qux')));
*
* One could access nested properties using dot notation:
*
* {{%DOT-NOTATION}}{{foo.bar.baz}}
*
* Which would render as `qux`.
*/
const PRAGMA_DOT_NOTATION = 'DOT-NOTATION';
/**
* The {{%IMPLICIT-ITERATOR}} pragma allows access to non-associative array data in an
* iterable section:
*
* $context = array('items' => array('foo', 'bar', 'baz'));
*
* With this template:
*
* {{%IMPLICIT-ITERATOR}}{{#items}}{{.}}{{/items}}
*
* Would render as `foobarbaz`.
*
* {{%IMPLICIT-ITERATOR}} accepts an optional 'iterator' argument which allows implicit
* iterator tags other than {{.}} ...
*
* {{%IMPLICIT-ITERATOR iterator=i}}{{#items}}{{i}}{{/items}}
*/
const PRAGMA_IMPLICIT_ITERATOR = 'IMPLICIT-ITERATOR';
/**
* The {{%UNESCAPED}} pragma swaps the meaning of the {{normal}} and {{{unescaped}}}
@@ -56,6 +94,7 @@ class Mustache {
protected $_pragmasImplemented = array(
self::PRAGMA_DOT_NOTATION,
self::PRAGMA_IMPLICIT_ITERATOR,
self::PRAGMA_UNESCAPED
);
@@ -188,25 +227,40 @@ class Mustache {
// regular section
case '#':
if ($val) {
// higher order sections
if (is_callable($val)) {
$content = call_user_func($val, $content);
$replace .= $this->_renderTemplate($content);
} else if ($this->_varIsIterable($val)) {
foreach ($val as $local_context) {
$this->_pushContext($local_context);
$replace .= $this->_renderTemplate($content);
$this->_popContext();
// higher order sections
if (is_callable($val)) {
$content = call_user_func($val, $content);
$replace .= $this->_renderTemplate($content);
} else if ($this->_varIsIterable($val)) {
if ($this->_hasPragma(self::PRAGMA_IMPLICIT_ITERATOR)) {
if ($opt = $this->_getPragmaOptions(self::PRAGMA_IMPLICIT_ITERATOR)) {
$iterator = $opt['iterator'];
} else {
$iterator = '.';
}
} else {
if (is_array($val) || is_object($val)) {
$this->_pushContext($val);
$replace .= $this->_renderTemplate($content);
$this->_popContext();
$iterator = false;
}
foreach ($val as $local_context) {
if ($iterator) {
$iterator_context = array($iterator => $local_context);
$this->_pushContext($iterator_context);
} else {
$replace .= $content;
$this->_pushContext($local_context);
}
$replace .= $this->_renderTemplate($content);
$this->_popContext();
}
} else if ($val) {
if (is_array($val) || is_object($val)) {
$this->_pushContext($val);
$replace .= $this->_renderTemplate($content);
$this->_popContext();
} else {
$replace .= $content;
}
}
break;
@@ -297,11 +351,11 @@ class Mustache {
* @throws MustacheException Unknown pragma
*/
protected function _getPragmaOptions($pragma_name) {
if (!$this->_hasPragma()) {
if (!$this->_hasPragma($pragma_name)) {
throw new MustacheException('Unknown pragma: ' . $pragma_name, MustacheException::UNKNOWN_PRAGMA);
}
return $this->_localPragmas[$pragma_name];
return (is_array($this->_localPragmas[$pragma_name])) ? $this->_localPragmas[$pragma_name] : array();
}
@@ -527,7 +581,7 @@ class Mustache {
* @return string
*/
protected function _getVariable($tag_name) {
if ($this->_hasPragma(self::PRAGMA_DOT_NOTATION)) {
if ($this->_hasPragma(self::PRAGMA_DOT_NOTATION) && $tag_name != '.') {
$chunks = explode('.', $tag_name);
$first = array_shift($chunks);
@@ -603,7 +657,7 @@ class Mustache {
* @return bool
*/
protected function _varIsIterable($var) {
return is_object($var) || (is_array($var) && !array_diff_key($var, array_keys(array_keys($var))));
return $var instanceof Traversable || (is_array($var) && !array_diff_key($var, array_keys(array_keys($var))));
}
}