| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177 |
- <?php
- /*
- * This file is part of Mustache.php.
- *
- * (c) 2012 Justin Hileman
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
- /**
- * Abstract Mustache Template class.
- *
- * @abstract
- */
- abstract class Mustache_Template
- {
- /**
- * @var Mustache_Engine
- */
- protected $mustache;
- /**
- * @var boolean
- */
- protected $strictCallables = false;
- /**
- * Mustache Template constructor.
- *
- * @param Mustache_Engine $mustache
- */
- public function __construct(Mustache_Engine $mustache)
- {
- $this->mustache = $mustache;
- }
- /**
- * Mustache Template instances can be treated as a function and rendered by simply calling them:
- *
- * $m = new Mustache_Engine;
- * $tpl = $m->loadTemplate('Hello, {{ name }}!');
- * echo $tpl(array('name' => 'World')); // "Hello, World!"
- *
- * @see Mustache_Template::render
- *
- * @param mixed $context Array or object rendering context (default: array())
- *
- * @return string Rendered template
- */
- public function __invoke($context = array())
- {
- return $this->render($context);
- }
- /**
- * Render this template given the rendering context.
- *
- * @param mixed $context Array or object rendering context (default: array())
- *
- * @return string Rendered template
- */
- public function render($context = array())
- {
- return $this->renderInternal($this->prepareContextStack($context));
- }
- /**
- * Internal rendering method implemented by Mustache Template concrete subclasses.
- *
- * 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: '')
- *
- * @return string Rendered template
- */
- abstract public function renderInternal(Mustache_Context $context, $indent = '');
- /**
- * Tests whether a value should be iterated over (e.g. in a section context).
- *
- * In most languages there are two distinct array types: list and hash (or whatever you want to call them). Lists
- * should be iterated, hashes should be treated as objects. Mustache follows this paradigm for Ruby, Javascript,
- * Java, Python, etc.
- *
- * PHP, however, treats lists and hashes as one primitive type: array. So Mustache.php needs a way to distinguish
- * between between a list of things (numeric, normalized array) and a set of variables to be used as section context
- * (associative array). In other words, this will be iterated over:
- *
- * $items = array(
- * array('name' => 'foo'),
- * array('name' => 'bar'),
- * array('name' => 'baz'),
- * );
- *
- * ... but this will be used as a section context block:
- *
- * $items = array(
- * 1 => array('name' => 'foo'),
- * 'banana' => array('name' => 'bar'),
- * 42 => array('name' => 'baz'),
- * );
- *
- * @param mixed $value
- *
- * @return boolean True if the value is 'iterable'
- */
- protected function isIterable($value)
- {
- if (is_object($value)) {
- return $value instanceof Traversable;
- } elseif (is_array($value)) {
- $i = 0;
- foreach ($value as $k => $v) {
- if ($k !== $i++) {
- return false;
- }
- }
- return true;
- } else {
- return false;
- }
- }
- /**
- * Helper method to prepare the Context stack.
- *
- * Adds the Mustache HelperCollection to the stack's top context frame if helpers are present.
- *
- * @param mixed $context Optional first context frame (default: null)
- *
- * @return Mustache_Context
- */
- protected function prepareContextStack($context = null)
- {
- $stack = new Mustache_Context;
- $helpers = $this->mustache->getHelpers();
- if (!$helpers->isEmpty()) {
- $stack->push($helpers);
- }
- if (!empty($context)) {
- $stack->push($context);
- }
- 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 (($this->strictCallables ? is_object($value) : !is_string($value)) && is_callable($value)) {
- return $this->mustache
- ->loadLambda((string) call_user_func($value))
- ->renderInternal($context, $indent);
- }
- return $value;
- }
- }
|