xref: /template/strap/vendor/salesforce/handlebars-php/src/Handlebars/Handlebars.php (revision 04fd306c7c155fa133ebb3669986875d65988276)
1*04fd306cSNickeau<?php
2*04fd306cSNickeau/**
3*04fd306cSNickeau * Handlebars
4*04fd306cSNickeau *
5*04fd306cSNickeau * @category  Xamin
6*04fd306cSNickeau * @package   Handlebars
7*04fd306cSNickeau * @author    fzerorubigd <fzerorubigd@gmail.com>
8*04fd306cSNickeau * @author    Behrooz Shabani <everplays@gmail.com>
9*04fd306cSNickeau * @author    Mardix <https://github.com/mardix>
10*04fd306cSNickeau * @copyright 2012 (c) ParsPooyesh Co
11*04fd306cSNickeau * @copyright 2013 (c) Behrooz Shabani
12*04fd306cSNickeau * @copyright 2014 (c) Mardix
13*04fd306cSNickeau * @license   MIT
14*04fd306cSNickeau * @link      http://voodoophp.org/docs/handlebars
15*04fd306cSNickeau */
16*04fd306cSNickeau
17*04fd306cSNickeaunamespace Handlebars;
18*04fd306cSNickeauuse Handlebars\Loader\StringLoader;
19*04fd306cSNickeauuse Handlebars\Cache\Dummy;
20*04fd306cSNickeauuse InvalidArgumentException;
21*04fd306cSNickeau
22*04fd306cSNickeau
23*04fd306cSNickeauclass Handlebars
24*04fd306cSNickeau{
25*04fd306cSNickeau    private static $instance = null;
26*04fd306cSNickeau    const VERSION = '2.2';
27*04fd306cSNickeau
28*04fd306cSNickeau    const OPTION_ENABLE_DATA_VARIABLES = 'enableDataVariables';
29*04fd306cSNickeau
30*04fd306cSNickeau    /**
31*04fd306cSNickeau     * factory method
32*04fd306cSNickeau     *
33*04fd306cSNickeau     * @param array $options see __construct's options parameter
34*04fd306cSNickeau     *
35*04fd306cSNickeau     * @return Handlebars
36*04fd306cSNickeau     */
37*04fd306cSNickeau    public static function factory($options = array())
38*04fd306cSNickeau    {
39*04fd306cSNickeau        if (! self::$instance) {
40*04fd306cSNickeau            self::$instance = new self($options);
41*04fd306cSNickeau        }
42*04fd306cSNickeau
43*04fd306cSNickeau        return self::$instance;
44*04fd306cSNickeau    }
45*04fd306cSNickeau
46*04fd306cSNickeau    /**
47*04fd306cSNickeau     * @var Tokenizer
48*04fd306cSNickeau     */
49*04fd306cSNickeau    private $tokenizer;
50*04fd306cSNickeau
51*04fd306cSNickeau    /**
52*04fd306cSNickeau     * @var Parser
53*04fd306cSNickeau     */
54*04fd306cSNickeau    private $parser;
55*04fd306cSNickeau
56*04fd306cSNickeau    /**
57*04fd306cSNickeau     * @var Helpers
58*04fd306cSNickeau     */
59*04fd306cSNickeau    private $helpers;
60*04fd306cSNickeau
61*04fd306cSNickeau    /**
62*04fd306cSNickeau     * @var Loader
63*04fd306cSNickeau     */
64*04fd306cSNickeau    private $loader;
65*04fd306cSNickeau
66*04fd306cSNickeau    /**
67*04fd306cSNickeau     * @var Loader
68*04fd306cSNickeau     */
69*04fd306cSNickeau    private $partialsLoader;
70*04fd306cSNickeau
71*04fd306cSNickeau    /**
72*04fd306cSNickeau     * @var Cache
73*04fd306cSNickeau     */
74*04fd306cSNickeau    private $cache;
75*04fd306cSNickeau
76*04fd306cSNickeau    /**
77*04fd306cSNickeau     * @var callable escape function to use
78*04fd306cSNickeau     */
79*04fd306cSNickeau    private $escape = 'htmlspecialchars';
80*04fd306cSNickeau
81*04fd306cSNickeau    /**
82*04fd306cSNickeau     * @var array parametes to pass to escape function
83*04fd306cSNickeau     */
84*04fd306cSNickeau    private $escapeArgs = array(
85*04fd306cSNickeau        ENT_COMPAT,
86*04fd306cSNickeau        'UTF-8'
87*04fd306cSNickeau    );
88*04fd306cSNickeau
89*04fd306cSNickeau    private $aliases = array();
90*04fd306cSNickeau
91*04fd306cSNickeau    /**
92*04fd306cSNickeau     * @var bool Enable @data variables
93*04fd306cSNickeau     */
94*04fd306cSNickeau    private $enableDataVariables = false;
95*04fd306cSNickeau
96*04fd306cSNickeau    /**
97*04fd306cSNickeau     * Handlebars engine constructor
98*04fd306cSNickeau     * $options array can contain :
99*04fd306cSNickeau     * helpers        => Helpers object
100*04fd306cSNickeau     * escape         => a callable function to escape values
101*04fd306cSNickeau     * escapeArgs     => array to pass as extra parameter to escape function
102*04fd306cSNickeau     * loader         => Loader object
103*04fd306cSNickeau     * partials_loader => Loader object
104*04fd306cSNickeau     * cache          => Cache object
105*04fd306cSNickeau     * enableDataVariables => boolean. Enables @data variables (default: false)
106*04fd306cSNickeau     *
107*04fd306cSNickeau     * @param array $options array of options to set
108*04fd306cSNickeau     *
109*04fd306cSNickeau     * @throws \InvalidArgumentException
110*04fd306cSNickeau     */
111*04fd306cSNickeau    public function __construct(Array $options = [])
112*04fd306cSNickeau    {
113*04fd306cSNickeau        if (isset($options['helpers'])) {
114*04fd306cSNickeau            $this->setHelpers($options['helpers']);
115*04fd306cSNickeau        }
116*04fd306cSNickeau
117*04fd306cSNickeau        if (isset($options['loader'])) {
118*04fd306cSNickeau            $this->setLoader($options['loader']);
119*04fd306cSNickeau        }
120*04fd306cSNickeau
121*04fd306cSNickeau        if (isset($options['partials_loader'])) {
122*04fd306cSNickeau            $this->setPartialsLoader($options['partials_loader']);
123*04fd306cSNickeau        }
124*04fd306cSNickeau
125*04fd306cSNickeau        if (isset($options['cache'])) {
126*04fd306cSNickeau            $this->setCache($options['cache']);
127*04fd306cSNickeau        }
128*04fd306cSNickeau
129*04fd306cSNickeau        if (isset($options['escape'])) {
130*04fd306cSNickeau            if (!is_callable($options['escape'])) {
131*04fd306cSNickeau                throw new InvalidArgumentException(
132*04fd306cSNickeau                    'Handlebars Constructor "escape" option must be callable'
133*04fd306cSNickeau                );
134*04fd306cSNickeau            }
135*04fd306cSNickeau            $this->escape = $options['escape'];
136*04fd306cSNickeau        }
137*04fd306cSNickeau
138*04fd306cSNickeau        if (isset($options['escapeArgs'])) {
139*04fd306cSNickeau            if (!is_array($options['escapeArgs'])) {
140*04fd306cSNickeau                $options['escapeArgs'] = array($options['escapeArgs']);
141*04fd306cSNickeau            }
142*04fd306cSNickeau            $this->escapeArgs = $options['escapeArgs'];
143*04fd306cSNickeau        }
144*04fd306cSNickeau
145*04fd306cSNickeau        if (isset($options['partials_alias'])
146*04fd306cSNickeau            && is_array($options['partials_alias'])
147*04fd306cSNickeau        ) {
148*04fd306cSNickeau            $this->aliases = $options['partials_alias'];
149*04fd306cSNickeau        }
150*04fd306cSNickeau
151*04fd306cSNickeau        if (isset($options[self::OPTION_ENABLE_DATA_VARIABLES])) {
152*04fd306cSNickeau            if (!is_bool($options[self::OPTION_ENABLE_DATA_VARIABLES])) {
153*04fd306cSNickeau                throw new InvalidArgumentException(
154*04fd306cSNickeau                    'Handlebars Constructor "' . self::OPTION_ENABLE_DATA_VARIABLES . '" option must be a boolean'
155*04fd306cSNickeau                );
156*04fd306cSNickeau            }
157*04fd306cSNickeau            $this->enableDataVariables = $options[self::OPTION_ENABLE_DATA_VARIABLES];
158*04fd306cSNickeau        }
159*04fd306cSNickeau    }
160*04fd306cSNickeau
161*04fd306cSNickeau
162*04fd306cSNickeau
163*04fd306cSNickeau    /**
164*04fd306cSNickeau     * Shortcut 'render' invocation.
165*04fd306cSNickeau     *
166*04fd306cSNickeau     * Equivalent to calling `$handlebars->loadTemplate($template)->render($data);`
167*04fd306cSNickeau     *
168*04fd306cSNickeau     * @param string $template template name
169*04fd306cSNickeau     * @param mixed  $data     data to use as context
170*04fd306cSNickeau     * @return string Rendered template
171*04fd306cSNickeau     */
172*04fd306cSNickeau    public function render($template, $data)
173*04fd306cSNickeau    {
174*04fd306cSNickeau        return $this->loadTemplate($template)->render($data);
175*04fd306cSNickeau    }
176*04fd306cSNickeau    /**
177*04fd306cSNickeau     * To invoke when this object is called as a function
178*04fd306cSNickeau     *
179*04fd306cSNickeau     * @param string $template template name
180*04fd306cSNickeau     * @param mixed  $data     data to use as context
181*04fd306cSNickeau     * @return string Rendered template
182*04fd306cSNickeau     */
183*04fd306cSNickeau    public function __invoke($template, $data)
184*04fd306cSNickeau    {
185*04fd306cSNickeau        return $this->render($template, $data);
186*04fd306cSNickeau    }
187*04fd306cSNickeau
188*04fd306cSNickeau    /**
189*04fd306cSNickeau     * Set helpers for current enfine
190*04fd306cSNickeau     *
191*04fd306cSNickeau     * @param Helpers $helpers handlebars helper
192*04fd306cSNickeau     *
193*04fd306cSNickeau     * @return void
194*04fd306cSNickeau     */
195*04fd306cSNickeau    public function setHelpers(Helpers $helpers)
196*04fd306cSNickeau    {
197*04fd306cSNickeau        $this->helpers = $helpers;
198*04fd306cSNickeau    }
199*04fd306cSNickeau
200*04fd306cSNickeau    /**
201*04fd306cSNickeau     * Get helpers, or create new one if ther is no helper
202*04fd306cSNickeau     *
203*04fd306cSNickeau     * @return Helpers
204*04fd306cSNickeau     */
205*04fd306cSNickeau    public function getHelpers()
206*04fd306cSNickeau    {
207*04fd306cSNickeau        if (!isset($this->helpers)) {
208*04fd306cSNickeau            $this->helpers = new Helpers();
209*04fd306cSNickeau        }
210*04fd306cSNickeau        return $this->helpers;
211*04fd306cSNickeau    }
212*04fd306cSNickeau
213*04fd306cSNickeau    /**
214*04fd306cSNickeau     * Add a new helper.
215*04fd306cSNickeau     *
216*04fd306cSNickeau     * @param string $name   helper name
217*04fd306cSNickeau     * @param mixed  $helper helper callable
218*04fd306cSNickeau     *
219*04fd306cSNickeau     * @return void
220*04fd306cSNickeau     */
221*04fd306cSNickeau    public function addHelper($name, $helper)
222*04fd306cSNickeau    {
223*04fd306cSNickeau        $this->getHelpers()->add($name, $helper);
224*04fd306cSNickeau    }
225*04fd306cSNickeau
226*04fd306cSNickeau    /**
227*04fd306cSNickeau     * Get a helper by name.
228*04fd306cSNickeau     *
229*04fd306cSNickeau     * @param string $name helper name
230*04fd306cSNickeau     * @return callable Helper
231*04fd306cSNickeau     */
232*04fd306cSNickeau    public function getHelper($name)
233*04fd306cSNickeau    {
234*04fd306cSNickeau        return $this->getHelpers()->__get($name);
235*04fd306cSNickeau    }
236*04fd306cSNickeau
237*04fd306cSNickeau    /**
238*04fd306cSNickeau     * Check whether this instance has a helper.
239*04fd306cSNickeau     *
240*04fd306cSNickeau     * @param string $name helper name
241*04fd306cSNickeau     * @return boolean True if the helper is present
242*04fd306cSNickeau     */
243*04fd306cSNickeau    public function hasHelper($name)
244*04fd306cSNickeau    {
245*04fd306cSNickeau        return $this->getHelpers()->has($name);
246*04fd306cSNickeau    }
247*04fd306cSNickeau
248*04fd306cSNickeau    /**
249*04fd306cSNickeau     * Remove a helper by name.
250*04fd306cSNickeau     *
251*04fd306cSNickeau     * @param string $name helper name
252*04fd306cSNickeau     * @return void
253*04fd306cSNickeau     */
254*04fd306cSNickeau    public function removeHelper($name)
255*04fd306cSNickeau    {
256*04fd306cSNickeau        $this->getHelpers()->remove($name);
257*04fd306cSNickeau    }
258*04fd306cSNickeau
259*04fd306cSNickeau    /**
260*04fd306cSNickeau     * Set current loader
261*04fd306cSNickeau     *
262*04fd306cSNickeau     * @param Loader $loader handlebars loader
263*04fd306cSNickeau     * @return void
264*04fd306cSNickeau     */
265*04fd306cSNickeau    public function setLoader(Loader $loader)
266*04fd306cSNickeau    {
267*04fd306cSNickeau        $this->loader = $loader;
268*04fd306cSNickeau    }
269*04fd306cSNickeau
270*04fd306cSNickeau    /**
271*04fd306cSNickeau     * get current loader
272*04fd306cSNickeau     *
273*04fd306cSNickeau     * @return Loader
274*04fd306cSNickeau     */
275*04fd306cSNickeau    public function getLoader()
276*04fd306cSNickeau    {
277*04fd306cSNickeau        if (! isset($this->loader)) {
278*04fd306cSNickeau            $this->loader = new StringLoader();
279*04fd306cSNickeau        }
280*04fd306cSNickeau        return $this->loader;
281*04fd306cSNickeau    }
282*04fd306cSNickeau
283*04fd306cSNickeau    /**
284*04fd306cSNickeau     * Set current partials loader
285*04fd306cSNickeau     *
286*04fd306cSNickeau     * @param Loader $loader handlebars loader
287*04fd306cSNickeau     * @return void
288*04fd306cSNickeau     */
289*04fd306cSNickeau    public function setPartialsLoader(Loader $loader)
290*04fd306cSNickeau    {
291*04fd306cSNickeau        $this->partialsLoader = $loader;
292*04fd306cSNickeau    }
293*04fd306cSNickeau
294*04fd306cSNickeau    /**
295*04fd306cSNickeau     * get current partials loader
296*04fd306cSNickeau     *
297*04fd306cSNickeau     * @return Loader
298*04fd306cSNickeau     */
299*04fd306cSNickeau    public function getPartialsLoader()
300*04fd306cSNickeau    {
301*04fd306cSNickeau        if (!isset($this->partialsLoader)) {
302*04fd306cSNickeau            $this->partialsLoader = new StringLoader();
303*04fd306cSNickeau        }
304*04fd306cSNickeau        return $this->partialsLoader;
305*04fd306cSNickeau    }
306*04fd306cSNickeau
307*04fd306cSNickeau    /**
308*04fd306cSNickeau     * Set cache  for current engine
309*04fd306cSNickeau     *
310*04fd306cSNickeau     * @param Cache $cache handlebars cache
311*04fd306cSNickeau     * @return void
312*04fd306cSNickeau     */
313*04fd306cSNickeau    public function setCache(Cache $cache)
314*04fd306cSNickeau    {
315*04fd306cSNickeau        $this->cache = $cache;
316*04fd306cSNickeau    }
317*04fd306cSNickeau
318*04fd306cSNickeau    /**
319*04fd306cSNickeau     * Get cache
320*04fd306cSNickeau     *
321*04fd306cSNickeau     * @return Cache
322*04fd306cSNickeau     */
323*04fd306cSNickeau    public function getCache()
324*04fd306cSNickeau    {
325*04fd306cSNickeau        if (!isset($this->cache)) {
326*04fd306cSNickeau            $this->cache = new Dummy();
327*04fd306cSNickeau        }
328*04fd306cSNickeau        return $this->cache;
329*04fd306cSNickeau    }
330*04fd306cSNickeau
331*04fd306cSNickeau    /**
332*04fd306cSNickeau     * Get current escape function
333*04fd306cSNickeau     *
334*04fd306cSNickeau     * @return callable
335*04fd306cSNickeau     */
336*04fd306cSNickeau    public function getEscape()
337*04fd306cSNickeau    {
338*04fd306cSNickeau        return $this->escape;
339*04fd306cSNickeau    }
340*04fd306cSNickeau
341*04fd306cSNickeau    /**
342*04fd306cSNickeau     * Set current escape function
343*04fd306cSNickeau     *
344*04fd306cSNickeau     * @param callable $escape function
345*04fd306cSNickeau     * @throws \InvalidArgumentException
346*04fd306cSNickeau     * @return void
347*04fd306cSNickeau     */
348*04fd306cSNickeau    public function setEscape($escape)
349*04fd306cSNickeau    {
350*04fd306cSNickeau        if (!is_callable($escape)) {
351*04fd306cSNickeau            throw new InvalidArgumentException(
352*04fd306cSNickeau                'Escape function must be a callable'
353*04fd306cSNickeau            );
354*04fd306cSNickeau        }
355*04fd306cSNickeau        $this->escape = $escape;
356*04fd306cSNickeau    }
357*04fd306cSNickeau
358*04fd306cSNickeau    /**
359*04fd306cSNickeau     * Get current escape function
360*04fd306cSNickeau     *
361*04fd306cSNickeau     * @return array
362*04fd306cSNickeau     */
363*04fd306cSNickeau    public function getEscapeArgs()
364*04fd306cSNickeau    {
365*04fd306cSNickeau        return $this->escapeArgs;
366*04fd306cSNickeau    }
367*04fd306cSNickeau
368*04fd306cSNickeau    /**
369*04fd306cSNickeau     * Set current escape function
370*04fd306cSNickeau     *
371*04fd306cSNickeau     * @param array $escapeArgs arguments to pass as extra arg to function
372*04fd306cSNickeau     * @return void
373*04fd306cSNickeau     */
374*04fd306cSNickeau    public function setEscapeArgs($escapeArgs)
375*04fd306cSNickeau    {
376*04fd306cSNickeau        if (! is_array($escapeArgs)) {
377*04fd306cSNickeau            $escapeArgs = array($escapeArgs);
378*04fd306cSNickeau        }
379*04fd306cSNickeau        $this->escapeArgs = $escapeArgs;
380*04fd306cSNickeau    }
381*04fd306cSNickeau
382*04fd306cSNickeau
383*04fd306cSNickeau    /**
384*04fd306cSNickeau     * Set the Handlebars Tokenizer instance.
385*04fd306cSNickeau     *
386*04fd306cSNickeau     * @param Tokenizer $tokenizer tokenizer
387*04fd306cSNickeau     * @return void
388*04fd306cSNickeau     */
389*04fd306cSNickeau    public function setTokenizer(Tokenizer $tokenizer)
390*04fd306cSNickeau    {
391*04fd306cSNickeau        $this->tokenizer = $tokenizer;
392*04fd306cSNickeau    }
393*04fd306cSNickeau
394*04fd306cSNickeau    /**
395*04fd306cSNickeau     * Get the current Handlebars Tokenizer instance.
396*04fd306cSNickeau     *
397*04fd306cSNickeau     * If no Tokenizer instance has been explicitly specified, this method will
398*04fd306cSNickeau     * instantiate and return a new one.
399*04fd306cSNickeau     *
400*04fd306cSNickeau     * @return Tokenizer
401*04fd306cSNickeau     */
402*04fd306cSNickeau    public function getTokenizer()
403*04fd306cSNickeau    {
404*04fd306cSNickeau        if (! isset($this->tokenizer)) {
405*04fd306cSNickeau            $this->tokenizer = new Tokenizer();
406*04fd306cSNickeau        }
407*04fd306cSNickeau
408*04fd306cSNickeau        return $this->tokenizer;
409*04fd306cSNickeau    }
410*04fd306cSNickeau
411*04fd306cSNickeau    /**
412*04fd306cSNickeau     * Set the Handlebars Parser instance.
413*04fd306cSNickeau     *
414*04fd306cSNickeau     * @param Parser $parser parser object
415*04fd306cSNickeau     * @return void
416*04fd306cSNickeau     */
417*04fd306cSNickeau    public function setParser(Parser $parser)
418*04fd306cSNickeau    {
419*04fd306cSNickeau        $this->parser = $parser;
420*04fd306cSNickeau    }
421*04fd306cSNickeau
422*04fd306cSNickeau    /**
423*04fd306cSNickeau     * Get the current Handlebars Parser instance.
424*04fd306cSNickeau     *
425*04fd306cSNickeau     * If no Parser instance has been explicitly specified, this method will
426*04fd306cSNickeau     * instantiate and return a new one.
427*04fd306cSNickeau     *
428*04fd306cSNickeau     * @return Parser
429*04fd306cSNickeau     */
430*04fd306cSNickeau    public function getParser()
431*04fd306cSNickeau    {
432*04fd306cSNickeau        if (! isset($this->parser)) {
433*04fd306cSNickeau            $this->parser = new Parser();
434*04fd306cSNickeau        }
435*04fd306cSNickeau        return $this->parser;
436*04fd306cSNickeau    }
437*04fd306cSNickeau
438*04fd306cSNickeau    /**
439*04fd306cSNickeau     * Determines if the @data variables are enabled.
440*04fd306cSNickeau     * @return bool
441*04fd306cSNickeau     */
442*04fd306cSNickeau    public function isDataVariablesEnabled()
443*04fd306cSNickeau    {
444*04fd306cSNickeau        return $this->enableDataVariables;
445*04fd306cSNickeau    }
446*04fd306cSNickeau
447*04fd306cSNickeau    /**
448*04fd306cSNickeau     * Load a template by name with current template loader
449*04fd306cSNickeau     *
450*04fd306cSNickeau     * @param string $name template name
451*04fd306cSNickeau     *
452*04fd306cSNickeau     * @return Template
453*04fd306cSNickeau     */
454*04fd306cSNickeau    public function loadTemplate($name)
455*04fd306cSNickeau    {
456*04fd306cSNickeau        $source = $this->getLoader()->load($name);
457*04fd306cSNickeau        $tree = $this->tokenize($source);
458*04fd306cSNickeau        return new Template($this, $tree, $source);
459*04fd306cSNickeau    }
460*04fd306cSNickeau
461*04fd306cSNickeau    /**
462*04fd306cSNickeau     * Load a partial by name with current partial loader
463*04fd306cSNickeau     *
464*04fd306cSNickeau     * @param string $name partial name
465*04fd306cSNickeau     *
466*04fd306cSNickeau     * @return Template
467*04fd306cSNickeau     */
468*04fd306cSNickeau    public function loadPartial($name)
469*04fd306cSNickeau    {
470*04fd306cSNickeau        if (isset($this->aliases[$name])) {
471*04fd306cSNickeau            $name = $this->aliases[$name];
472*04fd306cSNickeau        }
473*04fd306cSNickeau        $source = $this->getPartialsLoader()->load($name);
474*04fd306cSNickeau        $tree = $this->tokenize($source);
475*04fd306cSNickeau        return new Template($this, $tree, $source);
476*04fd306cSNickeau    }
477*04fd306cSNickeau
478*04fd306cSNickeau    /**
479*04fd306cSNickeau     * Register partial alias
480*04fd306cSNickeau     *
481*04fd306cSNickeau     * @param string $alias   Partial alias
482*04fd306cSNickeau     * @param string $content The real value
483*04fd306cSNickeau     * @return void
484*04fd306cSNickeau     */
485*04fd306cSNickeau    public function registerPartial($alias, $content)
486*04fd306cSNickeau    {
487*04fd306cSNickeau        $this->aliases[$alias] = $content;
488*04fd306cSNickeau    }
489*04fd306cSNickeau
490*04fd306cSNickeau    /**
491*04fd306cSNickeau     * Un-register partial alias
492*04fd306cSNickeau     *
493*04fd306cSNickeau     * @param string $alias Partial alias
494*04fd306cSNickeau     * @return void
495*04fd306cSNickeau     */
496*04fd306cSNickeau    public function unRegisterPartial($alias)
497*04fd306cSNickeau    {
498*04fd306cSNickeau        if (isset($this->aliases[$alias])) {
499*04fd306cSNickeau            unset($this->aliases[$alias]);
500*04fd306cSNickeau        }
501*04fd306cSNickeau    }
502*04fd306cSNickeau
503*04fd306cSNickeau    /**
504*04fd306cSNickeau     * Load string into a template object
505*04fd306cSNickeau     *
506*04fd306cSNickeau     * @param string $source string to load
507*04fd306cSNickeau     * @return Template
508*04fd306cSNickeau     */
509*04fd306cSNickeau    public function loadString($source)
510*04fd306cSNickeau    {
511*04fd306cSNickeau        $tree = $this->tokenize($source);
512*04fd306cSNickeau        return new Template($this, $tree, $source);
513*04fd306cSNickeau    }
514*04fd306cSNickeau
515*04fd306cSNickeau    /**
516*04fd306cSNickeau     * try to tokenize source, or get them from cache if available
517*04fd306cSNickeau     *
518*04fd306cSNickeau     * @param string $source handlebars source code
519*04fd306cSNickeau     * @return array handlebars parsed data into array
520*04fd306cSNickeau     */
521*04fd306cSNickeau    private function tokenize($source)
522*04fd306cSNickeau    {
523*04fd306cSNickeau        $hash = md5(sprintf('version: %s, data : %s', self::VERSION, $source));
524*04fd306cSNickeau        $tree = $this->getCache()->get($hash);
525*04fd306cSNickeau        if ($tree === false) {
526*04fd306cSNickeau            $tokens = $this->getTokenizer()->scan($source);
527*04fd306cSNickeau            $tree = $this->getParser()->parse($tokens);
528*04fd306cSNickeau            $this->getCache()->set($hash, $tree);
529*04fd306cSNickeau        }
530*04fd306cSNickeau        return $tree;
531*04fd306cSNickeau    }
532*04fd306cSNickeau
533*04fd306cSNickeau}