From ff666397196bf7e66495dc33dedf50081e0b6632 Mon Sep 17 00:00:00 2001 From: Justin Hileman Date: Tue, 1 May 2012 22:28:35 -0700 Subject: [PATCH 01/29] Add Symfony ClassLoader (needed for bootstrap) --- .gitmodules | 3 +++ vendor/symfony/Symfony/Component/ClassLoader | 1 + 2 files changed, 4 insertions(+) create mode 160000 vendor/symfony/Symfony/Component/ClassLoader diff --git a/.gitmodules b/.gitmodules index 042ea4d..ee478af 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,6 @@ [submodule "vendor/yaml"] path = vendor/yaml url = https://github.com/fabpot/yaml.git +[submodule "vendor/symfony/Symfony/Component/ClassLoader"] + path = vendor/symfony/Symfony/Component/ClassLoader + url = https://github.com/symfony/ClassLoader.git diff --git a/vendor/symfony/Symfony/Component/ClassLoader b/vendor/symfony/Symfony/Component/ClassLoader new file mode 160000 index 0000000..0e6ee8d --- /dev/null +++ b/vendor/symfony/Symfony/Component/ClassLoader @@ -0,0 +1 @@ +Subproject commit 0e6ee8d07dda6920106048247d41249201604e76 From 01bcf6a51a76173dc8a70d3227033997740ec698 Mon Sep 17 00:00:00 2001 From: Justin Hileman Date: Tue, 1 May 2012 23:14:03 -0700 Subject: [PATCH 02/29] Add a `build_bootstrap` script. Generates `mustache.php`, a single-file bootstrap library which is a lot easier to include in your project. --- .gitignore | 1 + bin/build_bootstrap.php | 147 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 148 insertions(+) create mode 100755 bin/build_bootstrap.php diff --git a/.gitignore b/.gitignore index 987e2a2..15977fb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ composer.lock vendor +mustache.php diff --git a/bin/build_bootstrap.php b/bin/build_bootstrap.php new file mode 100755 index 0000000..887eb29 --- /dev/null +++ b/bin/build_bootstrap.php @@ -0,0 +1,147 @@ +#!/usr/bin/env php + + */ +class SymfonyClassCollectionLoader +{ + static private $loaded; + + /** + * 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 + * + * @throws InvalidArgumentException When class can't be loaded + */ + static public function load(array $classes, $cacheDir, $name, $extension = '.php') + { + // each $name can only be loaded once per PHP process + if (isset(self::$loaded[$name])) { + return; + } + + self::$loaded[$name] = true; + + $content = ''; + foreach ($classes as $class) { + if (!class_exists($class) && !interface_exists($class) && (!function_exists('trait_exists') || !trait_exists($class))) { + throw new InvalidArgumentException(sprintf('Unable to load class "%s"', $class)); + } + + $r = new ReflectionClass($class); + $content .= preg_replace(array('/^\s*<\?php/', '/\?>\s*$/'), '', file_get_contents($r->getFileName())); + } + + $cache = $cacheDir.'/'.$name.$extension; + self::writeCacheFile($cache, self::stripComments(' Date: Sat, 12 Jan 2013 09:17:33 -0800 Subject: [PATCH 03/29] Add LambdaHelper and Logger to build_bootstrap. --- bin/build_bootstrap.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/bin/build_bootstrap.php b/bin/build_bootstrap.php index 887eb29..fe7b632 100755 --- a/bin/build_bootstrap.php +++ b/bin/build_bootstrap.php @@ -37,11 +37,15 @@ SymfonyClassCollectionLoader::load(array( '\Mustache_Compiler', '\Mustache_Context', '\Mustache_HelperCollection', + '\Mustache_LambdaHelper', + '\Mustache_Loader', '\Mustache_Loader_ArrayLoader', '\Mustache_Loader_FilesystemLoader', '\Mustache_Loader_MutableLoader', '\Mustache_Loader_StringLoader', - '\Mustache_Loader', + '\Mustache_Logger', + '\Mustache_Logger_AbstractLogger', + '\Mustache_Logger_StreamLogger', '\Mustache_Parser', '\Mustache_Template', '\Mustache_Tokenizer', From 0436c59477eb2dd5195162fb2af338324c099a6a Mon Sep 17 00:00:00 2001 From: Justin Hileman Date: Sun, 20 Jan 2013 10:35:55 -0800 Subject: [PATCH 04/29] Improve Mustache exception types, catchability. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Subclass common exception types (runtime, logic, invalid argument). * Add new "unknown x" exceptions for filters, helpers and templates. * Make all Mustache exceptions implement Mustache_Exception interface… Gotta catch 'em all! --- src/Mustache/Compiler.php | 8 ++--- src/Mustache/Engine.php | 22 ++++++++------ src/Mustache/Exception.php | 18 ++++++++++++ .../Exception/InvalidArgumentException.php | 18 ++++++++++++ src/Mustache/Exception/LogicException.php | 18 ++++++++++++ src/Mustache/Exception/RuntimeException.php | 18 ++++++++++++ src/Mustache/Exception/SyntaxException.php | 29 +++++++++++++++++++ .../Exception/UnknownFilterException.php | 29 +++++++++++++++++++ .../Exception/UnknownHelperException.php | 29 +++++++++++++++++++ .../Exception/UnknownTemplateException.php | 29 +++++++++++++++++++ src/Mustache/HelperCollection.php | 12 ++++---- src/Mustache/Loader/ArrayLoader.php | 4 ++- src/Mustache/Loader/FilesystemLoader.php | 8 ++--- src/Mustache/Logger/StreamLogger.php | 15 ++++++---- src/Mustache/Parser.php | 13 +++++---- test/Mustache/Test/CompilerTest.php | 4 +-- test/Mustache/Test/EngineTest.php | 8 ++--- .../Test/FiveThree/Functional/FiltersTest.php | 2 +- test/Mustache/Test/Loader/ArrayLoaderTest.php | 2 +- .../Test/Loader/FilesystemLoaderTest.php | 4 +-- .../Mustache/Test/Logger/StreamLoggerTest.php | 6 ++-- test/Mustache/Test/ParserTest.php | 2 +- 22 files changed, 250 insertions(+), 48 deletions(-) create mode 100644 src/Mustache/Exception.php create mode 100644 src/Mustache/Exception/InvalidArgumentException.php create mode 100644 src/Mustache/Exception/LogicException.php create mode 100644 src/Mustache/Exception/RuntimeException.php create mode 100644 src/Mustache/Exception/SyntaxException.php create mode 100644 src/Mustache/Exception/UnknownFilterException.php create mode 100644 src/Mustache/Exception/UnknownHelperException.php create mode 100644 src/Mustache/Exception/UnknownTemplateException.php diff --git a/src/Mustache/Compiler.php b/src/Mustache/Compiler.php index fe02419..e22d02a 100644 --- a/src/Mustache/Compiler.php +++ b/src/Mustache/Compiler.php @@ -50,7 +50,7 @@ class Mustache_Compiler /** * Helper function for walking the Mustache token parse tree. * - * @throws InvalidArgumentException upon encountering unknown token types. + * @throws Mustache_Exception_SyntaxException upon encountering unknown token types. * * @param array $tree Parse tree of Mustache tokens * @param int $level (default: 0) @@ -113,7 +113,7 @@ class Mustache_Compiler break; default: - throw new InvalidArgumentException('Unknown node type: '.json_encode($node)); + throw new Mustache_Exception_SyntaxException(sprintf('Unknown token type: %s', $node[Mustache_Tokenizer::TYPE]), $node); } } @@ -316,7 +316,7 @@ class Mustache_Compiler const FILTER = ' $filter = $context->%s(%s); if (is_string($filter) || !is_callable($filter)) { - throw new UnexpectedValueException(%s); + throw new Mustache_Exception_UnknownFilterException(%s); } $value = call_user_func($filter, $value);%s '; @@ -338,7 +338,7 @@ class Mustache_Compiler $name = array_shift($filters); $method = $this->getFindMethod($name); $filter = ($method !== 'last') ? var_export($name, true) : ''; - $msg = var_export(sprintf('Filter not found: %s', $name), true); + $msg = var_export($name, true); return sprintf($this->prepare(self::FILTER, $level), $method, $filter, $msg, $this->getFilter($filters, $level)); } diff --git a/src/Mustache/Engine.php b/src/Mustache/Engine.php index ddfffca..7f4b371 100644 --- a/src/Mustache/Engine.php +++ b/src/Mustache/Engine.php @@ -89,6 +89,8 @@ class Mustache_Engine * 'logger' => new Mustache_StreamLogger('php://stderr'), * ); * + * @throws Mustache_Exception_InvalidArgumentException If `escape` option is not callable. + * * @param array $options (default: array()) */ public function __construct(array $options = array()) @@ -123,7 +125,7 @@ class Mustache_Engine if (isset($options['escape'])) { if (!is_callable($options['escape'])) { - throw new InvalidArgumentException('Mustache Constructor "escape" option must be callable'); + throw new Mustache_Exception_InvalidArgumentException('Mustache Constructor "escape" option must be callable'); } $this->escape = $options['escape']; @@ -233,7 +235,7 @@ class Mustache_Engine /** * Set partials for the current partials Loader instance. * - * @throws RuntimeException If the current Loader instance is immutable + * @throws Mustache_Exception_RuntimeException If the current Loader instance is immutable * * @param array $partials (default: array()) */ @@ -241,7 +243,7 @@ class Mustache_Engine { $loader = $this->getPartialsLoader(); if (!$loader instanceof Mustache_Loader_MutableLoader) { - throw new RuntimeException('Unable to set partials on an immutable Mustache Loader instance'); + throw new Mustache_Exception_RuntimeException('Unable to set partials on an immutable Mustache Loader instance'); } $loader->setTemplates($partials); @@ -254,14 +256,14 @@ class Mustache_Engine * any other valid Mustache context value. They will be prepended to the context stack, so they will be available in * any template loaded by this Mustache instance. * - * @throws InvalidArgumentException if $helpers is not an array or Traversable + * @throws Mustache_Exception_InvalidArgumentException if $helpers is not an array or Traversable * * @param array|Traversable $helpers */ public function setHelpers($helpers) { if (!is_array($helpers) && !$helpers instanceof Traversable) { - throw new InvalidArgumentException('setHelpers expects an array of helpers'); + throw new Mustache_Exception_InvalidArgumentException('setHelpers expects an array of helpers'); } $this->getHelpers()->clear(); @@ -343,12 +345,14 @@ class Mustache_Engine /** * Set the Mustache Logger instance. * + * @throws Mustache_Exception_InvalidArgumentException If logger is not an instance of Mustache_Logger or Psr\Log\LoggerInterface. + * * @param Mustache_Logger|Psr\Log\LoggerInterface $logger */ public function setLogger($logger = null) { if ($logger !== null && !($logger instanceof Mustache_Logger || is_a($logger, 'Psr\\Log\\LoggerInterface'))) { - throw new InvalidArgumentException('Expected an instance of Mustache_Logger or Psr\\Log\\LoggerInterface.'); + throw new Mustache_Exception_InvalidArgumentException('Expected an instance of Mustache_Logger or Psr\\Log\\LoggerInterface.'); } $this->logger = $logger; @@ -636,7 +640,7 @@ class Mustache_Engine /** * Helper method to dump a generated Mustache Template subclass to the file cache. * - * @throws RuntimeException if unable to create the cache directory or write to $fileName. + * @throws Mustache_Exception_RuntimeException if unable to create the cache directory or write to $fileName. * * @param string $fileName * @param string $source @@ -655,7 +659,7 @@ class Mustache_Engine @mkdir($dirName, 0777, true); if (!is_dir($dirName)) { - throw new RuntimeException(sprintf('Failed to create cache directory "%s".', $dirName)); + throw new Mustache_Exception_RuntimeException(sprintf('Failed to create cache directory "%s".', $dirName)); } } @@ -682,7 +686,7 @@ class Mustache_Engine ); } - throw new RuntimeException(sprintf('Failed to write cache file "%s".', $fileName)); + throw new Mustache_Exception_RuntimeException(sprintf('Failed to write cache file "%s".', $fileName)); } /** diff --git a/src/Mustache/Exception.php b/src/Mustache/Exception.php new file mode 100644 index 0000000..b4f8300 --- /dev/null +++ b/src/Mustache/Exception.php @@ -0,0 +1,18 @@ +token = $token; + parent::__construct($msg); + } + + public function getToken() + { + return $this->token; + } +} diff --git a/src/Mustache/Exception/UnknownFilterException.php b/src/Mustache/Exception/UnknownFilterException.php new file mode 100644 index 0000000..f5c0884 --- /dev/null +++ b/src/Mustache/Exception/UnknownFilterException.php @@ -0,0 +1,29 @@ +filterName = $filterName; + parent::__construct(sprintf('Unknown filter: %s', $filterName)); + } + + public function getFilterName() + { + return $this->filterName; + } +} diff --git a/src/Mustache/Exception/UnknownHelperException.php b/src/Mustache/Exception/UnknownHelperException.php new file mode 100644 index 0000000..98af13e --- /dev/null +++ b/src/Mustache/Exception/UnknownHelperException.php @@ -0,0 +1,29 @@ +helperName = $helperName; + parent::__construct(sprintf('Unknown helper: %s', $helperName)); + } + + public function getHelperName() + { + return $this->helperName; + } +} diff --git a/src/Mustache/Exception/UnknownTemplateException.php b/src/Mustache/Exception/UnknownTemplateException.php new file mode 100644 index 0000000..141d372 --- /dev/null +++ b/src/Mustache/Exception/UnknownTemplateException.php @@ -0,0 +1,29 @@ +templateName = $templateName; + parent::__construct(sprintf('Unknown template: %s', $templateName)); + } + + public function getTemplateName() + { + return $this->templateName; + } +} diff --git a/src/Mustache/HelperCollection.php b/src/Mustache/HelperCollection.php index f6354e6..e991137 100644 --- a/src/Mustache/HelperCollection.php +++ b/src/Mustache/HelperCollection.php @@ -21,7 +21,7 @@ class Mustache_HelperCollection * * Optionally accepts an array (or Traversable) of `$name => $helper` pairs. * - * @throws InvalidArgumentException if the $helpers argument isn't an array or Traversable + * @throws Mustache_Exception_InvalidArgumentException if the $helpers argument isn't an array or Traversable * * @param array|Traversable $helpers (default: null) */ @@ -29,7 +29,7 @@ class Mustache_HelperCollection { if ($helpers !== null) { if (!is_array($helpers) && !$helpers instanceof Traversable) { - throw new InvalidArgumentException('HelperCollection constructor expects an array of helpers'); + throw new Mustache_Exception_InvalidArgumentException('HelperCollection constructor expects an array of helpers'); } foreach ($helpers as $name => $helper) { @@ -79,6 +79,8 @@ class Mustache_HelperCollection /** * Get a helper by name. * + * @throws Mustache_Exception_UnknownHelperException If helper does not exist. + * * @param string $name * * @return mixed Helper @@ -86,7 +88,7 @@ class Mustache_HelperCollection public function get($name) { if (!$this->has($name)) { - throw new InvalidArgumentException('Unknown helper: '.$name); + throw new Mustache_Exception_UnknownHelperException($name); } return $this->helpers[$name]; @@ -133,14 +135,14 @@ class Mustache_HelperCollection /** * Check whether a given helper is present in the collection. * - * @throws InvalidArgumentException if the requested helper is not present. + * @throws Mustache_Exception_UnknownHelperException if the requested helper is not present. * * @param string $name */ public function remove($name) { if (!$this->has($name)) { - throw new InvalidArgumentException('Unknown helper: '.$name); + throw new Mustache_Exception_UnknownHelperException($name); } unset($this->helpers[$name]); diff --git a/src/Mustache/Loader/ArrayLoader.php b/src/Mustache/Loader/ArrayLoader.php index 1ce6e20..c6fa894 100644 --- a/src/Mustache/Loader/ArrayLoader.php +++ b/src/Mustache/Loader/ArrayLoader.php @@ -43,6 +43,8 @@ class Mustache_Loader_ArrayLoader implements Mustache_Loader, Mustache_Loader_Mu /** * Load a Template. * + * @throws Mustache_Exception_UnknownTemplateException If a template file is not found. + * * @param string $name * * @return string Mustache Template source @@ -50,7 +52,7 @@ class Mustache_Loader_ArrayLoader implements Mustache_Loader, Mustache_Loader_Mu public function load($name) { if (!isset($this->templates[$name])) { - throw new InvalidArgumentException('Template '.$name.' not found.'); + throw new Mustache_Exception_UnknownTemplateException($name); } return $this->templates[$name]; diff --git a/src/Mustache/Loader/FilesystemLoader.php b/src/Mustache/Loader/FilesystemLoader.php index bbd2a43..e6d0578 100644 --- a/src/Mustache/Loader/FilesystemLoader.php +++ b/src/Mustache/Loader/FilesystemLoader.php @@ -42,7 +42,7 @@ class Mustache_Loader_FilesystemLoader implements Mustache_Loader * 'extension' => '.ms', * ); * - * @throws RuntimeException if $baseDir does not exist. + * @throws Mustache_Exception_RuntimeException if $baseDir does not exist. * * @param string $baseDir Base directory containing Mustache template files. * @param array $options Array of Loader options (default: array()) @@ -52,7 +52,7 @@ class Mustache_Loader_FilesystemLoader implements Mustache_Loader $this->baseDir = rtrim(realpath($baseDir), '/'); if (!is_dir($this->baseDir)) { - throw new RuntimeException('FilesystemLoader baseDir must be a directory: '.$baseDir); + throw new Mustache_Exception_RuntimeException(sprintf('FilesystemLoader baseDir must be a directory: %s', $baseDir)); } if (array_key_exists('extension', $options)) { @@ -86,7 +86,7 @@ class Mustache_Loader_FilesystemLoader implements Mustache_Loader /** * Helper function for loading a Mustache file by name. * - * @throws InvalidArgumentException if a template file is not found. + * @throws Mustache_Exception_UnknownTemplateException If a template file is not found. * * @param string $name * @@ -97,7 +97,7 @@ class Mustache_Loader_FilesystemLoader implements Mustache_Loader $fileName = $this->getFileName($name); if (!file_exists($fileName)) { - throw new InvalidArgumentException('Template '.$name.' not found.'); + throw new Mustache_Exception_UnknownTemplateException($name); } return file_get_contents($fileName); diff --git a/src/Mustache/Logger/StreamLogger.php b/src/Mustache/Logger/StreamLogger.php index 7f3fd50..c61a25e 100644 --- a/src/Mustache/Logger/StreamLogger.php +++ b/src/Mustache/Logger/StreamLogger.php @@ -64,14 +64,14 @@ class Mustache_Logger_StreamLogger extends Mustache_Logger_AbstractLogger /** * Set the minimum logging level. * - * @throws InvalidArgumentException if the logging level is unknown. + * @throws Mustache_Exception_InvalidArgumentException if the logging level is unknown. * * @param integer $level The minimum logging level which will be written */ public function setLevel($level) { if (!array_key_exists($level, self::$levels)) { - throw new InvalidArgumentException('Unexpected logging level: ' . $level); + throw new Mustache_Exception_InvalidArgumentException(sprintf('Unexpected logging level: %s', $level)); } $this->level = $level; @@ -90,7 +90,7 @@ class Mustache_Logger_StreamLogger extends Mustache_Logger_AbstractLogger /** * Logs with an arbitrary level. * - * @throws InvalidArgumentException if the logging level is unknown. + * @throws Mustache_Exception_InvalidArgumentException if the logging level is unknown. * * @param mixed $level * @param string $message @@ -99,7 +99,7 @@ class Mustache_Logger_StreamLogger extends Mustache_Logger_AbstractLogger public function log($level, $message, array $context = array()) { if (!array_key_exists($level, self::$levels)) { - throw new InvalidArgumentException('Unexpected logging level: ' . $level); + throw new Mustache_Exception_InvalidArgumentException(sprintf('Unexpected logging level: %s', $level)); } if (self::$levels[$level] >= self::$levels[$this->level]) { @@ -110,6 +110,9 @@ class Mustache_Logger_StreamLogger extends Mustache_Logger_AbstractLogger /** * Write a record to the log. * + * @throws Mustache_Exception_LogicException If neither a stream resource nor url is present. + * @throws Mustache_Exception_RuntimeException If the stream url cannot be opened. + * * @param integer $level The logging level * @param string $message The log message * @param array $context The log context @@ -118,13 +121,13 @@ class Mustache_Logger_StreamLogger extends Mustache_Logger_AbstractLogger { if (!is_resource($this->stream)) { if (!isset($this->url)) { - throw new LogicException('Missing stream url, the stream can not be opened. This may be caused by a premature call to close().'); + throw new Mustache_Exception_LogicException('Missing stream url, the stream can not be opened. This may be caused by a premature call to close().'); } $this->stream = fopen($this->url, 'a'); if (!is_resource($this->stream)) { // @codeCoverageIgnoreStart - throw new UnexpectedValueException(sprintf('The stream or file "%s" could not be opened.', $this->url)); + throw new Mustache_Exception_RuntimeException(sprintf('The stream or file "%s" could not be opened.', $this->url)); // @codeCoverageIgnoreEnd } } diff --git a/src/Mustache/Parser.php b/src/Mustache/Parser.php index 5766dde..ab7db84 100644 --- a/src/Mustache/Parser.php +++ b/src/Mustache/Parser.php @@ -32,12 +32,12 @@ class Mustache_Parser /** * Helper method for recursively building a parse tree. * + * @throws Mustache_Exception_SyntaxException when nesting errors or mismatched section tags are encountered. + * * @param ArrayIterator $tokens Stream of Mustache tokens * @param array $parent Parent token (default: null) * * @return array Mustache Token parse tree - * - * @throws LogicException when nesting errors or mismatched section tags are encountered. */ private function buildTree(ArrayIterator $tokens, array $parent = null) { @@ -58,11 +58,13 @@ class Mustache_Parser case Mustache_Tokenizer::T_END_SECTION: if (!isset($parent)) { - throw new LogicException('Unexpected closing tag: /'. $token[Mustache_Tokenizer::NAME]); + $msg = sprintf('Unexpected closing tag: /%s', $token[Mustache_Tokenizer::NAME]); + throw new Mustache_Exception_SyntaxException($msg, $token); } if ($token[Mustache_Tokenizer::NAME] !== $parent[Mustache_Tokenizer::NAME]) { - throw new LogicException('Nesting error: ' . $parent[Mustache_Tokenizer::NAME] . ' vs. ' . $token[Mustache_Tokenizer::NAME]); + $msg = sprintf('Nesting error: %s vs. %s', $parent[Mustache_Tokenizer::NAME], $token[Mustache_Tokenizer::NAME]); + throw new Mustache_Exception_SyntaxException($msg, $token); } $parent[Mustache_Tokenizer::END] = $token[Mustache_Tokenizer::INDEX]; @@ -80,7 +82,8 @@ class Mustache_Parser } while ($tokens->valid()); if (isset($parent)) { - throw new LogicException('Missing closing tag: ' . $parent[Mustache_Tokenizer::NAME]); + $msg = sprintf('Missing closing tag: %s', $parent[Mustache_Tokenizer::NAME]); + throw new Mustache_Exception_SyntaxException($msg, $parent); } return $nodes; diff --git a/test/Mustache/Test/CompilerTest.php b/test/Mustache/Test/CompilerTest.php index 8b6f5be..c952e0c 100644 --- a/test/Mustache/Test/CompilerTest.php +++ b/test/Mustache/Test/CompilerTest.php @@ -85,9 +85,9 @@ class Mustache_Test_CompilerTest extends PHPUnit_Framework_TestCase } /** - * @expectedException InvalidArgumentException + * @expectedException Mustache_Exception_SyntaxException */ - public function testCompilerThrowsUnknownNodeTypeException() + public function testCompilerThrowsSyntaxException() { $compiler = new Mustache_Compiler; $compiler->compile('', array(array(Mustache_Tokenizer::TYPE => 'invalid')), 'SomeClass'); diff --git a/test/Mustache/Test/EngineTest.php b/test/Mustache/Test/EngineTest.php index bf59d18..5625637 100644 --- a/test/Mustache/Test/EngineTest.php +++ b/test/Mustache/Test/EngineTest.php @@ -141,7 +141,7 @@ class Mustache_Test_EngineTest extends PHPUnit_Framework_TestCase } /** - * @expectedException InvalidArgumentException + * @expectedException Mustache_Exception_InvalidArgumentException * @dataProvider getBadEscapers */ public function testNonCallableEscapeThrowsException($escape) @@ -158,7 +158,7 @@ class Mustache_Test_EngineTest extends PHPUnit_Framework_TestCase } /** - * @expectedException RuntimeException + * @expectedException Mustache_Exception_RuntimeException */ public function testImmutablePartialsLoadersThrowException() { @@ -223,7 +223,7 @@ class Mustache_Test_EngineTest extends PHPUnit_Framework_TestCase } /** - * @expectedException InvalidArgumentException + * @expectedException Mustache_Exception_InvalidArgumentException */ public function testSetHelpersThrowsExceptions() { @@ -232,7 +232,7 @@ class Mustache_Test_EngineTest extends PHPUnit_Framework_TestCase } /** - * @expectedException InvalidArgumentException + * @expectedException Mustache_Exception_InvalidArgumentException */ public function testSetLoggerThrowsExceptions() { diff --git a/test/Mustache/Test/FiveThree/Functional/FiltersTest.php b/test/Mustache/Test/FiveThree/Functional/FiltersTest.php index 8c51e37..bbd037e 100644 --- a/test/Mustache/Test/FiveThree/Functional/FiltersTest.php +++ b/test/Mustache/Test/FiveThree/Functional/FiltersTest.php @@ -67,7 +67,7 @@ class Mustache_Test_FiveThree_Functional_FiltersTest extends PHPUnit_Framework_T } /** - * @expectedException UnexpectedValueException + * @expectedException Mustache_Exception_UnknownFilterException * @dataProvider getBrokenPipes */ public function testThrowsExceptionForBrokenPipes($tpl, $data) diff --git a/test/Mustache/Test/Loader/ArrayLoaderTest.php b/test/Mustache/Test/Loader/ArrayLoaderTest.php index 63d1a96..b1da190 100644 --- a/test/Mustache/Test/Loader/ArrayLoaderTest.php +++ b/test/Mustache/Test/Loader/ArrayLoaderTest.php @@ -42,7 +42,7 @@ class Mustache_Test_Loader_ArrayLoaderTest extends PHPUnit_Framework_TestCase } /** - * @expectedException InvalidArgumentException + * @expectedException Mustache_Exception_UnknownTemplateException */ public function testMissingTemplatesThrowExceptions() { diff --git a/test/Mustache/Test/Loader/FilesystemLoaderTest.php b/test/Mustache/Test/Loader/FilesystemLoaderTest.php index d12a6ff..92b12f9 100644 --- a/test/Mustache/Test/Loader/FilesystemLoaderTest.php +++ b/test/Mustache/Test/Loader/FilesystemLoaderTest.php @@ -44,7 +44,7 @@ class Mustache_Test_Loader_FilesystemLoaderTest extends PHPUnit_Framework_TestCa } /** - * @expectedException RuntimeException + * @expectedException Mustache_Exception_RuntimeException */ public function testMissingBaseDirThrowsException() { @@ -52,7 +52,7 @@ class Mustache_Test_Loader_FilesystemLoaderTest extends PHPUnit_Framework_TestCa } /** - * @expectedException InvalidArgumentException + * @expectedException Mustache_Exception_UnknownTemplateException */ public function testMissingTemplateThrowsException() { diff --git a/test/Mustache/Test/Logger/StreamLoggerTest.php b/test/Mustache/Test/Logger/StreamLoggerTest.php index 9dfd4c2..4ddbcec 100644 --- a/test/Mustache/Test/Logger/StreamLoggerTest.php +++ b/test/Mustache/Test/Logger/StreamLoggerTest.php @@ -34,7 +34,7 @@ class Mustache_Test_Logger_StreamLoggerTest extends PHPUnit_Framework_TestCase } /** - * @expectedException LogicException + * @expectedException Mustache_Exception_LogicException */ public function testPrematurelyClosedStreamThrowsException() { @@ -187,7 +187,7 @@ class Mustache_Test_Logger_StreamLoggerTest extends PHPUnit_Framework_TestCase } /** - * @expectedException InvalidArgumentException + * @expectedException Mustache_Exception_InvalidArgumentException */ public function testThrowsInvalidArgumentExceptionWhenSettingUnknownLevels() { @@ -196,7 +196,7 @@ class Mustache_Test_Logger_StreamLoggerTest extends PHPUnit_Framework_TestCase } /** - * @expectedException InvalidArgumentException + * @expectedException Mustache_Exception_InvalidArgumentException */ public function testThrowsInvalidArgumentExceptionWhenLoggingUnknownLevels() { diff --git a/test/Mustache/Test/ParserTest.php b/test/Mustache/Test/ParserTest.php index 5f898d8..a99b848 100644 --- a/test/Mustache/Test/ParserTest.php +++ b/test/Mustache/Test/ParserTest.php @@ -108,7 +108,7 @@ class Mustache_Test_ParserTest extends PHPUnit_Framework_TestCase /** * @dataProvider getBadParseTrees - * @expectedException LogicException + * @expectedException Mustache_Exception_SyntaxException */ public function testParserThrowsExceptions($tokens) { From 8b02366a3fdc91bc7180ca0e5b6da3b0f82cbd5e Mon Sep 17 00:00:00 2001 From: Justin Hileman Date: Sun, 20 Jan 2013 10:50:00 -0800 Subject: [PATCH 05/29] Add test coverage for new exception types. --- .../Test/Exception/SyntaxExceptionTest.php | 27 ++++++++++++++++ .../Exception/UnknownFilterExceptionTest.php | 32 +++++++++++++++++++ .../Exception/UnknownHelperExceptionTest.php | 32 +++++++++++++++++++ .../UnknownTemplateExceptionTest.php | 32 +++++++++++++++++++ 4 files changed, 123 insertions(+) create mode 100644 test/Mustache/Test/Exception/SyntaxExceptionTest.php create mode 100644 test/Mustache/Test/Exception/UnknownFilterExceptionTest.php create mode 100644 test/Mustache/Test/Exception/UnknownHelperExceptionTest.php create mode 100644 test/Mustache/Test/Exception/UnknownTemplateExceptionTest.php diff --git a/test/Mustache/Test/Exception/SyntaxExceptionTest.php b/test/Mustache/Test/Exception/SyntaxExceptionTest.php new file mode 100644 index 0000000..8914fbd --- /dev/null +++ b/test/Mustache/Test/Exception/SyntaxExceptionTest.php @@ -0,0 +1,27 @@ + 'this')); + $this->assertTrue($e instanceof LogicException); + $this->assertTrue($e instanceof Mustache_Exception); + } + + public function testGetToken() + { + $token = array(Mustache_Tokenizer::TYPE => 'whatever'); + $e = new Mustache_Exception_SyntaxException('ignore this', $token); + $this->assertEquals($token, $e->getToken()); + } +} diff --git a/test/Mustache/Test/Exception/UnknownFilterExceptionTest.php b/test/Mustache/Test/Exception/UnknownFilterExceptionTest.php new file mode 100644 index 0000000..8ba2e4d --- /dev/null +++ b/test/Mustache/Test/Exception/UnknownFilterExceptionTest.php @@ -0,0 +1,32 @@ +assertTrue($e instanceof UnexpectedValueException); + $this->assertTrue($e instanceof Mustache_Exception); + } + + public function testMessage() + { + $e = new Mustache_Exception_UnknownFilterException('sausage'); + $this->assertEquals('Unknown filter: sausage', $e->getMessage()); + } + + public function testGetFilterName() + { + $e = new Mustache_Exception_UnknownFilterException('eggs'); + $this->assertEquals('eggs', $e->getFilterName()); + } +} diff --git a/test/Mustache/Test/Exception/UnknownHelperExceptionTest.php b/test/Mustache/Test/Exception/UnknownHelperExceptionTest.php new file mode 100644 index 0000000..60567f9 --- /dev/null +++ b/test/Mustache/Test/Exception/UnknownHelperExceptionTest.php @@ -0,0 +1,32 @@ +assertTrue($e instanceof InvalidArgumentException); + $this->assertTrue($e instanceof Mustache_Exception); + } + + public function testMessage() + { + $e = new Mustache_Exception_UnknownHelperException('beta'); + $this->assertEquals('Unknown helper: beta', $e->getMessage()); + } + + public function testGetHelperName() + { + $e = new Mustache_Exception_UnknownHelperException('gamma'); + $this->assertEquals('gamma', $e->getHelperName()); + } +} diff --git a/test/Mustache/Test/Exception/UnknownTemplateExceptionTest.php b/test/Mustache/Test/Exception/UnknownTemplateExceptionTest.php new file mode 100644 index 0000000..001bc63 --- /dev/null +++ b/test/Mustache/Test/Exception/UnknownTemplateExceptionTest.php @@ -0,0 +1,32 @@ +assertTrue($e instanceof InvalidArgumentException); + $this->assertTrue($e instanceof Mustache_Exception); + } + + public function testMessage() + { + $e = new Mustache_Exception_UnknownTemplateException('luigi'); + $this->assertEquals('Unknown template: luigi', $e->getMessage()); + } + + public function testGetTemplateName() + { + $e = new Mustache_Exception_UnknownTemplateException('yoshi'); + $this->assertEquals('yoshi', $e->getTemplateName()); + } +} From 1f07edd1adf4c3d92f212bf758ba63862586ec61 Mon Sep 17 00:00:00 2001 From: Justin Hileman Date: Sun, 20 Jan 2013 10:57:14 -0800 Subject: [PATCH 06/29] Bail early on log formatting if message has no placeholders. --- src/Mustache/Logger/StreamLogger.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Mustache/Logger/StreamLogger.php b/src/Mustache/Logger/StreamLogger.php index c61a25e..da771f9 100644 --- a/src/Mustache/Logger/StreamLogger.php +++ b/src/Mustache/Logger/StreamLogger.php @@ -177,7 +177,9 @@ class Mustache_Logger_StreamLogger extends Mustache_Logger_AbstractLogger */ protected static function interpolateMessage($message, array $context = array()) { - $message = (string) $message; + if (strpos($message, '{') === false) { + return $message; + } // build a replacement array with braces around the context keys $replace = array(); From a20068657e238faa1f28fc2d235edd6778f666f9 Mon Sep 17 00:00:00 2001 From: Justin Hileman Date: Sun, 20 Jan 2013 11:24:59 -0800 Subject: [PATCH 07/29] Link to main docs more prominently --- README.markdown | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/README.markdown b/README.markdown index d7ef259..1c49ae3 100644 --- a/README.markdown +++ b/README.markdown @@ -5,6 +5,7 @@ A [Mustache](http://mustache.github.com/) implementation in PHP. [![Build Status](https://secure.travis-ci.org/bobthecow/mustache.php.png?branch=dev)](http://travis-ci.org/bobthecow/mustache.php) + Usage ----- @@ -55,9 +56,14 @@ echo $m->render($template, $chris); ``` +And That's Not All! +------------------- + +Read [the Mustache.php documentation](https://github.com/bobthecow/mustache.php/wiki/Home) for more information. + + See Also -------- - * [Mustache.php wiki](https://github.com/bobthecow/mustache.php/wiki/Home). * [Readme for the Ruby Mustache implementation](http://github.com/defunkt/mustache/blob/master/README.md). * [mustache(5)](http://mustache.github.com/mustache.5.html) man page. From 5fcd9f6d256553d54a97b722228428ee164f935e Mon Sep 17 00:00:00 2001 From: Justin Hileman Date: Sun, 20 Jan 2013 15:52:21 -0800 Subject: [PATCH 08/29] mention UnknownTemplateException in loader interface --- src/Mustache/Loader.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Mustache/Loader.php b/src/Mustache/Loader.php index 21229d1..f659a1d 100644 --- a/src/Mustache/Loader.php +++ b/src/Mustache/Loader.php @@ -18,6 +18,8 @@ interface Mustache_Loader /** * Load a Template by name. * + * @throws Mustache_Exception_UnknownTemplateException If a template file is not found. + * * @param string $name * * @return string Mustache Template source From 59020c2e4f2da839e7156e20b86202920bb534db Mon Sep 17 00:00:00 2001 From: Justin Hileman Date: Mon, 21 Jan 2013 10:02:58 -0800 Subject: [PATCH 09/29] Remove unnecessary @implements annotations. --- src/Mustache/Loader/ArrayLoader.php | 3 --- src/Mustache/Loader/FilesystemLoader.php | 2 -- src/Mustache/Loader/StringLoader.php | 2 -- 3 files changed, 7 deletions(-) diff --git a/src/Mustache/Loader/ArrayLoader.php b/src/Mustache/Loader/ArrayLoader.php index c6fa894..ec35774 100644 --- a/src/Mustache/Loader/ArrayLoader.php +++ b/src/Mustache/Loader/ArrayLoader.php @@ -23,9 +23,6 @@ * * The ArrayLoader is used internally as a partials loader by Mustache_Engine instance when an array of partials * is set. It can also be used as a quick-and-dirty Template loader. - * - * @implements Loader - * @implements MutableLoader */ class Mustache_Loader_ArrayLoader implements Mustache_Loader, Mustache_Loader_MutableLoader { diff --git a/src/Mustache/Loader/FilesystemLoader.php b/src/Mustache/Loader/FilesystemLoader.php index e6d0578..71d7f1c 100644 --- a/src/Mustache/Loader/FilesystemLoader.php +++ b/src/Mustache/Loader/FilesystemLoader.php @@ -23,8 +23,6 @@ * 'loader' => new Mustache_Loader_FilesystemLoader(dirname(__FILE__).'/views'), * 'partials_loader' => new Mustache_Loader_FilesystemLoader(dirname(__FILE__).'/views/partials'), * )); - * - * @implements Mustache_Loader */ class Mustache_Loader_FilesystemLoader implements Mustache_Loader { diff --git a/src/Mustache/Loader/StringLoader.php b/src/Mustache/Loader/StringLoader.php index aa8fcf7..e73b3cd 100644 --- a/src/Mustache/Loader/StringLoader.php +++ b/src/Mustache/Loader/StringLoader.php @@ -22,8 +22,6 @@ * $m = new Mustache; * $tpl = $m->loadTemplate('{{ foo }}'); * echo $tpl->render(array('foo' => 'bar')); // "bar" - * - * @implements Loader */ class Mustache_Loader_StringLoader implements Mustache_Loader { From b22d15a759db41644d86006c526b0f016b19ae86 Mon Sep 17 00:00:00 2001 From: Justin Hileman Date: Mon, 21 Jan 2013 10:03:57 -0800 Subject: [PATCH 10/29] Add an inline template loader. This loader is awesome for micro-frameworks such as Silex :) --- src/Mustache/Loader/InlineLoader.php | 121 ++++++++++++++++++ .../Mustache/Test/Loader/InlineLoaderTest.php | 56 ++++++++ 2 files changed, 177 insertions(+) create mode 100644 src/Mustache/Loader/InlineLoader.php create mode 100644 test/Mustache/Test/Loader/InlineLoaderTest.php diff --git a/src/Mustache/Loader/InlineLoader.php b/src/Mustache/Loader/InlineLoader.php new file mode 100644 index 0000000..835fbf1 --- /dev/null +++ b/src/Mustache/Loader/InlineLoader.php @@ -0,0 +1,121 @@ +load('hello'); + * $goodbye = $loader->load('goodbye'); + * + * __halt_compiler(); + * + * @@ hello + * Hello, {{ planet }}! + * + * @@ goodbye + * Goodbye, cruel {{ planet }} + * + * Templates are deliniated by lines containing only `@@ name`. + * + * The InlineLoader is well-suited to micro-frameworks such as Silex: + * + * $app->register(new MustacheServiceProvider, array( + * 'mustache.loader' => new Mustache_Loader_InlineLoader(__FILE__, __COMPILER_HALT_OFFSET__) + * )); + * + * $app->get('/{name}', function() use ($app) { + * return $app['mustache']->render('hello', compact('name')); + * }) + * ->value('name', 'world'); + * + * __halt_compiler(); + * + * @@ hello + * Hello, {{ name }}! + * + */ +class Mustache_Loader_InlineLoader implements Mustache_Loader +{ + protected $fileName; + protected $offset; + protected $templates; + + /** + * The InlineLoader requires a filename and offset to process templates. + * The magic constants `__FILE__` and `__COMPILER_HALT_OFFSET__` are usually + * perfectly suited to the job: + * + * $loader = new Mustache_Loader_InlineLoader(__FILE__, __COMPILER_HALT_OFFSET__); + * + * Note that this only works if the loader is instantiated inside the same + * file as the inline templates. If the templates are located in another + * file, it would be necessary to manually specify the filename and offset. + * + * @param string $fileName The file to parse for inline templates + * @param int $offset A string offset for the start of the templates. + * This usually coincides with the `__halt_compiler` + * call, and the `__COMPILER_HALT_OFFSET__`. + */ + public function __construct($fileName, $offset) + { + if (!is_file($fileName)) { + throw new Mustache_Exception_InvalidArgumentException('InlineLoader expects a valid filename.'); + } + + if (!is_int($offset) || $offset < 0) { + throw new Mustache_Exception_InvalidArgumentException('InlineLoader expects a valid file offset.'); + } + + $this->fileName = $fileName; + $this->offset = $offset; + } + + /** + * Load a Template by name. + * + * @throws Mustache_Exception_UnknownTemplateException If a template file is not found. + * + * @param string $name + * + * @return string Mustache Template source + */ + public function load($name) + { + $this->loadTemplates(); + + if (!array_key_exists($name, $this->templates)) { + throw new Mustache_Exception_UnknownTemplateException($name); + } + + return $this->templates[$name]; + } + + /** + * Parse and load templates from the end of a source file. + */ + protected function loadTemplates() + { + if ($this->templates === null) { + $this->templates = array(); + $data = file_get_contents($this->fileName, false, null, $this->offset); + foreach (preg_split("/^@@(?= [\w\d\.]+$)/m", $data, -1) as $chunk) { + if (trim($chunk)) { + list($name, $content) = explode("\n", $chunk, 2); + $this->templates[trim($name)] = trim($content); + } + } + } + } +} diff --git a/test/Mustache/Test/Loader/InlineLoaderTest.php b/test/Mustache/Test/Loader/InlineLoaderTest.php new file mode 100644 index 0000000..52a24bd --- /dev/null +++ b/test/Mustache/Test/Loader/InlineLoaderTest.php @@ -0,0 +1,56 @@ +assertEquals('{{ foo }}', $loader->load('foo')); + $this->assertEquals('{{#bar}}BAR{{/bar}}', $loader->load('bar')); + } + + /** + * @expectedException Mustache_Exception_UnknownTemplateException + */ + public function testMissingTemplatesThrowExceptions() + { + $loader = new Mustache_Loader_InlineLoader(__FILE__, __COMPILER_HALT_OFFSET__); + $loader->load('not_a_real_template'); + } + + /** + * @expectedException Mustache_Exception_InvalidArgumentException + */ + public function testInvalidOffsetThrowsException() + { + $loader = new Mustache_Loader_InlineLoader(__FILE__, 'notanumber'); + } + + /** + * @expectedException Mustache_Exception_InvalidArgumentException + */ + public function testInvalidFileThrowsException() + { + $loader = new Mustache_Loader_InlineLoader('notarealfile', __COMPILER_HALT_OFFSET__); + } +} + +__halt_compiler(); + +@@ foo +{{ foo }} + +@@ bar +{{#bar}}BAR{{/bar}} From e5bc8d5edf02ff27cad4d7304e8aa59a91c934b4 Mon Sep 17 00:00:00 2001 From: Justin Hileman Date: Mon, 21 Jan 2013 10:26:12 -0800 Subject: [PATCH 11/29] Add a CascadingLoader implementation. --- src/Mustache/Loader/CascadingLoader.php | 69 +++++++++++++++++++ .../Test/Loader/CascadingLoaderTest.php | 40 +++++++++++ 2 files changed, 109 insertions(+) create mode 100644 src/Mustache/Loader/CascadingLoader.php create mode 100644 test/Mustache/Test/Loader/CascadingLoaderTest.php diff --git a/src/Mustache/Loader/CascadingLoader.php b/src/Mustache/Loader/CascadingLoader.php new file mode 100644 index 0000000..192edb9 --- /dev/null +++ b/src/Mustache/Loader/CascadingLoader.php @@ -0,0 +1,69 @@ +loaders = array(); + foreach ($loaders as $loader) { + $this->addLoader($loader); + } + } + + /** + * Add a Loader instance. + * + * @param Mustache_Loader $loader A Mustache Loader instance + */ + public function addLoader(Mustache_Loader $loader) + { + $this->loaders[] = $loader; + } + + /** + * Load a Template by name. + * + * @throws Mustache_Exception_UnknownTemplateException If a template file is not found. + * + * @param string $name + * + * @return string Mustache Template source + */ + public function load($name) + { + foreach ($this->loaders as $loader) { + try { + return $loader->load($name); + } catch (Mustache_Exception_UnknownTemplateException $e) { + // do nothing, check the next loader. + } + } + + throw new Mustache_Exception_UnknownTemplateException($name); + } +} diff --git a/test/Mustache/Test/Loader/CascadingLoaderTest.php b/test/Mustache/Test/Loader/CascadingLoaderTest.php new file mode 100644 index 0000000..06e1725 --- /dev/null +++ b/test/Mustache/Test/Loader/CascadingLoaderTest.php @@ -0,0 +1,40 @@ + '{{ foo }}')), + new Mustache_Loader_ArrayLoader(array('bar' => '{{#bar}}BAR{{/bar}}')), + )); + + $this->assertEquals('{{ foo }}', $loader->load('foo')); + $this->assertEquals('{{#bar}}BAR{{/bar}}', $loader->load('bar')); + } + + /** + * @expectedException Mustache_Exception_UnknownTemplateException + */ + public function testMissingTemplatesThrowExceptions() + { + $loader = new Mustache_Loader_CascadingLoader(array( + new Mustache_Loader_ArrayLoader(array('foo' => '{{ foo }}')), + new Mustache_Loader_ArrayLoader(array('bar' => '{{#bar}}BAR{{/bar}}')), + )); + + $loader->load('not_a_real_template'); + } +} From b1ca6f3cae1a645b89f6529b0e7cba3793d1114a Mon Sep 17 00:00:00 2001 From: Justin Hileman Date: Wed, 23 Jan 2013 06:24:15 -0800 Subject: [PATCH 12/29] Update Lambda Helper docblock. It was a lie. --- src/Mustache/LambdaHelper.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Mustache/LambdaHelper.php b/src/Mustache/LambdaHelper.php index 6f226c5..dfd4659 100644 --- a/src/Mustache/LambdaHelper.php +++ b/src/Mustache/LambdaHelper.php @@ -12,8 +12,9 @@ /** * Mustache Lambda Helper. * - * Passed to section and interpolation lambdas, giving them access to a `render` - * method for rendering a string with the current context. + * Passed as the second argument to section lambdas (higher order sections), + * giving them access to a `render` method for rendering a string with the + * current context. */ class Mustache_LambdaHelper { From 2c29f7e2b62e91915f40fd0d4d739708451fa6eb Mon Sep 17 00:00:00 2001 From: Shahar Roth Date: Thu, 24 Jan 2013 15:09:36 -0800 Subject: [PATCH 13/29] Update src/Mustache/Engine.php --- src/Mustache/Engine.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Mustache/Engine.php b/src/Mustache/Engine.php index ddfffca..bc9c90d 100644 --- a/src/Mustache/Engine.php +++ b/src/Mustache/Engine.php @@ -86,7 +86,7 @@ class Mustache_Engine * // A Mustache Logger instance. No logging will occur unless this is set. Using a PSR-3 compatible * // logging library -- such as Monolog -- is highly recommended. A simple stream logger implementation is * // available as well: - * 'logger' => new Mustache_StreamLogger('php://stderr'), + * 'logger' => new Mustache_Logger_StreamLogger('php://stderr'), * ); * * @param array $options (default: array()) From 05e527fe212cd1d305e557d82eef16b06a250bea Mon Sep 17 00:00:00 2001 From: Justin Hileman Date: Sat, 26 Jan 2013 14:36:24 -0800 Subject: [PATCH 14/29] Don't instantiate a LambdaHelper for classes with no Lambdas :) --- src/Mustache/Compiler.php | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/Mustache/Compiler.php b/src/Mustache/Compiler.php index e22d02a..f7f1d31 100644 --- a/src/Mustache/Compiler.php +++ b/src/Mustache/Compiler.php @@ -141,6 +141,24 @@ class Mustache_Compiler %s }'; + const KLASS_NO_LAMBDAS = 'walk($tree); $sections = implode("\n", $this->sections); + $klass = empty($this->sections) ? self::KLASS_NO_LAMBDAS : self::KLASS; - return sprintf($this->prepare(self::KLASS, 0, false), $name, $code, $this->getEscape('$buffer'), $sections); + return sprintf($this->prepare($klass, 0, false), $name, $code, $this->getEscape('$buffer'), $sections); } const SECTION_CALL = ' From cf76a4b8f908507e6a5e25b9ccf3e5106e69a032 Mon Sep 17 00:00:00 2001 From: Justin Hileman Date: Sat, 26 Jan 2013 14:49:14 -0800 Subject: [PATCH 15/29] Remove unused `escape` param from `renderInternal` --- src/Mustache/Compiler.php | 18 +++++------------- src/Mustache/Template.php | 5 +++-- test/Mustache/Test/CompilerTest.php | 4 ---- 3 files changed, 8 insertions(+), 19 deletions(-) diff --git a/src/Mustache/Compiler.php b/src/Mustache/Compiler.php index f7f1d31..e35f6f7 100644 --- a/src/Mustache/Compiler.php +++ b/src/Mustache/Compiler.php @@ -126,17 +126,13 @@ class Mustache_Compiler { private $lambdaHelper; - public function renderInternal(Mustache_Context $context, $indent = \'\', $escape = false) + public function renderInternal(Mustache_Context $context, $indent = \'\') { $this->lambdaHelper = new Mustache_LambdaHelper($this->mustache, $context); $buffer = \'\'; %s - if ($escape) { - return %s; - } else { - return $buffer; - } + return $buffer; } %s }'; @@ -145,16 +141,12 @@ class Mustache_Compiler class %s extends Mustache_Template { - public function renderInternal(Mustache_Context $context, $indent = \'\', $escape = false) + public function renderInternal(Mustache_Context $context, $indent = \'\') { $buffer = \'\'; %s - if ($escape) { - return %s; - } else { - return $buffer; - } + return $buffer; } %s }'; @@ -173,7 +165,7 @@ class Mustache_Compiler $sections = implode("\n", $this->sections); $klass = empty($this->sections) ? self::KLASS_NO_LAMBDAS : self::KLASS; - return sprintf($this->prepare($klass, 0, false), $name, $code, $this->getEscape('$buffer'), $sections); + return sprintf($this->prepare($klass, 0, false), $name, $code, $sections); } const SECTION_CALL = ' diff --git a/src/Mustache/Template.php b/src/Mustache/Template.php index b9c81fd..b3d57ed 100644 --- a/src/Mustache/Template.php +++ b/src/Mustache/Template.php @@ -67,13 +67,14 @@ abstract class Mustache_Template * * This is where the magic happens :) * + * NOTE: This method is not part of the Mustache.php public API. + * * @param Mustache_Context $context * @param string $indent (default: '') - * @param bool $escape (default: false) * * @return string Rendered template */ - abstract public function renderInternal(Mustache_Context $context, $indent = '', $escape = false); + abstract public function renderInternal(Mustache_Context $context, $indent = ''); /** * Tests whether a value should be iterated over (e.g. in a section context). diff --git a/test/Mustache/Test/CompilerTest.php b/test/Mustache/Test/CompilerTest.php index c952e0c..a94a3f3 100644 --- a/test/Mustache/Test/CompilerTest.php +++ b/test/Mustache/Test/CompilerTest.php @@ -33,13 +33,11 @@ class Mustache_Test_CompilerTest extends PHPUnit_Framework_TestCase return array( array('', array(), 'Banana', false, 'ISO-8859-1', array( "\nclass Banana extends Mustache_Template", - 'return htmlspecialchars($buffer, ENT_COMPAT, \'ISO-8859-1\');', 'return $buffer;', )), array('', array($this->createTextToken('TEXT')), 'Monkey', false, 'UTF-8', array( "\nclass Monkey extends Mustache_Template", - 'return htmlspecialchars($buffer, ENT_COMPAT, \'UTF-8\');', '$buffer .= $indent . \'TEXT\';', 'return $buffer;', )), @@ -47,7 +45,6 @@ class Mustache_Test_CompilerTest extends PHPUnit_Framework_TestCase array('', array($this->createTextToken('TEXT')), 'Monkey', true, 'ISO-8859-1', array( "\nclass Monkey extends Mustache_Template", '$buffer .= $indent . \'TEXT\';', - 'return call_user_func($this->mustache->getEscape(), $buffer);', 'return $buffer;', )), @@ -77,7 +74,6 @@ class Mustache_Test_CompilerTest extends PHPUnit_Framework_TestCase '$buffer .= htmlspecialchars($value, ENT_COMPAT, \'UTF-8\');', '$value = $context->last();', '$buffer .= \'\\\'bar\\\'\';', - 'return htmlspecialchars($buffer, ENT_COMPAT, \'UTF-8\');', 'return $buffer;', ) ), From a777c587f2349c8ee09a48d3b0d6f4a6757e6d84 Mon Sep 17 00:00:00 2001 From: Justin Hileman Date: Sat, 26 Jan 2013 15:30:23 -0800 Subject: [PATCH 16/29] Add `resolveValue` method to base Template. DRYs up compiled class output a bit and makes things FASTER! Speeds up value resolution by 33% for primitives, 25% for methods and properties, and 10% for lambdas. --- src/Mustache/Compiler.php | 7 +------ src/Mustache/Template.php | 22 ++++++++++++++++++++++ test/Mustache/Test/CompilerTest.php | 4 ++-- 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/src/Mustache/Compiler.php b/src/Mustache/Compiler.php index e35f6f7..27f02f0 100644 --- a/src/Mustache/Compiler.php +++ b/src/Mustache/Compiler.php @@ -275,12 +275,7 @@ class Mustache_Compiler } const VARIABLE = ' - $value = $context->%s(%s); - if (!is_string($value) && is_callable($value)) { - $value = $this->mustache - ->loadLambda((string) call_user_func($value)) - ->renderInternal($context, $indent); - }%s + $value = $this->resolveValue($context->%s(%s), $context, $indent);%s $buffer .= %s%s; '; diff --git a/src/Mustache/Template.php b/src/Mustache/Template.php index b3d57ed..4c67445 100644 --- a/src/Mustache/Template.php +++ b/src/Mustache/Template.php @@ -147,4 +147,26 @@ abstract class Mustache_Template return $stack; } + + /** + * Resolve a context value. + * + * Invoke the value if it is callable, otherwise return the value. + * + * @param mixed $value + * @param Mustache_Context $context + * @param string $indent + * + * @return string + */ + protected function resolveValue($value, Mustache_Context $context, $indent = '') + { + if (!is_string($value) && is_callable($value)) { + return $this->mustache + ->loadLambda((string) call_user_func($value)) + ->renderInternal($context, $indent); + } + + return $value; + } } diff --git a/test/Mustache/Test/CompilerTest.php b/test/Mustache/Test/CompilerTest.php index a94a3f3..134456d 100644 --- a/test/Mustache/Test/CompilerTest.php +++ b/test/Mustache/Test/CompilerTest.php @@ -70,9 +70,9 @@ class Mustache_Test_CompilerTest extends PHPUnit_Framework_TestCase "\nclass Monkey extends Mustache_Template", '$buffer .= $indent . \'foo\'', '$buffer .= "\n"', - '$value = $context->find(\'name\');', + '$value = $this->resolveValue($context->find(\'name\'), $context, $indent);', '$buffer .= htmlspecialchars($value, ENT_COMPAT, \'UTF-8\');', - '$value = $context->last();', + '$value = $this->resolveValue($context->last(), $context, $indent);', '$buffer .= \'\\\'bar\\\'\';', 'return $buffer;', ) From d5e199b3b9824ca22d788d064761166ecdbe1e96 Mon Sep 17 00:00:00 2001 From: Justin Hileman Date: Sat, 26 Jan 2013 16:25:57 -0800 Subject: [PATCH 17/29] Update build_bootstrap with all the new classes! --- bin/build_bootstrap.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/bin/build_bootstrap.php b/bin/build_bootstrap.php index fe7b632..ea0d917 100755 --- a/bin/build_bootstrap.php +++ b/bin/build_bootstrap.php @@ -36,11 +36,21 @@ SymfonyClassCollectionLoader::load(array( '\Mustache_Engine', '\Mustache_Compiler', '\Mustache_Context', + '\Mustache_Exception', + '\Mustache_Exception_InvalidArgumentException', + '\Mustache_Exception_LogicException', + '\Mustache_Exception_RuntimeException', + '\Mustache_Exception_SyntaxException', + '\Mustache_Exception_UnknownFilterException', + '\Mustache_Exception_UnknownHelperException', + '\Mustache_Exception_UnknownTemplateException', '\Mustache_HelperCollection', '\Mustache_LambdaHelper', '\Mustache_Loader', '\Mustache_Loader_ArrayLoader', + '\Mustache_Loader_CascadingLoader', '\Mustache_Loader_FilesystemLoader', + '\Mustache_Loader_InlineLoader', '\Mustache_Loader_MutableLoader', '\Mustache_Loader_StringLoader', '\Mustache_Logger', From c75b4c2e0b4831fbcc66e0fa61a6d477af62157d Mon Sep 17 00:00:00 2001 From: Justin Hileman Date: Sat, 26 Jan 2013 16:34:16 -0800 Subject: [PATCH 18/29] Fix compiled templates' PSR-2 compliance. --- src/Mustache/Compiler.php | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/Mustache/Compiler.php b/src/Mustache/Compiler.php index 27f02f0..d6c448d 100644 --- a/src/Mustache/Compiler.php +++ b/src/Mustache/Compiler.php @@ -148,7 +148,6 @@ class Mustache_Compiler return $buffer; } - %s }'; /** @@ -165,7 +164,7 @@ class Mustache_Compiler $sections = implode("\n", $this->sections); $klass = empty($this->sections) ? self::KLASS_NO_LAMBDAS : self::KLASS; - return sprintf($this->prepare($klass, 0, false), $name, $code, $sections); + return sprintf($this->prepare($klass, 0, false, true), $name, $code, $sections); } const SECTION_CALL = ' @@ -174,7 +173,8 @@ class Mustache_Compiler '; const SECTION = ' - private function section%s(Mustache_Context $context, $indent, $value) { + private function section%s(Mustache_Context $context, $indent, $value) + { $buffer = \'\'; if (!is_string($value) && is_callable($value)) { $source = %s; @@ -377,15 +377,19 @@ class Mustache_Compiler * @param string $text * @param int $bonus Additional indent level (default: 0) * @param boolean $prependNewline Prepend a newline to the snippet? (default: true) + * @param boolean $appendNewline Append a newline to the snippet? (default: false) * * @return string PHP source code snippet */ - private function prepare($text, $bonus = 0, $prependNewline = true) + private function prepare($text, $bonus = 0, $prependNewline = true, $appendNewline = false) { $text = ($prependNewline ? "\n" : '').trim($text); if ($prependNewline) { $bonus++; } + if ($appendNewline) { + $text .= "\n"; + } return preg_replace("/\n( {8})?/", "\n".str_repeat(" ", $bonus * 4), $text); } From 12d6884b4b14fe0287cffcb1eff184477cc9d776 Mon Sep 17 00:00:00 2001 From: Justin Hileman Date: Sat, 26 Jan 2013 16:48:35 -0800 Subject: [PATCH 19/29] Improve test coverage for custom escapers and charsets. --- test/Mustache/Test/CompilerTest.php | 42 +++++++++++++++++++++++++---- 1 file changed, 37 insertions(+), 5 deletions(-) diff --git a/test/Mustache/Test/CompilerTest.php b/test/Mustache/Test/CompilerTest.php index 134456d..bd94073 100644 --- a/test/Mustache/Test/CompilerTest.php +++ b/test/Mustache/Test/CompilerTest.php @@ -42,11 +42,43 @@ class Mustache_Test_CompilerTest extends PHPUnit_Framework_TestCase 'return $buffer;', )), - array('', array($this->createTextToken('TEXT')), 'Monkey', true, 'ISO-8859-1', array( - "\nclass Monkey extends Mustache_Template", - '$buffer .= $indent . \'TEXT\';', - 'return $buffer;', - )), + array( + '', + array( + array( + Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_ESCAPED, + Mustache_Tokenizer::NAME => 'name', + ) + ), + 'Monkey', + true, + 'ISO-8859-1', + array( + "\nclass Monkey extends Mustache_Template", + '$value = $this->resolveValue($context->find(\'name\'), $context, $indent);', + '$buffer .= $indent . call_user_func($this->mustache->getEscape(), $value);', + 'return $buffer;', + ) + ), + + array( + '', + array( + array( + Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_ESCAPED, + Mustache_Tokenizer::NAME => 'name', + ) + ), + 'Monkey', + false, + 'ISO-8859-1', + array( + "\nclass Monkey extends Mustache_Template", + '$value = $this->resolveValue($context->find(\'name\'), $context, $indent);', + '$buffer .= $indent . htmlspecialchars($value, ENT_COMPAT, \'ISO-8859-1\');', + 'return $buffer;', + ) + ), array( '', From 8053ce7093f3e6d0c1524b4c7ccab86f75d12d8a Mon Sep 17 00:00:00 2001 From: Matt DeClaire Date: Thu, 14 Feb 2013 16:00:37 -0800 Subject: [PATCH 20/29] implement default behavior for the partials_loader --- src/Mustache/Engine.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Mustache/Engine.php b/src/Mustache/Engine.php index 94803cb..807dfcc 100644 --- a/src/Mustache/Engine.php +++ b/src/Mustache/Engine.php @@ -113,6 +113,8 @@ class Mustache_Engine if (isset($options['partials_loader'])) { $this->setPartialsLoader($options['partials_loader']); + } else if (isset($options['loader'])) { + $this->setPartialsLoader($options['loader']); } if (isset($options['partials'])) { From 62435a5705bedd9fefeae6f814cc07d9f4e175ae Mon Sep 17 00:00:00 2001 From: Matt DeClaire Date: Fri, 15 Feb 2013 10:02:30 -0800 Subject: [PATCH 21/29] lazily default partialsLoader to loader Conflicts: src/Mustache/Engine.php --- src/Mustache/Engine.php | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/Mustache/Engine.php b/src/Mustache/Engine.php index 807dfcc..b892eef 100644 --- a/src/Mustache/Engine.php +++ b/src/Mustache/Engine.php @@ -113,8 +113,6 @@ class Mustache_Engine if (isset($options['partials_loader'])) { $this->setPartialsLoader($options['partials_loader']); - } else if (isset($options['loader'])) { - $this->setPartialsLoader($options['loader']); } if (isset($options['partials'])) { @@ -228,7 +226,7 @@ class Mustache_Engine public function getPartialsLoader() { if (!isset($this->partialsLoader)) { - $this->partialsLoader = new Mustache_Loader_ArrayLoader; + $this->partialsLoader = $this->loader; } return $this->partialsLoader; @@ -243,12 +241,15 @@ class Mustache_Engine */ public function setPartials(array $partials = array()) { - $loader = $this->getPartialsLoader(); - if (!$loader instanceof Mustache_Loader_MutableLoader) { - throw new Mustache_Exception_RuntimeException('Unable to set partials on an immutable Mustache Loader instance'); + if (isset($this->partialsLoader)) { + if (!$this->partialsLoader instanceof Mustache_Loader_MutableLoader) { + throw new Mustache_Exception_RuntimeException('Unable to set partials on an immutable Mustache Loader instance'); + } + } else { + $this->partialsLoader = new Mustache_Loader_ArrayLoader; } - $loader->setTemplates($partials); + $this->partialsLoader->setTemplates($partials); } /** From 5a3802e2a6c23d58bf20993eb00755a90e239a26 Mon Sep 17 00:00:00 2001 From: Matt DeClaire Date: Fri, 15 Feb 2013 10:07:40 -0800 Subject: [PATCH 22/29] fix for when loader is not defined --- src/Mustache/Engine.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Mustache/Engine.php b/src/Mustache/Engine.php index b892eef..62309d2 100644 --- a/src/Mustache/Engine.php +++ b/src/Mustache/Engine.php @@ -226,7 +226,7 @@ class Mustache_Engine public function getPartialsLoader() { if (!isset($this->partialsLoader)) { - $this->partialsLoader = $this->loader; + $this->partialsLoader = $this->getLoader(); } return $this->partialsLoader; From 32b747be5cbe5be347eaadc209148b80266125b3 Mon Sep 17 00:00:00 2001 From: Matt DeClaire Date: Fri, 15 Feb 2013 10:55:04 -0800 Subject: [PATCH 23/29] fix test: a partialLoader should match the loader when neither are specified --- test/Mustache/Test/EngineTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/Mustache/Test/EngineTest.php b/test/Mustache/Test/EngineTest.php index 5625637..8149b13 100644 --- a/test/Mustache/Test/EngineTest.php +++ b/test/Mustache/Test/EngineTest.php @@ -104,7 +104,7 @@ class Mustache_Test_EngineTest extends PHPUnit_Framework_TestCase $mustache->setLoader($loader); $this->assertSame($loader, $mustache->getLoader()); - $this->assertNotSame($loader, $mustache->getPartialsLoader()); + $this->assertSame($loader, $mustache->getPartialsLoader()); $mustache->setPartialsLoader($loader); $this->assertSame($loader, $mustache->getPartialsLoader()); From 72007e65b439c5f915291674ea4f8614e297e669 Mon Sep 17 00:00:00 2001 From: Justin Hileman Date: Tue, 12 Mar 2013 15:29:18 -0700 Subject: [PATCH 24/29] Simplify `setPartials` nested ifs. --- src/Mustache/Engine.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Mustache/Engine.php b/src/Mustache/Engine.php index 62309d2..fd2fb05 100644 --- a/src/Mustache/Engine.php +++ b/src/Mustache/Engine.php @@ -241,14 +241,14 @@ class Mustache_Engine */ public function setPartials(array $partials = array()) { - if (isset($this->partialsLoader)) { - if (!$this->partialsLoader instanceof Mustache_Loader_MutableLoader) { - throw new Mustache_Exception_RuntimeException('Unable to set partials on an immutable Mustache Loader instance'); - } - } else { + if (!isset($this->partialsLoader)) { $this->partialsLoader = new Mustache_Loader_ArrayLoader; } + if (!$this->partialsLoader instanceof Mustache_Loader_MutableLoader) { + throw new Mustache_Exception_RuntimeException('Unable to set partials on an immutable Mustache Loader instance'); + } + $this->partialsLoader->setTemplates($partials); } From ca44ef68f8d2b232bf5c0ef4d598462d6ac92c98 Mon Sep 17 00:00:00 2001 From: Justin Hileman Date: Tue, 12 Mar 2013 15:52:42 -0700 Subject: [PATCH 25/29] Move loader cascading into the loadPartial method. This means the `partialsLoader` property is never set to the default loader, fixing things like `setPartials`, but template loading cascades as per the spec. Add test coverage for partial cascading. --- src/Mustache/Engine.php | 16 ++++++++++++---- test/Mustache/Test/EngineTest.php | 25 ++++++++++++++++++++++++- 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/src/Mustache/Engine.php b/src/Mustache/Engine.php index fd2fb05..2f61f58 100644 --- a/src/Mustache/Engine.php +++ b/src/Mustache/Engine.php @@ -226,7 +226,7 @@ class Mustache_Engine public function getPartialsLoader() { if (!isset($this->partialsLoader)) { - $this->partialsLoader = $this->getLoader(); + $this->partialsLoader = new Mustache_Loader_ArrayLoader; } return $this->partialsLoader; @@ -492,13 +492,21 @@ class Mustache_Engine public function loadPartial($name) { try { - return $this->loadSource($this->getPartialsLoader()->load($name)); - } catch (InvalidArgumentException $e) { + if (isset($this->partialsLoader)) { + $loader = $this->partialsLoader; + } elseif (isset($this->loader) && !$this->loader instanceof Mustache_Loader_StringLoader) { + $loader = $this->loader; + } else { + throw new Mustache_Exception_UnknownTemplateException($name); + } + + return $this->loadSource($loader->load($name)); + } catch (Mustache_Exception_UnknownTemplateException $e) { // If the named partial cannot be found, log then return null. $this->log( Mustache_Logger::WARNING, 'Partial not found: "{name}"', - array('name' => $name) + array('name' => $e->getTemplateName()) ); } } diff --git a/test/Mustache/Test/EngineTest.php b/test/Mustache/Test/EngineTest.php index 8149b13..5c00821 100644 --- a/test/Mustache/Test/EngineTest.php +++ b/test/Mustache/Test/EngineTest.php @@ -104,7 +104,7 @@ class Mustache_Test_EngineTest extends PHPUnit_Framework_TestCase $mustache->setLoader($loader); $this->assertSame($loader, $mustache->getLoader()); - $this->assertSame($loader, $mustache->getPartialsLoader()); + $this->assertNotSame($loader, $mustache->getPartialsLoader()); $mustache->setPartialsLoader($loader); $this->assertSame($loader, $mustache->getPartialsLoader()); @@ -240,6 +240,29 @@ class Mustache_Test_EngineTest extends PHPUnit_Framework_TestCase $mustache->setLogger(new StdClass); } + public function testLoadPartialCascading() + { + $loader = new Mustache_Loader_ArrayLoader(array( + 'foo' => 'FOO', + )); + + $mustache = new Mustache_Engine(array('loader' => $loader)); + + $tpl = $mustache->loadTemplate('foo'); + + $this->assertSame($tpl, $mustache->loadPartial('foo')); + + $mustache->setPartials(array( + 'foo' => 'f00', + )); + + // setting partials overrides the default template loading fallback. + $this->assertNotSame($tpl, $mustache->loadPartial('foo')); + + // but it didn't overwrite the original template loader templates. + $this->assertSame($tpl, $mustache->loadTemplate('foo')); + } + public function testPartialLoadFailLogging() { $name = tempnam(sys_get_temp_dir(), 'mustache-test'); From 32a397f93d39570ca4a7174261fd804d9168754f Mon Sep 17 00:00:00 2001 From: Justin Hileman Date: Tue, 12 Mar 2013 16:20:02 -0700 Subject: [PATCH 26/29] Remove unused submodule. --- .gitmodules | 3 --- vendor/symfony/Symfony/Component/ClassLoader | 1 - 2 files changed, 4 deletions(-) delete mode 160000 vendor/symfony/Symfony/Component/ClassLoader diff --git a/.gitmodules b/.gitmodules index ee478af..042ea4d 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,6 +4,3 @@ [submodule "vendor/yaml"] path = vendor/yaml url = https://github.com/fabpot/yaml.git -[submodule "vendor/symfony/Symfony/Component/ClassLoader"] - path = vendor/symfony/Symfony/Component/ClassLoader - url = https://github.com/symfony/ClassLoader.git diff --git a/vendor/symfony/Symfony/Component/ClassLoader b/vendor/symfony/Symfony/Component/ClassLoader deleted file mode 160000 index 0e6ee8d..0000000 --- a/vendor/symfony/Symfony/Component/ClassLoader +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 0e6ee8d07dda6920106048247d41249201604e76 From 7fb7758178a144a7081bfdf0a23c7eaf4b967704 Mon Sep 17 00:00:00 2001 From: Justin Hileman Date: Tue, 12 Mar 2013 16:29:33 -0700 Subject: [PATCH 27/29] Include header in generated bootstrap files. --- bin/build_bootstrap.php | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/bin/build_bootstrap.php b/bin/build_bootstrap.php index ea0d917..2574a9f 100755 --- a/bin/build_bootstrap.php +++ b/bin/build_bootstrap.php @@ -75,6 +75,19 @@ class SymfonyClassCollectionLoader { static private $loaded; + const HEADER = <<\s*$/'), '', file_get_contents($r->getFileName())); } - $cache = $cacheDir.'/'.$name.$extension; - self::writeCacheFile($cache, self::stripComments(' Date: Thu, 28 Mar 2013 16:48:00 -0400 Subject: [PATCH 28/29] s/an/a/ --- src/Mustache/Loader/InlineLoader.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Mustache/Loader/InlineLoader.php b/src/Mustache/Loader/InlineLoader.php index 835fbf1..1463bf8 100644 --- a/src/Mustache/Loader/InlineLoader.php +++ b/src/Mustache/Loader/InlineLoader.php @@ -10,7 +10,7 @@ */ /** - * An Mustache Template loader for inline templates. + * A Mustache Template loader for inline templates. * * With the InlineLoader, templates can be defined at the end of any PHP source * file: From 0f1fc69e5c48ffea864ebfff0fe340e4591e432c Mon Sep 17 00:00:00 2001 From: Justin Hileman Date: Mon, 1 Apr 2013 20:50:30 -0700 Subject: [PATCH 29/29] Bump to v2.3.0 --- src/Mustache/Engine.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Mustache/Engine.php b/src/Mustache/Engine.php index 7cb0baa..adb0c0e 100644 --- a/src/Mustache/Engine.php +++ b/src/Mustache/Engine.php @@ -23,7 +23,7 @@ */ class Mustache_Engine { - const VERSION = '2.2.0'; + const VERSION = '2.3.0'; const SPEC_VERSION = '1.1.2'; const PRAGMA_FILTERS = 'FILTERS';