|
@@ -25,11 +25,18 @@ class Mustache {
|
|
|
// Override charset passed to htmlentities() and htmlspecialchars(). Defaults to UTF-8.
|
|
// Override charset passed to htmlentities() and htmlspecialchars(). Defaults to UTF-8.
|
|
|
protected $charset = 'UTF-8';
|
|
protected $charset = 'UTF-8';
|
|
|
|
|
|
|
|
|
|
+ const PRAGMA_DOT_NOTATION = 'DOT-NOTATION';
|
|
|
|
|
+
|
|
|
protected $tagRegEx;
|
|
protected $tagRegEx;
|
|
|
|
|
|
|
|
protected $template = '';
|
|
protected $template = '';
|
|
|
protected $context = array();
|
|
protected $context = array();
|
|
|
protected $partials = array();
|
|
protected $partials = array();
|
|
|
|
|
+ protected $pragmas = array();
|
|
|
|
|
+
|
|
|
|
|
+ protected $pragmasImplemented = array(
|
|
|
|
|
+ self::PRAGMA_DOT_NOTATION
|
|
|
|
|
+ );
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
* Mustache class constructor.
|
|
* Mustache class constructor.
|
|
@@ -101,6 +108,7 @@ class Mustache {
|
|
|
* @return string Rendered Mustache template.
|
|
* @return string Rendered Mustache template.
|
|
|
*/
|
|
*/
|
|
|
protected function _render($template, &$context) {
|
|
protected function _render($template, &$context) {
|
|
|
|
|
+ $template = $this->renderPragmas($template, $context);
|
|
|
$template = $this->renderSection($template, $context);
|
|
$template = $this->renderSection($template, $context);
|
|
|
return $this->renderTags($template, $context);
|
|
return $this->renderTags($template, $context);
|
|
|
}
|
|
}
|
|
@@ -158,6 +166,74 @@ class Mustache {
|
|
|
return $template;
|
|
return $template;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Initialize pragmas and remove all pragma tags.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @access protected
|
|
|
|
|
+ * @param string $template
|
|
|
|
|
+ * @param array &$context
|
|
|
|
|
+ * @return string
|
|
|
|
|
+ */
|
|
|
|
|
+ protected function renderPragmas($template, &$context) {
|
|
|
|
|
+ // no pragmas
|
|
|
|
|
+ if (strpos($template, $this->otag . '%') === false) {
|
|
|
|
|
+ return $template;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $otag = $this->prepareRegEx($this->otag);
|
|
|
|
|
+ $ctag = $this->prepareRegEx($this->ctag);
|
|
|
|
|
+ $regex = '/' . $otag . '%([\\w_-]+)((?: [\\w]+=[\\w]+)*)' . $ctag . '\\n?/';
|
|
|
|
|
+ return preg_replace_callback($regex, array($this, 'renderPragma'), $template);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * A preg_replace helper to remove {{%PRAGMA}} tags and enable requested pragma.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @access protected
|
|
|
|
|
+ * @param mixed $matches
|
|
|
|
|
+ * @return void
|
|
|
|
|
+ * @throws MustacheException unknown pragma
|
|
|
|
|
+ */
|
|
|
|
|
+ protected function renderPragma($matches) {
|
|
|
|
|
+ $pragma = $matches[0];
|
|
|
|
|
+ $pragma_name = $matches[1];
|
|
|
|
|
+ $options_string = $matches[2];
|
|
|
|
|
+
|
|
|
|
|
+ if (!in_array($pragma_name, $this->pragmasImplemented)) {
|
|
|
|
|
+ throw new MustacheException('Unknown pragma: ' . $pragma_name, MustacheException::UNKNOWN_PRAGMA);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $options = array();
|
|
|
|
|
+ foreach (explode(' ', trim($options_string)) as $o) {
|
|
|
|
|
+ if ($p = trim($o)) {
|
|
|
|
|
+ $p = explode('=', trim($p));
|
|
|
|
|
+ $options[$p[0]] = $p[1];
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (empty($options)) {
|
|
|
|
|
+ $this->pragmas[$pragma_name] = true;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ $this->pragmas[$pragma_name] = $options;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return '';
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ protected function hasPragma($pragma_name) {
|
|
|
|
|
+ if (array_key_exists($pragma_name, $this->pragmas) && $this->pragmas[$pragma_name]) {
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ protected function getPragmaOptions($pragma_name) {
|
|
|
|
|
+ if (!$this->hasPragma()) {
|
|
|
|
|
+ throw new MustacheException('Unknown pragma: ' . $pragma_name, MustacheException::UNKNOWN_PRAGMA);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return $this->pragmas[$pragma_name];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
* Loop through and render individual Mustache tags.
|
|
* Loop through and render individual Mustache tags.
|
|
|
*
|
|
*
|
|
@@ -171,9 +247,11 @@ class Mustache {
|
|
|
return $template;
|
|
return $template;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- $otag = $this->prepareRegEx($this->otag);
|
|
|
|
|
- $ctag = $this->prepareRegEx($this->ctag);
|
|
|
|
|
|
|
+ $otag = $this->prepareRegEx($this->otag);
|
|
|
|
|
+ $ctag = $this->prepareRegEx($this->ctag);
|
|
|
|
|
+
|
|
|
$this->tagRegEx = '/' . $otag . "([#\^\/=!>\\{&])?(.+?)\\1?" . $ctag . "+/";
|
|
$this->tagRegEx = '/' . $otag . "([#\^\/=!>\\{&])?(.+?)\\1?" . $ctag . "+/";
|
|
|
|
|
+
|
|
|
$html = '';
|
|
$html = '';
|
|
|
$matches = array();
|
|
$matches = array();
|
|
|
while (preg_match($this->tagRegEx, $template, $matches, PREG_OFFSET_CAPTURE)) {
|
|
while (preg_match($this->tagRegEx, $template, $matches, PREG_OFFSET_CAPTURE)) {
|
|
@@ -347,6 +425,33 @@ class Mustache {
|
|
|
* @return string
|
|
* @return string
|
|
|
*/
|
|
*/
|
|
|
protected function getVariable($tag_name, &$context) {
|
|
protected function getVariable($tag_name, &$context) {
|
|
|
|
|
+ if ($this->hasPragma(self::PRAGMA_DOT_NOTATION)) {
|
|
|
|
|
+ $chunks = explode('.', $tag_name);
|
|
|
|
|
+ $first = array_shift($chunks);
|
|
|
|
|
+
|
|
|
|
|
+ $ret = $this->_getVariable($first, $context);
|
|
|
|
|
+ while ($next = array_shift($chunks)) {
|
|
|
|
|
+ // Slice off a chunk of context for dot notation traversal.
|
|
|
|
|
+ $c = array($ret);
|
|
|
|
|
+ $ret = $this->_getVariable($next, $c);
|
|
|
|
|
+ }
|
|
|
|
|
+ return $ret;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ return $this->_getVariable($tag_name, $context);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Get a variable from the context array. Internal helper used by getVariable() to abstract
|
|
|
|
|
+ * variable traversal for dot notation.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @access protected
|
|
|
|
|
+ * @param string $tag_name
|
|
|
|
|
+ * @param array &$context
|
|
|
|
|
+ * @throws MustacheException Unknown variable name.
|
|
|
|
|
+ * @return string
|
|
|
|
|
+ */
|
|
|
|
|
+ protected function _getVariable($tag_name, &$context) {
|
|
|
foreach ($context as $view) {
|
|
foreach ($context as $view) {
|
|
|
if (is_object($view)) {
|
|
if (is_object($view)) {
|
|
|
if (isset($view->$tag_name)) {
|
|
if (isset($view->$tag_name)) {
|
|
@@ -439,4 +544,8 @@ class MustacheException extends Exception {
|
|
|
// with no associated partial.
|
|
// with no associated partial.
|
|
|
const UNKNOWN_PARTIAL = 3;
|
|
const UNKNOWN_PARTIAL = 3;
|
|
|
|
|
|
|
|
|
|
+ // An UNKNOWN_PRAGMA exception is thrown whenever a {{%PRAGMA}} tag appears
|
|
|
|
|
+ // which can't be handled by this Mustache instance.
|
|
|
|
|
+ const UNKNOWN_PRAGMA = 4;
|
|
|
|
|
+
|
|
|
}
|
|
}
|