PageRenderTime 55ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/system/src/Grav/Common/Twig/Twig.php

https://gitlab.com/3dplex/3d-plex-main-site
PHP | 420 lines | 237 code | 60 blank | 123 comment | 27 complexity | 87df64786666148e9ff9017190a7824e MD5 | raw file
  1. <?php
  2. <<<<<<< HEAD
  3. =======
  4. /**
  5. * @package Grav.Common.Twig
  6. *
  7. * @copyright Copyright (C) 2014 - 2016 RocketTheme, LLC. All rights reserved.
  8. * @license MIT License; see LICENSE file for details.
  9. */
  10. >>>>>>> update grav cms
  11. namespace Grav\Common\Twig;
  12. use Grav\Common\Grav;
  13. use Grav\Common\Config\Config;
  14. use Grav\Common\Language\Language;
  15. use Grav\Common\Page\Page;
  16. use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;
  17. use RocketTheme\Toolbox\Event\Event;
  18. <<<<<<< HEAD
  19. /**
  20. * The Twig object handles all the Twig template rendering for Grav. It's a singleton object
  21. * that is optimized so that it only needs to be initialized once and can be reused for individual
  22. * page template rendering as well as the main site template rendering.
  23. *
  24. * @author RocketTheme
  25. * @license MIT
  26. */
  27. =======
  28. >>>>>>> update grav cms
  29. class Twig
  30. {
  31. /**
  32. * @var \Twig_Environment
  33. */
  34. public $twig;
  35. /**
  36. * @var array
  37. */
  38. public $twig_vars = [];
  39. /**
  40. * @var array
  41. */
  42. public $twig_paths;
  43. /**
  44. * @var string
  45. */
  46. public $template;
  47. /**
  48. * @var Grav
  49. */
  50. protected $grav;
  51. /**
  52. * @var \Twig_Loader_Filesystem
  53. */
  54. protected $loader;
  55. /**
  56. * @var \Twig_Loader_Array
  57. */
  58. protected $loaderArray;
  59. <<<<<<< HEAD
  60. =======
  61. protected $autoescape;
  62. >>>>>>> update grav cms
  63. /**
  64. * Constructor
  65. *
  66. * @param Grav $grav
  67. */
  68. public function __construct(Grav $grav)
  69. {
  70. $this->grav = $grav;
  71. $this->twig_paths = [];
  72. }
  73. /**
  74. * Twig initialization that sets the twig loader chain, then the environment, then extensions
  75. * and also the base set of twig vars
  76. */
  77. public function init()
  78. {
  79. if (!isset($this->twig)) {
  80. /** @var Config $config */
  81. $config = $this->grav['config'];
  82. /** @var UniformResourceLocator $locator */
  83. $locator = $this->grav['locator'];
  84. /** @var Language $language */
  85. $language = $this->grav['language'];
  86. $active_language = $language->getActive();
  87. <<<<<<< HEAD
  88. $language_append = '';
  89. if ($language->getDefault() != $active_language || $config->get('system.languages.include_default_lang') === true) {
  90. $language_append = $active_language ? '/' . $active_language : '';
  91. =======
  92. $path_append = rtrim($this->grav['pages']->base(), '/');
  93. if ($language->getDefault() != $active_language || $config->get('system.languages.include_default_lang') === true) {
  94. $path_append .= $active_language ? '/' . $active_language : '';
  95. >>>>>>> update grav cms
  96. }
  97. // handle language templates if available
  98. if ($language->enabled()) {
  99. $lang_templates = $locator->findResource('theme://templates/' . ($active_language ? $active_language : $language->getDefault()));
  100. if ($lang_templates) {
  101. $this->twig_paths[] = $lang_templates;
  102. }
  103. }
  104. $this->twig_paths = array_merge($this->twig_paths, $locator->findResources('theme://templates'));
  105. $this->grav->fireEvent('onTwigTemplatePaths');
  106. $this->loader = new \Twig_Loader_Filesystem($this->twig_paths);
  107. $this->loaderArray = new \Twig_Loader_Array([]);
  108. $loader_chain = new \Twig_Loader_Chain([$this->loaderArray, $this->loader]);
  109. $params = $config->get('system.twig');
  110. if (!empty($params['cache'])) {
  111. <<<<<<< HEAD
  112. $params['cache'] = $locator->findResource('cache://twig', true, true);
  113. =======
  114. $cachePath = $locator->findResource('cache://twig', true, true);
  115. $params['cache'] = new \Twig_Cache_Filesystem($cachePath, \Twig_Cache_Filesystem::FORCE_BYTECODE_INVALIDATION);
  116. }
  117. if (!empty($this->autoescape)) {
  118. $params['autoescape'] = $this->autoescape;
  119. >>>>>>> update grav cms
  120. }
  121. $this->twig = new TwigEnvironment($loader_chain, $params);
  122. if ($config->get('system.twig.undefined_functions')) {
  123. $this->twig->registerUndefinedFunctionCallback(function ($name) {
  124. if (function_exists($name)) {
  125. return new \Twig_Function_Function($name);
  126. }
  127. return new \Twig_Function_Function(function () {
  128. });
  129. });
  130. }
  131. if ($config->get('system.twig.undefined_filters')) {
  132. $this->twig->registerUndefinedFilterCallback(function ($name) {
  133. if (function_exists($name)) {
  134. return new \Twig_Filter_Function($name);
  135. }
  136. return new \Twig_Filter_Function(function () {
  137. });
  138. });
  139. }
  140. $this->grav->fireEvent('onTwigInitialized');
  141. // set default date format if set in config
  142. if ($config->get('system.pages.dateformat.long')) {
  143. $this->twig->getExtension('core')->setDateFormat($config->get('system.pages.dateformat.long'));
  144. }
  145. // enable the debug extension if required
  146. if ($config->get('system.twig.debug')) {
  147. $this->twig->addExtension(new \Twig_Extension_Debug());
  148. }
  149. $this->twig->addExtension(new TwigExtension());
  150. $this->grav->fireEvent('onTwigExtensions');
  151. // Set some standard variables for twig
  152. $this->twig_vars = $this->twig_vars + [
  153. 'config' => $config,
  154. 'uri' => $this->grav['uri'],
  155. 'base_dir' => rtrim(ROOT_DIR, '/'),
  156. <<<<<<< HEAD
  157. 'base_url' => $this->grav['base_url'] . $language_append,
  158. 'base_url_simple' => $this->grav['base_url'],
  159. 'base_url_absolute' => $this->grav['base_url_absolute'] . $language_append,
  160. 'base_url_relative' => $this->grav['base_url_relative'] . $language_append,
  161. =======
  162. 'base_url' => $this->grav['base_url'] . $path_append,
  163. 'base_url_simple' => $this->grav['base_url'],
  164. 'base_url_absolute' => $this->grav['base_url_absolute'] . $path_append,
  165. 'base_url_relative' => $this->grav['base_url_relative'] . $path_append,
  166. >>>>>>> update grav cms
  167. 'theme_dir' => $locator->findResource('theme://'),
  168. 'theme_url' => $this->grav['base_url'] . '/' . $locator->findResource('theme://', false),
  169. 'site' => $config->get('site'),
  170. 'assets' => $this->grav['assets'],
  171. 'taxonomy' => $this->grav['taxonomy'],
  172. 'browser' => $this->grav['browser'],
  173. ];
  174. }
  175. }
  176. /**
  177. * @return \Twig_Environment
  178. */
  179. public function twig()
  180. {
  181. return $this->twig;
  182. }
  183. /**
  184. * @return \Twig_Loader_Filesystem
  185. */
  186. public function loader()
  187. {
  188. return $this->loader;
  189. }
  190. /**
  191. * Adds or overrides a template.
  192. *
  193. * @param string $name The template name
  194. * @param string $template The template source
  195. */
  196. public function setTemplate($name, $template)
  197. {
  198. $this->loaderArray->setTemplate($name, $template);
  199. }
  200. /**
  201. * Twig process that renders a page item. It supports two variations:
  202. * 1) Handles modular pages by rendering a specific page based on its modular twig template
  203. * 2) Renders individual page items for twig processing before the site rendering
  204. *
  205. * @param Page $item The page item to render
  206. * @param string $content Optional content override
  207. *
  208. * @return string The rendered output
  209. * @throws \Twig_Error_Loader
  210. */
  211. public function processPage(Page $item, $content = null)
  212. {
  213. $content = $content !== null ? $content : $item->content();
  214. // override the twig header vars for local resolution
  215. $this->grav->fireEvent('onTwigPageVariables', new Event(['page' => $item]));
  216. $twig_vars = $this->twig_vars;
  217. $twig_vars['page'] = $item;
  218. $twig_vars['media'] = $item->media();
  219. $twig_vars['header'] = $item->header();
  220. $local_twig = clone($this->twig);
  221. $modular_twig = $item->modularTwig();
  222. $process_twig = isset($item->header()->process['twig']) ? $item->header()->process['twig'] : false;
  223. $output = '';
  224. try {
  225. // Process Modular Twig
  226. if ($modular_twig) {
  227. $twig_vars['content'] = $content;
  228. $template = $item->template() . TEMPLATE_EXT;
  229. $output = $content = $local_twig->render($template, $twig_vars);
  230. }
  231. // Process in-page Twig
  232. if (!$modular_twig || ($modular_twig && $process_twig)) {
  233. $name = '@Page:' . $item->path();
  234. $this->setTemplate($name, $content);
  235. $output = $local_twig->render($name, $twig_vars);
  236. }
  237. } catch (\Twig_Error_Loader $e) {
  238. throw new \RuntimeException($e->getRawMessage(), 404, $e);
  239. }
  240. return $output;
  241. }
  242. /**
  243. * Process a Twig template directly by using a template name
  244. * and optional array of variables
  245. *
  246. * @param string $template template to render with
  247. * @param array $vars Optional variables
  248. *
  249. * @return string
  250. */
  251. public function processTemplate($template, $vars = [])
  252. {
  253. // override the twig header vars for local resolution
  254. $this->grav->fireEvent('onTwigTemplateVariables');
  255. $vars += $this->twig_vars;
  256. try {
  257. $output = $this->twig->render($template, $vars);
  258. } catch (\Twig_Error_Loader $e) {
  259. throw new \RuntimeException($e->getRawMessage(), 404, $e);
  260. }
  261. return $output;
  262. }
  263. /**
  264. * Process a Twig template directly by using a Twig string
  265. * and optional array of variables
  266. *
  267. * @param string $string string to render.
  268. * @param array $vars Optional variables
  269. *
  270. * @return string
  271. */
  272. public function processString($string, array $vars = [])
  273. {
  274. // override the twig header vars for local resolution
  275. $this->grav->fireEvent('onTwigStringVariables');
  276. $vars += $this->twig_vars;
  277. $name = '@Var:' . $string;
  278. $this->setTemplate($name, $string);
  279. try {
  280. $output = $this->twig->render($name, $vars);
  281. } catch (\Twig_Error_Loader $e) {
  282. throw new \RuntimeException($e->getRawMessage(), 404, $e);
  283. }
  284. return $output;
  285. }
  286. /**
  287. * Twig process that renders the site layout. This is the main twig process that renders the overall
  288. * page and handles all the layout for the site display.
  289. *
  290. * @param string $format Output format (defaults to HTML).
  291. *
  292. * @return string the rendered output
  293. * @throws \RuntimeException
  294. */
  295. public function processSite($format = null)
  296. {
  297. // set the page now its been processed
  298. $this->grav->fireEvent('onTwigSiteVariables');
  299. $pages = $this->grav['pages'];
  300. $page = $this->grav['page'];
  301. $content = $page->content();
  302. $twig_vars = $this->twig_vars;
  303. $twig_vars['pages'] = $pages->root();
  304. $twig_vars['page'] = $page;
  305. $twig_vars['header'] = $page->header();
  306. $twig_vars['media'] = $page->media();
  307. $twig_vars['content'] = $content;
  308. $ext = '.' . ($format ? $format : 'html') . TWIG_EXT;
  309. // determine if params are set, if so disable twig cache
  310. $params = $this->grav['uri']->params(null, true);
  311. if (!empty($params)) {
  312. $this->twig->setCache(false);
  313. }
  314. // Get Twig template layout
  315. $template = $this->template($page->template() . $ext);
  316. try {
  317. $output = $this->twig->render($template, $twig_vars);
  318. } catch (\Twig_Error_Loader $e) {
  319. $error_msg = $e->getMessage();
  320. // Try html version of this template if initial template was NOT html
  321. if ($ext != '.html' . TWIG_EXT) {
  322. try {
  323. $output = $this->twig->render($page->template() . '.html' . TWIG_EXT, $twig_vars);
  324. } catch (\Twig_Error_Loader $e) {
  325. throw new \RuntimeException($error_msg, 400, $e);
  326. }
  327. } else {
  328. throw new \RuntimeException($error_msg, 400, $e);
  329. }
  330. }
  331. return $output;
  332. }
  333. /**
  334. * Simple helper method to get the twig template if it has already been set, else return
  335. * the one being passed in
  336. *
  337. * @param string $template the template name
  338. *
  339. * @return string the template name
  340. */
  341. public function template($template)
  342. {
  343. if (isset($this->template)) {
  344. return $this->template;
  345. } else {
  346. return $template;
  347. }
  348. }
  349. <<<<<<< HEAD
  350. =======
  351. /**
  352. * Overrides the autoescape setting
  353. *
  354. * @param boolean $state
  355. */
  356. public function setAutoescape($state) {
  357. $this->autoescape = (bool) $state;
  358. }
  359. >>>>>>> update grav cms
  360. }