Resolvers are a feature specific to the phly-mustache
implementation. What a
resolver does is accept a template name, and return either the mustache content,
or a set of tokens that phly-mustache
understands.
All resolvers implement Phly\Mustache\Resolver\ResolverInterface
:
namespace Phly\Mustache\Resolver;
interface ResolverInterface
{
/**
* Resolve a template name
*
* Resolve a template name to mustache content or a set of tokens.
*
* @param string $template
* @return string|array
*/
public function resolve($template);
}
Phly\Mustache\Resolver\AggregateResolver
allows aggregating multiple
resolvers. When resolution is performed, the first resolver to return a
non-false response short-circuits execution, and its response is returned.
The AggregateResolver
is both countable and iterable, and exposes the
following methods:
attach(ResolverInterface $resolver, $priority = 1)
: attach a resolver to the aggregate.AggregateResolver
acts as a priority queue; large numbers have higher priority, lower numbers (including negative numbers!) have lower priority; resolvers registered at the same priority are executed in the order in which they are attached. Use$priority
to ensure execution order.hasType($type)
: query to see if a resolver of the given type is already registered in the aggregate.fetchByType($type)
: retrieve resolvers that match the given type. If only one matches, that instance will be returned; if multiple resolvers match, they will be returned as anAggregateResolver
.
The Mustache
instance composes an AggregateResolver
, which implements the
ResolverInterface
, and composes other resolvers implementing the interface.
You can attach a ResolverInterface
instance to it via the following code:
$mustache->getResolver()->attach($resolver);
At that point, that resolver will be added to the queue of resolvers. The first
one to return a string value will short-circuit execution; if all of them return
a boolean false
value, Mustache
will raise a TemplateNotFoundException
.
The AggregateResolver
allows you to access resolvers by class type (see above
for details), or you can push additional resolvers into the aggregate. Since the
AggregateResolver
implements a priority queue, by default resolvers will be
executed in the order registered. You can attach with higher priority if you
want your resolver to execute earlier.
Typically, you will instantiate and configure a new resolver, and attach it to
the AggregateResolver
.
Phly\Mustache\Resolver\DefaultResolver
. is a filesystem-based implementation,
and looks for a template within an internal stack of templates. If found, it
returns the content of that template.
It has three features you can manipulate:
- Filesystem directory separator, via
setSeparator()
. - File suffix, via
setSuffix()
. - Template path stack, via
addTemplatePath()
.
addTemplatePath()
accepts up to two arguments:
- The
$path
to add. - The
$namespace
under which to add the path; if none is provided, the default (fallback) namespace is assumed.
When rendering, and hence resolving, namespaces are denoted with the syntax
namespace::template
; if no nameespace::
segment is present, the default
namespace is assumed. Internally, when you attempt to resolve a template, the
DefaultResolver
will query first the stack of paths representing the
namespace, and then, if not found, the default (fallback) namespace. (In the
case that no namespace was provided, it queries only the default namespace.)
One interesting use case for manipulating the filesystem directory separator is to allow using "dot notation" for template names, and having each segment map to a directory:
use Phly\Mustache\Resolver\DefaultResolver;
$resolver = $mustache->getResolver()->getByType(DefaultResolver::class);
$resolver->setSeparator('.');
// Render foo/bar.mustache:
echo $mustache->render('foo.bar');
As the DefaultResolver
provides a reasonable default, what other uses exist
for resolvers? Potential reasons for alternate implementations include:
- Caching resolvers. A resolver could pull from the filesystem on first invocation, but then cache any compiled tokens when complete.
- Database-backed resolvers. Store templates in a relational or document database.
Basically, resolvers provide a convenient extension point for providing mustache template content and/or tokens to the system.