From d30febdf571784a4a93f08d5167dd4bbbb7a11ef Mon Sep 17 00:00:00 2001 From: Justin Hileman Date: Mon, 22 Mar 2010 19:01:45 -0400 Subject: [PATCH] Added MustacheException class, added exceptions for missing variables and partials and unclosed or unopened section tags. Added throwExceptions member variable to enable/disable throwing exceptions on unexpected tags. Defaults to false. --- Mustache.php | 59 +++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 56 insertions(+), 3 deletions(-) diff --git a/Mustache.php b/Mustache.php index 89b304d..36b341e 100644 --- a/Mustache.php +++ b/Mustache.php @@ -16,6 +16,10 @@ class Mustache { public $otag = '{{'; public $ctag = '}}'; + + // Should this Mustache throw exceptions when it finds unexpected tags? + protected $throwExceptions = false; + protected $tagRegEx; protected $template = ''; @@ -134,7 +138,7 @@ class Mustache { $otag = $this->prepareRegEx($this->otag); $ctag = $this->prepareRegEx($this->ctag); - $this->tagRegEx = '/' . $otag . "(=|!|>|\\{|&)?([^\/#]+?)\\1?" . $ctag . "+/"; + $this->tagRegEx = '/' . $otag . "(#|\/|=|!|>|\\{|&)?([^\/#]+?)\\1?" . $ctag . "+/"; $html = ''; $matches = array(); while (preg_match($this->tagRegEx, $template, $matches, PREG_OFFSET_CAPTURE)) { @@ -165,6 +169,20 @@ class Mustache { */ protected function renderTag($modifier, $tag_name, &$context) { switch ($modifier) { + case '#': + if ($this->throwExceptions) { + throw new MustacheException('Unclosed section: ' . $tag_name, MustacheException::UNCLOSED_SECTION); + } else { + return ''; + } + break; + case '/': + if ($this->throwExceptions) { + throw new MustacheException('Unexpected close section: ' . $tag_name, MustacheException::UNEXPECTED_CLOSE_SECTION); + } else { + return ''; + } + break; case '=': return $this->changeDelimiter($tag_name, $context); break; @@ -302,7 +320,12 @@ class Mustache { return $view[$tag_name]; } } - return ''; + + if ($this->throwExceptions) { + throw new MustacheException("Unknown variable: " . $tag_name, MustacheException::UNKNOWN_VARIABLE); + } else { + return ''; + } } /** @@ -318,7 +341,12 @@ class Mustache { if (is_array($this->partials) && isset($this->partials[$tag_name])) { return $this->partials[$tag_name]; } - return ''; + + if ($this->throwExceptions) { + throw new MustacheException('Unknown partial: ' . $tag_name, MustacheException::UNKNOWN_PARTIAL); + } else { + return ''; + } } /** @@ -336,4 +364,29 @@ class Mustache { ); return strtr($str, $replace); } +} + + +/** + * MustacheException class. + * + * @extends Exception + */ +class MustacheException extends Exception { + + // An UNKNOWN_VARIABLE exception is thrown when a {{variable}} is not found + // in the current context. + const UNKNOWN_VARIABLE = 0; + + // An UNCLOSED_SECTION exception is thrown when a {{#section}} is not closed. + const UNCLOSED_SECTION = 1; + + // An UNEXPECTED_CLOSE_SECTION exception is thrown when {{/section}} appears + // without a corresponding {{#section}}. + const UNEXPECTED_CLOSE_SECTION = 2; + + // An UNKNOWN_PARTIAL exception is thrown whenever a {{>partial}} tag appears + // with no associated partial. + const UNKNOWN_PARTIAL = 3; + } \ No newline at end of file