Skip to content

Commit

Permalink
[#11] Resolver integration with Mustache class
Browse files Browse the repository at this point in the history
- Modified Resolver to use SplStack internally, allowing a stack of
  paths
- Modified Mustache class to add accessor/mutator for resolver, and to
  proxy to resolver internally for retrieving templates
  • Loading branch information
weierophinney committed Jul 30, 2012
1 parent 1686c71 commit 0590505
Show file tree
Hide file tree
Showing 10 changed files with 129 additions and 77 deletions.
10 changes: 10 additions & 0 deletions .vimproject
Expand Up @@ -106,6 +106,16 @@ mustache=/home/matthew/git/phly_mustache CD=. filter="*.php *.html *.xml *.txt"
template-with-pragma-in-section.mustache
template-with-sections-and-delim-set.mustache
template-with-sub-view.mustache
foo.mustache
foo.tpl
foo=foo {
bar.mustache
bar.tpl
bar=bar {
baz.mustache
baz.tpl
}
}
}
}
}
Expand Down
124 changes: 67 additions & 57 deletions library/Phly/Mustache/Mustache.php
Expand Up @@ -11,29 +11,22 @@
namespace Phly\Mustache;

use ArrayObject;
use SplStack;

/**
* Mustache implementation
*
*
* @todo Prevent duplicate paths from being added
* @category Phly
* @package phly_mustache
*/
class Mustache
{
/**
/**
* Cached file-based templates; contains template name/token pairs
* @var array
* @var array
*/
protected $cachedTemplates = array();

/**
* Stack of template paths to search
* @var SplStack
*/
protected $templatePath;

/**
* Lexer
* @var Lexer
Expand All @@ -47,25 +40,21 @@ class Mustache
protected $renderer;

/**
* Suffix used when resolving templates
* @var string
* Template resolver
* @var Resolver\ResolverInterface
*/
protected $suffix = '.mustache';
protected $resolver;

/**
* Constructor
*
* @return void
* Suffix used when resolving templates
* @var string
*/
public function __construct()
{
$this->templatePath = new SplStack;
}
protected $suffix = '.mustache';

/**
* Set lexer to use when tokenizing templates
*
* @param Lexer $lexer
*
* @param Lexer $lexer
* @return Mustache
*/
public function setLexer(Lexer $lexer)
Expand All @@ -77,7 +66,7 @@ public function setLexer(Lexer $lexer)

/**
* Get lexer
*
*
* @return Lexer
*/
public function getLexer()
Expand All @@ -90,8 +79,8 @@ public function getLexer()

/**
* Set renderer
*
* @param Renderer $renderer
*
* @param Renderer $renderer
* @return Mustache
*/
public function setRenderer(Renderer $renderer)
Expand All @@ -103,7 +92,7 @@ public function setRenderer(Renderer $renderer)

/**
* Get renderer
*
*
* @return Renderer
*/
public function getRenderer()
Expand All @@ -114,53 +103,74 @@ public function getRenderer()
return $this->renderer;
}

/**
* Set template resolver
*
* @param Resolver\ResolverInterface $resolver
* @return Mustache
*/
public function setResolver(Resolver\ResolverInterface $resolver)
{
$this->resolver = $resolver;
return $this;
}

/**
* Get template resolver
*
* @return Resolver\ResolverInterface
*/
public function getResolver()
{
if (!$this->resolver instanceof Resolver\ResolverInterface) {
$this->setResolver(new Resolver\DefaultResolver());
}
return $this->resolver;
}

/**
* Add a template path to the template path stack
*
* @param string $path
*
* @param string $path
* @return Mustache
* @throws InvalidTemplatePathException
*/
public function setTemplatePath($path)
{
if (!is_dir($path)) {
throw new Exception\InvalidTemplatePathException();
}
$this->templatePath->push($path);
$this->getResolver()->setTemplatePath($path);
return $this;
}

/**
* Set suffix used when resolving templates
*
* @param string $suffix
*
* @param string $suffix
* @return Mustache
*/
public function setSuffix($suffix)
{
$this->suffix = '.' . ltrim($suffix, '.');
$this->getResolver()->setSuffix($suffix);
return $this;
}

/**
* Get template suffix
*
*
* @return string
*/
public function getSuffix()
{
return $this->suffix;
return $this->getResolver()->getSuffix();
}

/**
* Render a template using a view, and optionally a list of partials
*
*
* @todo should partials be passed here? or simply referenced?
* @param string $template Either a template string or a template file in the template path
* @param array|object $view An array or object with items to inject in the template
* @param array|object $partials A list of partial names/template pairs for rendering as partials
* @return string
* @throws InvalidPartialsException
* @throws Exception\InvalidPartialsException
*/
public function render($template, $view, $partials = null)
{
Expand Down Expand Up @@ -191,7 +201,7 @@ public function render($template, $view, $partials = null)

/**
* Tokenize a template
*
*
* @param string $template Either a template string or a reference to a template
* @return array Array of tokens
*/
Expand Down Expand Up @@ -222,7 +232,7 @@ public function tokenize($template)
* use with other instances, either in parallel or later.
*
* To seed an instance with these tokens, use {@link restoreTokens()}.
*
*
* @return array
*/
public function getAllTokens()
Expand All @@ -233,10 +243,10 @@ public function getAllTokens()
/**
* Restore or seed this instance's list of cached template tokens
*
* This list should be in the form of template name/token list pairs,
* ideally as received from {@link getAllTokens()}.
*
* @param array $tokens
* This list should be in the form of template name/token list pairs,
* ideally as received from {@link getAllTokens()}.
*
* @param array $tokens
* @return Mustache
*/
public function restoreTokens(array $tokens)
Expand All @@ -247,21 +257,21 @@ public function restoreTokens(array $tokens)

/**
* Locate and retrieve a template in the template path stack
*
* @param string $template
*
* @param string $template
* @return string
* @throws TemplateNotFoundException
* @throws Exception\TemplateNotFoundException
*/
protected function fetchTemplate($template)
{
foreach ($this->templatePath as $path) {
$file = $path . DIRECTORY_SEPARATOR . $template . $this->getSuffix();
if (file_exists($file)) {
$content = file_get_contents($file);
$this->cachedTemplates[$template] = $content;
return $content;
}
$resolver = $this->getResolver();
$file = $resolver->resolve($template);
if (!$file) {
throw new Exception\TemplateNotFoundException('Template by name "' . $template . '" not found');
}
throw new Exception\TemplateNotFoundException('Template by name "' . $template . '" not found');

$content = file_get_contents($file);
$this->cachedTemplates[$template] = $content;
return $content;
}
}
39 changes: 29 additions & 10 deletions library/Phly/Mustache/Resolver/DefaultResolver.php
Expand Up @@ -11,6 +11,7 @@
namespace Phly\Mustache\Resolver;

use Phly\Mustache\Exception;
use SplStack;

/**
* Default resolver implementation
Expand Down Expand Up @@ -105,7 +106,7 @@ public function setTemplatePath($templatePath)
}

$templatePath = rtrim((string) $templatePath, '/\\');
$this->templatePath = $templatePath;
$this->getTemplatePath()->push($templatePath);
return $this;
}

Expand All @@ -116,27 +117,45 @@ public function setTemplatePath($templatePath)
*/
public function getTemplatePath()
{
if (!$this->templatePath instanceof SplStack) {
$this->templatePath = new SplStack;
}
return $this->templatePath;
}

/**
* Clear/initialize the template path stack
*
* @return void
*/
public function clearTemplatePath()
{
$this->templatePath = new SplStack();
}

/**
* Resolve a template to its file
*
* @param string $template
* @return string
* @return false|string Returns false if unable to resolve the template to a path
*/
public function resolve($template)
{
$segments = explode($this->getSeparator(), $template);
$segments = explode($this->getSeparator(), $template);
$relativePath = implode(DIRECTORY_SEPARATOR, $segments)
. $this->getSuffix();

foreach ($this->getTemplatePath() as $path) {
if (!empty($path)) {
$path .= DIRECTORY_SEPARATOR;
}

$path = $this->getTemplatePath();
if (!empty($path)) {
$path .= DIRECTORY_SEPARATOR;
$filename = $path . $relativePath;
if (file_exists($filename)) {
return $filename;
}
}

$filename = $path
. implode(DIRECTORY_SEPARATOR, $segments)
. $this->getSuffix();
return $filename;
return false;
}
}

0 comments on commit 0590505

Please sign in to comment.