Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 11 additions & 7 deletions src/main/php/com/github/mustache/FileBasedTemplateLoader.class.php
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
<?php namespace com\github\mustache;

use util\Objects;
use text\StreamTokenizer;
use com\github\mustache\templates\Templates;
use com\github\mustache\templates\Tokens;
use com\github\mustache\templates\NotFound;

/**
* File-based template loading loads templates from the file system.
*
* @test xp://com.github.mustache.unittest.FileBasedTemplateLoaderTest
*/
abstract class FileBasedTemplateLoader implements TemplateLoader, WithListing {
abstract class FileBasedTemplateLoader extends Templates {
protected $base, $extensions, $listing;

/**
Expand Down Expand Up @@ -46,16 +50,16 @@ protected abstract function inputStreamFor($name);
/**
* Load a template by a given name
*
* @param string $name The template name without file extension
* @return io.streams.InputStream
* @throws com.github.mustache.TemplateNotFoundException
* @param string $name The template name, not including the file extension
* @return com.github.mustache.templates.Source
*/
public function load($name) {
public function source($name) {
$variants= $this->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));
}

/**
Expand Down
27 changes: 15 additions & 12 deletions src/main/php/com/github/mustache/InMemory.class.php
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
<?php namespace com\github\mustache;

use io\streams\MemoryInputStream;
use text\StringTokenizer;
use com\github\mustache\templates\Templates;
use com\github\mustache\templates\NotFound;
use com\github\mustache\templates\Tokens;

/**
* Template loading
*
* @test xp://com.github.mustache.unittest.InMemoryTest
*/
class InMemory implements TemplateLoader, WithListing {
class InMemory extends Templates {
protected $templates, $listing;

/**
Expand Down Expand Up @@ -54,18 +57,18 @@ public function add($name, $bytes) {
return $this;
}

/**
* Load a template by a given name
*
* @param string $name The template name without file extension
* @return io.streams.InputStream
* @throws com.github.mustache.TemplateNotFoundException
*/
public function load($name) {
/**
* Load a template by a given name
*
* @param string $name The template name, not including the file extension
* @return com.github.mustache.templates.Source
*/
public function source($name) {
if (isset($this->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);
}

/**
Expand Down
83 changes: 37 additions & 46 deletions src/main/php/com/github/mustache/MustacheEngine.class.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
<?php namespace com\github\mustache;

use text\StreamTokenizer;
use com\github\mustache\templates\Source;
use com\github\mustache\templates\Templates;
use com\github\mustache\templates\FromLoader;
use text\StringTokenizer;

/**
Expand All @@ -23,8 +25,7 @@
* @see http://mustache.github.io/mustache.5.html
*/
class MustacheEngine {
protected $templates;
protected $parser;
protected $templates, $parser;
public $helpers= [];

/**
Expand All @@ -38,18 +39,22 @@ public function __construct() {
/**
* Sets template loader to be used
*
* @param com.github.mustache.TemplateLoader $l
* @param com.github.mustache.templates.Templates|com.github.mustache.TemplateLoader $l
* @return self this
*/
public function withTemplates(TemplateLoader $l) {
$this->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;
Expand Down Expand Up @@ -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('<string>', $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('<string>', $this->parser->parse(new StringTokenizer($source), $start, $end, $indent));
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could also be:

$source= new Tokens('<string>', new StringTokenizer($source));
return $source->compile($this->parser, $start, $end, $indent); 

...but the inlined version saves us a couple of nanoseconds here:)

}
}

/**
* Load a template.
* Load and compile a template
*
* @param string $name The template name.
* @param string $start Initial start tag, defaults to "{{"
Expand All @@ -117,64 +121,51 @@ 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);
}

/**
* Transform a template by its name, which is previously loaded from
* 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);
}
}
1 change: 1 addition & 0 deletions src/main/php/com/github/mustache/TemplateLoader.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
/**
* Template loading
*
* @deprecated Use com.github.mustache.templates.Templates instead!
* @test xp://com.github.mustache.unittest.TemplateTransformationTest
*/
interface TemplateLoader {
Expand Down
2 changes: 2 additions & 0 deletions src/main/php/com/github/mustache/WithListing.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

/**
* Template listing
*
* @deprecated Use com.github.mustache.templates.Templates instead!
*/
interface WithListing {

Expand Down
26 changes: 26 additions & 0 deletions src/main/php/com/github/mustache/templates/Compiled.class.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php namespace com\github\mustache\templates;

class Compiled extends Source {
private $tokens;

/** @param com.github.mustache.Template */
public function __construct($template) {
$this->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;
}
}
47 changes: 47 additions & 0 deletions src/main/php/com/github/mustache/templates/FromLoader.class.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php namespace com\github\mustache\templates;

use text\StreamTokenizer;
use lang\IllegalAccessException;
use com\github\mustache\WithListing;
use com\github\mustache\templates\Tokens;

/**
* Adapter for TemplateLoaders
*
* @deprecated Template loaders were replaced by `Templates`.
*/
class FromLoader extends Templates {
private $loader;

/** @param com.github.mustache.TemplateLoader $loader */
public function __construct($loader) {
$this->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');
}
}
}
33 changes: 33 additions & 0 deletions src/main/php/com/github/mustache/templates/NotFound.class.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php namespace com\github\mustache\templates;

use com\github\mustache\TemplateNotFoundException;

class NotFound extends Source {
private $reason;

/** @param string $reason */
public function __construct($reason) {
$this->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);
}
}
Loading