diff --git a/src/main/php/com/github/mustache/FileBasedTemplateLoader.class.php b/src/main/php/com/github/mustache/FileBasedTemplateLoader.class.php index e81daef..5dfcea7 100755 --- a/src/main/php/com/github/mustache/FileBasedTemplateLoader.class.php +++ b/src/main/php/com/github/mustache/FileBasedTemplateLoader.class.php @@ -1,13 +1,17 @@ variantsOf($name); foreach ($variants as $variant) { - if ($stream= $this->inputStreamFor($variant)) return $stream; + if ($stream= $this->inputStreamFor($variant)) return new Tokens($variant, new StreamTokenizer($stream)); } - throw new TemplateNotFoundException('Cannot find template ['.implode(', ', $variants).'] in '.Objects::stringOf($this->base)); + + return new NotFound('Cannot find template ['.implode(', ', $variants).'] in '.Objects::stringOf($this->base)); } /** diff --git a/src/main/php/com/github/mustache/InMemory.class.php b/src/main/php/com/github/mustache/InMemory.class.php index 7bfa40b..17b59d9 100755 --- a/src/main/php/com/github/mustache/InMemory.class.php +++ b/src/main/php/com/github/mustache/InMemory.class.php @@ -1,13 +1,16 @@ templates[$name])) { - return new MemoryInputStream($this->templates[$name]); + return new Tokens($name, new StringTokenizer($this->templates[$name])); + } else { + return new NotFound('Cannot find template '.$name); } - throw new TemplateNotFoundException('Cannot find template '.$name); } /** diff --git a/src/main/php/com/github/mustache/MustacheEngine.class.php b/src/main/php/com/github/mustache/MustacheEngine.class.php index e8406de..47ebe89 100644 --- a/src/main/php/com/github/mustache/MustacheEngine.class.php +++ b/src/main/php/com/github/mustache/MustacheEngine.class.php @@ -1,6 +1,8 @@ templates= $l; + public function withTemplates($l) { + if ($l instanceof Templates) { + $this->templates= $l; + } else { + $this->templates= new FromLoader($l); + } return $this; } /** - * Sets template loader to be used + * Gets used template loader * - * @return com.github.mustache.TemplateLoader + * @return com.github.mustache.Templates */ public function getTemplates() { return $this->templates; @@ -90,25 +95,24 @@ public function withHelpers(array $helpers) { } /** - * Compile a template. + * Compile a template * - * @param string $template The template, as a string + * @param string|com.github.mustache.templates.Source $source The template source * @param string $start Initial start tag, defaults to "{{" * @param string $end Initial end tag, defaults to "}}" * @param string $indent Indenting level, defaults to no indenting * @return com.github.mustache.Template */ - public function compile($template, $start= '{{', $end= '}}', $indent= '') { - return new Template('', $this->parser->parse( - new StringTokenizer($template), - $start, - $end, - $indent - )); + public function compile($source, $start= '{{', $end= '}}', $indent= '') { + if ($source instanceof Source) { + return $source->compile($this->parser, $start, $end, $indent); + } else { + return new Template('', $this->parser->parse(new StringTokenizer($source), $start, $end, $indent)); + } } /** - * Load a template. + * Load and compile a template * * @param string $name The template name. * @param string $start Initial start tag, defaults to "{{" @@ -117,47 +121,37 @@ public function compile($template, $start= '{{', $end= '}}', $indent= '') { * @return com.github.mustache.Template */ public function load($name, $start= '{{', $end= '}}', $indent= '') { - return new Template($name, $this->parser->parse( - new StreamTokenizer($this->templates->load($name)), - $start, - $end, - $indent - )); + return $this->templates->source($name)->compile($this->parser, $start, $end, $indent); } /** * Evaluate a compiled template. * * @param com.github.mustache.Template $template The template - * @param var $arg Either a view context, or a Context instance + * @param com.github.mustache.Context|[:var] $context The context * @return string The rendered output */ - public function evaluate(Template $template, $arg) { - if ($arg instanceof Context) { - $context= $arg; + public function evaluate(Template $template, $context) { + if ($context instanceof Context) { + $c= $context; } else { - $context= new DataContext($arg); + $c= new DataContext($context); } - return $template->evaluate($context->withEngine($this)); + return $template->evaluate($c->withEngine($this)); } /** - * Render a template - like evaluate(), but will compile if necessary. + * Render a template, compiling it from source * - * @param var $template The template, either as string or as compiled Template instance - * @param var $arg Either a view context, or a Context instance + * @param string|com.github.mustache.templates.Source $source The template source + * @param com.github.mustache.Context|[:var] $context The context * @param string $start Initial start tag, defaults to "{{" * @param string $end Initial end tag, defaults to "}}" * @param string $indent Indenting level, defaults to no indenting * @return string The rendered output */ - public function render($template, $arg, $start= '{{', $end= '}}', $indent= '') { - if ($template instanceof Template) { - $target= $template; - } else { - $target= $this->compile($template, $start, $end, $indent); - } - return $this->evaluate($target, $arg); + public function render($source, $context, $start= '{{', $end= '}}', $indent= '') { + return $this->evaluate($this->compile($source, $start, $end, $indent), $context); } /** @@ -165,16 +159,13 @@ public function render($template, $arg, $start= '{{', $end= '}}', $indent= '') { * the template loader. * * @param string $name The template name. - * @param var $arg Either a view context, or a Context instance + * @param com.github.mustache.Context|[:var] $context The context * @param string $start Initial start tag, defaults to "{{" * @param string $end Initial end tag, defaults to "}}" * @param string $indent Indenting level, defaults to no indenting * @return string The rendered output */ - public function transform($name, $arg, $start= '{{', $end= '}}', $indent= '') { - return $this->evaluate( - $this->load($name, $start, $end, $indent), - $arg - ); + public function transform($name, $context, $start= '{{', $end= '}}', $indent= '') { + return $this->evaluate($this->load($name, $start, $end, $indent), $context); } } \ No newline at end of file diff --git a/src/main/php/com/github/mustache/TemplateLoader.class.php b/src/main/php/com/github/mustache/TemplateLoader.class.php index 9fdd71a..33f7d99 100755 --- a/src/main/php/com/github/mustache/TemplateLoader.class.php +++ b/src/main/php/com/github/mustache/TemplateLoader.class.php @@ -3,6 +3,7 @@ /** * Template loading * + * @deprecated Use com.github.mustache.templates.Templates instead! * @test xp://com.github.mustache.unittest.TemplateTransformationTest */ interface TemplateLoader { diff --git a/src/main/php/com/github/mustache/WithListing.class.php b/src/main/php/com/github/mustache/WithListing.class.php index 677d500..e642e08 100755 --- a/src/main/php/com/github/mustache/WithListing.class.php +++ b/src/main/php/com/github/mustache/WithListing.class.php @@ -2,6 +2,8 @@ /** * Template listing + * + * @deprecated Use com.github.mustache.templates.Templates instead! */ interface WithListing { diff --git a/src/main/php/com/github/mustache/templates/Compiled.class.php b/src/main/php/com/github/mustache/templates/Compiled.class.php new file mode 100755 index 0000000..e63179b --- /dev/null +++ b/src/main/php/com/github/mustache/templates/Compiled.class.php @@ -0,0 +1,26 @@ +template= $template; + } + + /** @return string */ + public function code() { return (string)$this->template; } + + /** + * Compiles this source into a template + * + * @param com.github.mustache.MustacheParser $parser + * @param string $start + * @param string $end + * @param string $indent + * @return com.github.mustache.Template + */ + public function compile($parser, $start, $end, $indent) { + return $this->template; + } +} \ No newline at end of file diff --git a/src/main/php/com/github/mustache/templates/FromLoader.class.php b/src/main/php/com/github/mustache/templates/FromLoader.class.php new file mode 100755 index 0000000..e636e2d --- /dev/null +++ b/src/main/php/com/github/mustache/templates/FromLoader.class.php @@ -0,0 +1,47 @@ +loader= $loader; + } + + /** + * Load a template by a given name + * + * @param string $name The template name, not including the file extension + * @return com.github.mustache.TemplateSource + */ + public function source($name) { + try { + return new Tokens($name, new StreamTokenizer($this->loader->load($name))); + } catch (TemplateNotFoundException $e) { + return new NotFound($e->getMessage()); + } + } + + /** + * Returns available templates + * + * @return com.github.mustache.TemplateListing + */ + public function listing() { + if ($this->loader instanceof WithListing) { + return $this->loader->listing(); + } else { + throw new IllegalAccessException(typeof($this->loader)->toString().' does not provide listing'); + } + } +} \ No newline at end of file diff --git a/src/main/php/com/github/mustache/templates/NotFound.class.php b/src/main/php/com/github/mustache/templates/NotFound.class.php new file mode 100755 index 0000000..74b2c79 --- /dev/null +++ b/src/main/php/com/github/mustache/templates/NotFound.class.php @@ -0,0 +1,33 @@ +reason= $reason; + } + + /** @return bool */ + public function exists() { return false; } + + /** @return string */ + public function code() { + throw new TemplateNotFoundException($this->reason); + } + + /** + * Compiles this source into a template + * + * @param com.github.mustache.MustacheParser $parser + * @param string $start + * @param string $end + * @param string $indent + * @return com.github.mustache.Template + */ + public function compile($parser, $start, $end, $indent) { + throw new TemplateNotFoundException($this->reason); + } +} \ No newline at end of file diff --git a/src/main/php/com/github/mustache/templates/Source.class.php b/src/main/php/com/github/mustache/templates/Source.class.php new file mode 100755 index 0000000..5e92227 --- /dev/null +++ b/src/main/php/com/github/mustache/templates/Source.class.php @@ -0,0 +1,21 @@ +source($name)->code()); + } +} \ No newline at end of file diff --git a/src/main/php/com/github/mustache/templates/Tokens.class.php b/src/main/php/com/github/mustache/templates/Tokens.class.php new file mode 100755 index 0000000..0a95e1f --- /dev/null +++ b/src/main/php/com/github/mustache/templates/Tokens.class.php @@ -0,0 +1,40 @@ +source= $source; + $this->tokens= $tokens; + } + + /** @return string */ + public function code() { + $s= ''; + while ($this->tokens->hasMoreTokens()) { + $s.= $this->tokens->nextToken(true); + } + return $s; + } + + /** + * Compiles this source into a template + * + * @param com.github.mustache.MustacheParser $parser + * @param string $start + * @param string $end + * @param string $indent + * @return com.github.mustache.Template + */ + public function compile($parser, $start, $end, $indent) { + return new Template($this->source, $parser->parse($this->tokens, $start, $end, $indent)); + } +} \ No newline at end of file diff --git a/src/test/php/com/github/mustache/unittest/DeprecatedLoaderFunctionalityTest.class.php b/src/test/php/com/github/mustache/unittest/DeprecatedLoaderFunctionalityTest.class.php new file mode 100755 index 0000000..4cf0179 --- /dev/null +++ b/src/test/php/com/github/mustache/unittest/DeprecatedLoaderFunctionalityTest.class.php @@ -0,0 +1,21 @@ + $content]); + $this->assertEquals($content, Streams::readAll($loader->load('test'))); + } + + #[@test, @expect(class= TemplateNotFoundException::class, withMessage= 'Cannot find template not-found')] + public function load_raises_error_for_nonexistant_templates() { + (new InMemory())->load('not-found'); + } +} \ No newline at end of file diff --git a/src/test/php/com/github/mustache/unittest/FileBasedTemplateLoaderTest.class.php b/src/test/php/com/github/mustache/unittest/FileBasedTemplateLoaderTest.class.php index 65cecdd..073f052 100755 --- a/src/test/php/com/github/mustache/unittest/FileBasedTemplateLoaderTest.class.php +++ b/src/test/php/com/github/mustache/unittest/FileBasedTemplateLoaderTest.class.php @@ -40,14 +40,14 @@ protected function newFixture($args) { #[@test] public function load_asks_for_mustache_extension_by_default() { $loader= $this->newFixture(['base']); - $loader->load('template'); + $loader->source('template'); $this->assertEquals(['template.mustache'], $loader->askedFor); } #[@test] public function load_asks_for_all_given_variants() { $loader= $this->newFixture(['base', ['.mustache', '.ms']]); - $loader->load('template'); + $loader->source('template'); $this->assertEquals(['template.mustache', 'template.ms'], $loader->askedFor); } diff --git a/src/test/php/com/github/mustache/unittest/FilesInTest.class.php b/src/test/php/com/github/mustache/unittest/FilesInTest.class.php index c8a7b83..9ca7b4a 100755 --- a/src/test/php/com/github/mustache/unittest/FilesInTest.class.php +++ b/src/test/php/com/github/mustache/unittest/FilesInTest.class.php @@ -3,7 +3,6 @@ use com\github\mustache\FilesIn; use com\github\mustache\TemplateNotFoundException; use lang\System; -use io\streams\Streams; use io\Folder; use io\File; use io\FileUtil; @@ -39,17 +38,17 @@ public static function cleanupFiles() { } #[@test] - public function load_from_default_class_loader() { + public function source_from_default_class_loader() { $loader= new FilesIn(self::$temp); $this->assertEquals( 'Mustache template {{id}}', - Streams::readAll($loader->load('test')) + $loader->source('test')->code() ); } - #[@test, @expect(TemplateNotFoundException::class)] - public function load_non_existant() { - (new FilesIn(self::$temp))->load('@non.existant@'); + #[@test] + public function source_non_existant() { + $this->assertFalse((new FilesIn(self::$temp))->source('@non.existant@')->exists()); } #[@test] diff --git a/src/test/php/com/github/mustache/unittest/InMemoryTest.class.php b/src/test/php/com/github/mustache/unittest/InMemoryTest.class.php index 90489a7..b54b649 100755 --- a/src/test/php/com/github/mustache/unittest/InMemoryTest.class.php +++ b/src/test/php/com/github/mustache/unittest/InMemoryTest.class.php @@ -1,21 +1,19 @@ $content]); - $this->assertEquals($content, Streams::readAll($loader->load('test'))); + $this->assertEquals($content, $loader->source('test')->code()); } - #[@test, @expect(TemplateNotFoundException::class)] - public function load_non_existant() { - (new InMemory())->load('@non.existant@'); + #[@test] + public function source_non_existant() { + $this->assertFalse((new InMemory())->source('@non.existant@')->exists()); } #[@test] diff --git a/src/test/php/com/github/mustache/unittest/ResourcesInTest.class.php b/src/test/php/com/github/mustache/unittest/ResourcesInTest.class.php index ba896d9..a43e307 100755 --- a/src/test/php/com/github/mustache/unittest/ResourcesInTest.class.php +++ b/src/test/php/com/github/mustache/unittest/ResourcesInTest.class.php @@ -1,24 +1,22 @@ assertEquals( 'Mustache template {{id}}', - Streams::readAll($loader->load('com/github/mustache/unittest/template')) + $loader->source('com/github/mustache/unittest/template')->code() ); } - #[@test, @expect(TemplateNotFoundException::class)] - public function load_non_existant() { - (new ResourcesIn(ClassLoader::getDefault()))->load('@non.existant@'); + #[@test] + public function source_non_existant() { + $this->assertFalse((new ResourcesIn(ClassLoader::getDefault()))->source('@non.existant@')->exists()); } #[@test]