Engine.php 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787
  1. <?php
  2. /*
  3. * This file is part of Mustache.php.
  4. *
  5. * (c) 2010-2015 Justin Hileman
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. /**
  11. * A Mustache implementation in PHP.
  12. *
  13. * {@link http://defunkt.github.com/mustache}
  14. *
  15. * Mustache is a framework-agnostic logic-less templating language. It enforces separation of view
  16. * logic from template files. In fact, it is not even possible to embed logic in the template.
  17. *
  18. * This is very, very rad.
  19. *
  20. * @author Justin Hileman {@link http://justinhileman.com}
  21. */
  22. class Mustache_Engine
  23. {
  24. const VERSION = '2.9.0';
  25. const SPEC_VERSION = '1.1.2';
  26. const PRAGMA_FILTERS = 'FILTERS';
  27. const PRAGMA_BLOCKS = 'BLOCKS';
  28. const PRAGMA_ANCHORED_DOT = 'ANCHORED-DOT';
  29. // Known pragmas
  30. private static $knownPragmas = array(
  31. self::PRAGMA_FILTERS => true,
  32. self::PRAGMA_BLOCKS => true,
  33. self::PRAGMA_ANCHORED_DOT => true,
  34. );
  35. // Template cache
  36. private $templates = array();
  37. // Environment
  38. private $templateClassPrefix = '__Mustache_';
  39. private $cache;
  40. private $lambdaCache;
  41. private $cacheLambdaTemplates = false;
  42. private $loader;
  43. private $partialsLoader;
  44. private $helpers;
  45. private $escape;
  46. private $entityFlags = ENT_COMPAT;
  47. private $charset = 'UTF-8';
  48. private $logger;
  49. private $strictCallables = false;
  50. private $pragmas = array();
  51. // Services
  52. private $tokenizer;
  53. private $parser;
  54. private $compiler;
  55. /**
  56. * Mustache class constructor.
  57. *
  58. * Passing an $options array allows overriding certain Mustache options during instantiation:
  59. *
  60. * $options = array(
  61. * // The class prefix for compiled templates. Defaults to '__Mustache_'.
  62. * 'template_class_prefix' => '__MyTemplates_',
  63. *
  64. * // A Mustache cache instance or a cache directory string for compiled templates.
  65. * // Mustache will not cache templates unless this is set.
  66. * 'cache' => dirname(__FILE__).'/tmp/cache/mustache',
  67. *
  68. * // Override default permissions for cache files. Defaults to using the system-defined umask. It is
  69. * // *strongly* recommended that you configure your umask properly rather than overriding permissions here.
  70. * 'cache_file_mode' => 0666,
  71. *
  72. * // Optionally, enable caching for lambda section templates. This is generally not recommended, as lambda
  73. * // sections are often too dynamic to benefit from caching.
  74. * 'cache_lambda_templates' => true,
  75. *
  76. * // A Mustache template loader instance. Uses a StringLoader if not specified.
  77. * 'loader' => new Mustache_Loader_FilesystemLoader(dirname(__FILE__).'/views'),
  78. *
  79. * // A Mustache loader instance for partials.
  80. * 'partials_loader' => new Mustache_Loader_FilesystemLoader(dirname(__FILE__).'/views/partials'),
  81. *
  82. * // An array of Mustache partials. Useful for quick-and-dirty string template loading, but not as
  83. * // efficient or lazy as a Filesystem (or database) loader.
  84. * 'partials' => array('foo' => file_get_contents(dirname(__FILE__).'/views/partials/foo.mustache')),
  85. *
  86. * // An array of 'helpers'. Helpers can be global variables or objects, closures (e.g. for higher order
  87. * // sections), or any other valid Mustache context value. They will be prepended to the context stack,
  88. * // so they will be available in any template loaded by this Mustache instance.
  89. * 'helpers' => array('i18n' => function ($text) {
  90. * // do something translatey here...
  91. * }),
  92. *
  93. * // An 'escape' callback, responsible for escaping double-mustache variables.
  94. * 'escape' => function ($value) {
  95. * return htmlspecialchars($buffer, ENT_COMPAT, 'UTF-8');
  96. * },
  97. *
  98. * // Type argument for `htmlspecialchars`. Defaults to ENT_COMPAT. You may prefer ENT_QUOTES.
  99. * 'entity_flags' => ENT_QUOTES,
  100. *
  101. * // Character set for `htmlspecialchars`. Defaults to 'UTF-8'. Use 'UTF-8'.
  102. * 'charset' => 'ISO-8859-1',
  103. *
  104. * // A Mustache Logger instance. No logging will occur unless this is set. Using a PSR-3 compatible
  105. * // logging library -- such as Monolog -- is highly recommended. A simple stream logger implementation is
  106. * // available as well:
  107. * 'logger' => new Mustache_Logger_StreamLogger('php://stderr'),
  108. *
  109. * // Only treat Closure instances and invokable classes as callable. If true, values like
  110. * // `array('ClassName', 'methodName')` and `array($classInstance, 'methodName')`, which are traditionally
  111. * // "callable" in PHP, are not called to resolve variables for interpolation or section contexts. This
  112. * // helps protect against arbitrary code execution when user input is passed directly into the template.
  113. * // This currently defaults to false, but will default to true in v3.0.
  114. * 'strict_callables' => true,
  115. *
  116. * // Enable pragmas across all templates, regardless of the presence of pragma tags in the individual
  117. * // templates.
  118. * 'pragmas' => [Mustache_Engine::PRAGMA_FILTERS],
  119. * );
  120. *
  121. * @throws Mustache_Exception_InvalidArgumentException If `escape` option is not callable.
  122. *
  123. * @param array $options (default: array())
  124. */
  125. public function __construct(array $options = array())
  126. {
  127. if (isset($options['template_class_prefix'])) {
  128. $this->templateClassPrefix = $options['template_class_prefix'];
  129. }
  130. if (isset($options['cache'])) {
  131. $cache = $options['cache'];
  132. if (is_string($cache)) {
  133. $mode = isset($options['cache_file_mode']) ? $options['cache_file_mode'] : null;
  134. $cache = new Mustache_Cache_FilesystemCache($cache, $mode);
  135. }
  136. $this->setCache($cache);
  137. }
  138. if (isset($options['cache_lambda_templates'])) {
  139. $this->cacheLambdaTemplates = (bool) $options['cache_lambda_templates'];
  140. }
  141. if (isset($options['loader'])) {
  142. $this->setLoader($options['loader']);
  143. }
  144. if (isset($options['partials_loader'])) {
  145. $this->setPartialsLoader($options['partials_loader']);
  146. }
  147. if (isset($options['partials'])) {
  148. $this->setPartials($options['partials']);
  149. }
  150. if (isset($options['helpers'])) {
  151. $this->setHelpers($options['helpers']);
  152. }
  153. if (isset($options['escape'])) {
  154. if (!is_callable($options['escape'])) {
  155. throw new Mustache_Exception_InvalidArgumentException('Mustache Constructor "escape" option must be callable');
  156. }
  157. $this->escape = $options['escape'];
  158. }
  159. if (isset($options['entity_flags'])) {
  160. $this->entityFlags = $options['entity_flags'];
  161. }
  162. if (isset($options['charset'])) {
  163. $this->charset = $options['charset'];
  164. }
  165. if (isset($options['logger'])) {
  166. $this->setLogger($options['logger']);
  167. }
  168. if (isset($options['strict_callables'])) {
  169. $this->strictCallables = $options['strict_callables'];
  170. }
  171. if (isset($options['pragmas'])) {
  172. foreach ($options['pragmas'] as $pragma) {
  173. if (!isset(self::$knownPragmas[$pragma])) {
  174. throw new Mustache_Exception_InvalidArgumentException(sprintf('Unknown pragma: "%s".', $pragma));
  175. }
  176. $this->pragmas[$pragma] = true;
  177. }
  178. }
  179. }
  180. /**
  181. * Shortcut 'render' invocation.
  182. *
  183. * Equivalent to calling `$mustache->loadTemplate($template)->render($context);`
  184. *
  185. * @see Mustache_Engine::loadTemplate
  186. * @see Mustache_Template::render
  187. *
  188. * @param string $template
  189. * @param mixed $context (default: array())
  190. *
  191. * @return string Rendered template
  192. */
  193. public function render($template, $context = array())
  194. {
  195. return $this->loadTemplate($template)->render($context);
  196. }
  197. /**
  198. * Get the current Mustache escape callback.
  199. *
  200. * @return callable|null
  201. */
  202. public function getEscape()
  203. {
  204. return $this->escape;
  205. }
  206. /**
  207. * Get the current Mustache entitity type to escape.
  208. *
  209. * @return int
  210. */
  211. public function getEntityFlags()
  212. {
  213. return $this->entityFlags;
  214. }
  215. /**
  216. * Get the current Mustache character set.
  217. *
  218. * @return string
  219. */
  220. public function getCharset()
  221. {
  222. return $this->charset;
  223. }
  224. /**
  225. * Get the current globally enabled pragmas.
  226. *
  227. * @return array
  228. */
  229. public function getPragmas()
  230. {
  231. return array_keys($this->pragmas);
  232. }
  233. /**
  234. * Set the Mustache template Loader instance.
  235. *
  236. * @param Mustache_Loader $loader
  237. */
  238. public function setLoader(Mustache_Loader $loader)
  239. {
  240. $this->loader = $loader;
  241. }
  242. /**
  243. * Get the current Mustache template Loader instance.
  244. *
  245. * If no Loader instance has been explicitly specified, this method will instantiate and return
  246. * a StringLoader instance.
  247. *
  248. * @return Mustache_Loader
  249. */
  250. public function getLoader()
  251. {
  252. if (!isset($this->loader)) {
  253. $this->loader = new Mustache_Loader_StringLoader();
  254. }
  255. return $this->loader;
  256. }
  257. /**
  258. * Set the Mustache partials Loader instance.
  259. *
  260. * @param Mustache_Loader $partialsLoader
  261. */
  262. public function setPartialsLoader(Mustache_Loader $partialsLoader)
  263. {
  264. $this->partialsLoader = $partialsLoader;
  265. }
  266. /**
  267. * Get the current Mustache partials Loader instance.
  268. *
  269. * If no Loader instance has been explicitly specified, this method will instantiate and return
  270. * an ArrayLoader instance.
  271. *
  272. * @return Mustache_Loader
  273. */
  274. public function getPartialsLoader()
  275. {
  276. if (!isset($this->partialsLoader)) {
  277. $this->partialsLoader = new Mustache_Loader_ArrayLoader();
  278. }
  279. return $this->partialsLoader;
  280. }
  281. /**
  282. * Set partials for the current partials Loader instance.
  283. *
  284. * @throws Mustache_Exception_RuntimeException If the current Loader instance is immutable
  285. *
  286. * @param array $partials (default: array())
  287. */
  288. public function setPartials(array $partials = array())
  289. {
  290. if (!isset($this->partialsLoader)) {
  291. $this->partialsLoader = new Mustache_Loader_ArrayLoader();
  292. }
  293. if (!$this->partialsLoader instanceof Mustache_Loader_MutableLoader) {
  294. throw new Mustache_Exception_RuntimeException('Unable to set partials on an immutable Mustache Loader instance');
  295. }
  296. $this->partialsLoader->setTemplates($partials);
  297. }
  298. /**
  299. * Set an array of Mustache helpers.
  300. *
  301. * An array of 'helpers'. Helpers can be global variables or objects, closures (e.g. for higher order sections), or
  302. * any other valid Mustache context value. They will be prepended to the context stack, so they will be available in
  303. * any template loaded by this Mustache instance.
  304. *
  305. * @throws Mustache_Exception_InvalidArgumentException if $helpers is not an array or Traversable
  306. *
  307. * @param array|Traversable $helpers
  308. */
  309. public function setHelpers($helpers)
  310. {
  311. if (!is_array($helpers) && !$helpers instanceof Traversable) {
  312. throw new Mustache_Exception_InvalidArgumentException('setHelpers expects an array of helpers');
  313. }
  314. $this->getHelpers()->clear();
  315. foreach ($helpers as $name => $helper) {
  316. $this->addHelper($name, $helper);
  317. }
  318. }
  319. /**
  320. * Get the current set of Mustache helpers.
  321. *
  322. * @see Mustache_Engine::setHelpers
  323. *
  324. * @return Mustache_HelperCollection
  325. */
  326. public function getHelpers()
  327. {
  328. if (!isset($this->helpers)) {
  329. $this->helpers = new Mustache_HelperCollection();
  330. }
  331. return $this->helpers;
  332. }
  333. /**
  334. * Add a new Mustache helper.
  335. *
  336. * @see Mustache_Engine::setHelpers
  337. *
  338. * @param string $name
  339. * @param mixed $helper
  340. */
  341. public function addHelper($name, $helper)
  342. {
  343. $this->getHelpers()->add($name, $helper);
  344. }
  345. /**
  346. * Get a Mustache helper by name.
  347. *
  348. * @see Mustache_Engine::setHelpers
  349. *
  350. * @param string $name
  351. *
  352. * @return mixed Helper
  353. */
  354. public function getHelper($name)
  355. {
  356. return $this->getHelpers()->get($name);
  357. }
  358. /**
  359. * Check whether this Mustache instance has a helper.
  360. *
  361. * @see Mustache_Engine::setHelpers
  362. *
  363. * @param string $name
  364. *
  365. * @return bool True if the helper is present
  366. */
  367. public function hasHelper($name)
  368. {
  369. return $this->getHelpers()->has($name);
  370. }
  371. /**
  372. * Remove a helper by name.
  373. *
  374. * @see Mustache_Engine::setHelpers
  375. *
  376. * @param string $name
  377. */
  378. public function removeHelper($name)
  379. {
  380. $this->getHelpers()->remove($name);
  381. }
  382. /**
  383. * Set the Mustache Logger instance.
  384. *
  385. * @throws Mustache_Exception_InvalidArgumentException If logger is not an instance of Mustache_Logger or Psr\Log\LoggerInterface.
  386. *
  387. * @param Mustache_Logger|Psr\Log\LoggerInterface $logger
  388. */
  389. public function setLogger($logger = null)
  390. {
  391. if ($logger !== null && !($logger instanceof Mustache_Logger || is_a($logger, 'Psr\\Log\\LoggerInterface'))) {
  392. throw new Mustache_Exception_InvalidArgumentException('Expected an instance of Mustache_Logger or Psr\\Log\\LoggerInterface.');
  393. }
  394. if ($this->getCache()->getLogger() === null) {
  395. $this->getCache()->setLogger($logger);
  396. }
  397. $this->logger = $logger;
  398. }
  399. /**
  400. * Get the current Mustache Logger instance.
  401. *
  402. * @return Mustache_Logger|Psr\Log\LoggerInterface
  403. */
  404. public function getLogger()
  405. {
  406. return $this->logger;
  407. }
  408. /**
  409. * Set the Mustache Tokenizer instance.
  410. *
  411. * @param Mustache_Tokenizer $tokenizer
  412. */
  413. public function setTokenizer(Mustache_Tokenizer $tokenizer)
  414. {
  415. $this->tokenizer = $tokenizer;
  416. }
  417. /**
  418. * Get the current Mustache Tokenizer instance.
  419. *
  420. * If no Tokenizer instance has been explicitly specified, this method will instantiate and return a new one.
  421. *
  422. * @return Mustache_Tokenizer
  423. */
  424. public function getTokenizer()
  425. {
  426. if (!isset($this->tokenizer)) {
  427. $this->tokenizer = new Mustache_Tokenizer();
  428. }
  429. return $this->tokenizer;
  430. }
  431. /**
  432. * Set the Mustache Parser instance.
  433. *
  434. * @param Mustache_Parser $parser
  435. */
  436. public function setParser(Mustache_Parser $parser)
  437. {
  438. $this->parser = $parser;
  439. }
  440. /**
  441. * Get the current Mustache Parser instance.
  442. *
  443. * If no Parser instance has been explicitly specified, this method will instantiate and return a new one.
  444. *
  445. * @return Mustache_Parser
  446. */
  447. public function getParser()
  448. {
  449. if (!isset($this->parser)) {
  450. $this->parser = new Mustache_Parser();
  451. }
  452. return $this->parser;
  453. }
  454. /**
  455. * Set the Mustache Compiler instance.
  456. *
  457. * @param Mustache_Compiler $compiler
  458. */
  459. public function setCompiler(Mustache_Compiler $compiler)
  460. {
  461. $this->compiler = $compiler;
  462. }
  463. /**
  464. * Get the current Mustache Compiler instance.
  465. *
  466. * If no Compiler instance has been explicitly specified, this method will instantiate and return a new one.
  467. *
  468. * @return Mustache_Compiler
  469. */
  470. public function getCompiler()
  471. {
  472. if (!isset($this->compiler)) {
  473. $this->compiler = new Mustache_Compiler();
  474. }
  475. return $this->compiler;
  476. }
  477. /**
  478. * Set the Mustache Cache instance.
  479. *
  480. * @param Mustache_Cache $cache
  481. */
  482. public function setCache(Mustache_Cache $cache)
  483. {
  484. if (isset($this->logger) && $cache->getLogger() === null) {
  485. $cache->setLogger($this->getLogger());
  486. }
  487. $this->cache = $cache;
  488. }
  489. /**
  490. * Get the current Mustache Cache instance.
  491. *
  492. * If no Cache instance has been explicitly specified, this method will instantiate and return a new one.
  493. *
  494. * @return Mustache_Cache
  495. */
  496. public function getCache()
  497. {
  498. if (!isset($this->cache)) {
  499. $this->setCache(new Mustache_Cache_NoopCache());
  500. }
  501. return $this->cache;
  502. }
  503. /**
  504. * Get the current Lambda Cache instance.
  505. *
  506. * If 'cache_lambda_templates' is enabled, this is the default cache instance. Otherwise, it is a NoopCache.
  507. *
  508. * @see Mustache_Engine::getCache
  509. *
  510. * @return Mustache_Cache
  511. */
  512. protected function getLambdaCache()
  513. {
  514. if ($this->cacheLambdaTemplates) {
  515. return $this->getCache();
  516. }
  517. if (!isset($this->lambdaCache)) {
  518. $this->lambdaCache = new Mustache_Cache_NoopCache();
  519. }
  520. return $this->lambdaCache;
  521. }
  522. /**
  523. * Helper method to generate a Mustache template class.
  524. *
  525. * @param string $source
  526. *
  527. * @return string Mustache Template class name
  528. */
  529. public function getTemplateClassName($source)
  530. {
  531. return $this->templateClassPrefix . md5(sprintf(
  532. 'version:%s,escape:%s,entity_flags:%i,charset:%s,strict_callables:%s,pragmas:%s,source:%s',
  533. self::VERSION,
  534. isset($this->escape) ? 'custom' : 'default',
  535. $this->entityFlags,
  536. $this->charset,
  537. $this->strictCallables ? 'true' : 'false',
  538. implode(' ', $this->getPragmas()),
  539. $source
  540. ));
  541. }
  542. /**
  543. * Load a Mustache Template by name.
  544. *
  545. * @param string $name
  546. *
  547. * @return Mustache_Template
  548. */
  549. public function loadTemplate($name)
  550. {
  551. return $this->loadSource($this->getLoader()->load($name));
  552. }
  553. /**
  554. * Load a Mustache partial Template by name.
  555. *
  556. * This is a helper method used internally by Template instances for loading partial templates. You can most likely
  557. * ignore it completely.
  558. *
  559. * @param string $name
  560. *
  561. * @return Mustache_Template
  562. */
  563. public function loadPartial($name)
  564. {
  565. try {
  566. if (isset($this->partialsLoader)) {
  567. $loader = $this->partialsLoader;
  568. } elseif (isset($this->loader) && !$this->loader instanceof Mustache_Loader_StringLoader) {
  569. $loader = $this->loader;
  570. } else {
  571. throw new Mustache_Exception_UnknownTemplateException($name);
  572. }
  573. return $this->loadSource($loader->load($name));
  574. } catch (Mustache_Exception_UnknownTemplateException $e) {
  575. // If the named partial cannot be found, log then return null.
  576. $this->log(
  577. Mustache_Logger::WARNING,
  578. 'Partial not found: "{name}"',
  579. array('name' => $e->getTemplateName())
  580. );
  581. }
  582. }
  583. /**
  584. * Load a Mustache lambda Template by source.
  585. *
  586. * This is a helper method used by Template instances to generate subtemplates for Lambda sections. You can most
  587. * likely ignore it completely.
  588. *
  589. * @param string $source
  590. * @param string $delims (default: null)
  591. *
  592. * @return Mustache_Template
  593. */
  594. public function loadLambda($source, $delims = null)
  595. {
  596. if ($delims !== null) {
  597. $source = $delims . "\n" . $source;
  598. }
  599. return $this->loadSource($source, $this->getLambdaCache());
  600. }
  601. /**
  602. * Instantiate and return a Mustache Template instance by source.
  603. *
  604. * Optionally provide a Mustache_Cache instance. This is used internally by Mustache_Engine::loadLambda to respect
  605. * the 'cache_lambda_templates' configuration option.
  606. *
  607. * @see Mustache_Engine::loadTemplate
  608. * @see Mustache_Engine::loadPartial
  609. * @see Mustache_Engine::loadLambda
  610. *
  611. * @param string $source
  612. * @param Mustache_Cache $cache (default: null)
  613. *
  614. * @return Mustache_Template
  615. */
  616. private function loadSource($source, Mustache_Cache $cache = null)
  617. {
  618. $className = $this->getTemplateClassName($source);
  619. if (!isset($this->templates[$className])) {
  620. if ($cache === null) {
  621. $cache = $this->getCache();
  622. }
  623. if (!class_exists($className, false)) {
  624. if (!$cache->load($className)) {
  625. $compiled = $this->compile($source);
  626. $cache->cache($className, $compiled);
  627. }
  628. }
  629. $this->log(
  630. Mustache_Logger::DEBUG,
  631. 'Instantiating template: "{className}"',
  632. array('className' => $className)
  633. );
  634. $this->templates[$className] = new $className($this);
  635. }
  636. return $this->templates[$className];
  637. }
  638. /**
  639. * Helper method to tokenize a Mustache template.
  640. *
  641. * @see Mustache_Tokenizer::scan
  642. *
  643. * @param string $source
  644. *
  645. * @return array Tokens
  646. */
  647. private function tokenize($source)
  648. {
  649. return $this->getTokenizer()->scan($source);
  650. }
  651. /**
  652. * Helper method to parse a Mustache template.
  653. *
  654. * @see Mustache_Parser::parse
  655. *
  656. * @param string $source
  657. *
  658. * @return array Token tree
  659. */
  660. private function parse($source)
  661. {
  662. $parser = $this->getParser();
  663. $parser->setPragmas($this->getPragmas());
  664. return $parser->parse($this->tokenize($source));
  665. }
  666. /**
  667. * Helper method to compile a Mustache template.
  668. *
  669. * @see Mustache_Compiler::compile
  670. *
  671. * @param string $source
  672. *
  673. * @return string generated Mustache template class code
  674. */
  675. private function compile($source)
  676. {
  677. $tree = $this->parse($source);
  678. $name = $this->getTemplateClassName($source);
  679. $this->log(
  680. Mustache_Logger::INFO,
  681. 'Compiling template to "{className}" class',
  682. array('className' => $name)
  683. );
  684. $compiler = $this->getCompiler();
  685. $compiler->setPragmas($this->getPragmas());
  686. return $compiler->compile($source, $tree, $name, isset($this->escape), $this->charset, $this->strictCallables, $this->entityFlags);
  687. }
  688. /**
  689. * Add a log record if logging is enabled.
  690. *
  691. * @param int $level The logging level
  692. * @param string $message The log message
  693. * @param array $context The log context
  694. */
  695. private function log($level, $message, array $context = array())
  696. {
  697. if (isset($this->logger)) {
  698. $this->logger->log($level, $message, $context);
  699. }
  700. }
  701. }