diff --git a/modules/cms/ServiceProvider.php b/modules/cms/ServiceProvider.php index db411be3c7..ae2397aca3 100644 --- a/modules/cms/ServiceProvider.php +++ b/modules/cms/ServiceProvider.php @@ -1,19 +1,26 @@ registerTwig(); $this->registerComponents(); $this->registerThemeLogging(); $this->registerCombinerEvents(); @@ -55,6 +63,49 @@ public function boot() $this->bootRichEditorEvents(); } + /** + * Register Twig templating engine. + */ + protected function registerTwig() + { + App::singleton('cms.twig.loader', function () { + return new TwigLoader; + }); + + App::singleton('cms.twig.environment', function ($app) { + $loader = $app->make('cms.twig.loader'); + + $useCache = !Config::get('cms.twigNoCache'); + $isDebugMode = Config::get('app.debug', false); + $strictVariables = Config::get('cms.enableTwigStrictVariables', false); + $strictVariables = $strictVariables ?? $isDebugMode; + $forceBytecode = Config::get('cms.forceBytecodeInvalidation', false); + + $options = [ + 'auto_reload' => true, + 'debug' => $isDebugMode, + 'strict_variables' => $strictVariables, + ]; + + if ($useCache) { + $options['cache'] = new Twig_Cache_Filesystem( + storage_path().'/cms/twig', + $forceBytecode ? Twig_Cache_Filesystem::FORCE_BYTECODE_INVALIDATION : 0 + ); + } + + $twig = new Twig_Environment($loader, $options); + $twig->addExtension(new CmsTwigExtension); + $twig->addExtension(new SystemTwigExtension); + + if ($isDebugMode) { + $twig->addExtension(new DebugExtension); + } + + return $twig; + }); + } + /** * Register components. */ diff --git a/modules/cms/classes/CmsCompoundObject.php b/modules/cms/classes/CmsCompoundObject.php index f5218c76ed..71d4876be8 100644 --- a/modules/cms/classes/CmsCompoundObject.php +++ b/modules/cms/classes/CmsCompoundObject.php @@ -1,16 +1,13 @@ addExtension(new CmsTwigExtension()); - $twig->addExtension(new SystemTwigExtension); - + $twig = App::make('cms.twig.environment'); $stream = $twig->tokenize(new Twig_Source($markup === false ? $this->markup : $markup, 'getTwigNodeTree')); return $twig->parse($stream); } diff --git a/modules/cms/classes/Controller.php b/modules/cms/classes/Controller.php index 68b2d8c52d..75919d49f7 100644 --- a/modules/cms/classes/Controller.php +++ b/modules/cms/classes/Controller.php @@ -13,15 +13,10 @@ use Exception; use BackendAuth; use Twig_Environment; -use Twig_Cache_Filesystem; -use Cms\Twig\Loader as TwigLoader; -use Cms\Twig\DebugExtension; -use Cms\Twig\Extension as CmsTwigExtension; use Cms\Models\MaintenanceSetting; use System\Models\RequestLog; use System\Helpers\View as ViewHelper; use System\Classes\CombineAssets; -use System\Twig\Extension as SystemTwigExtension; use October\Rain\Exception\AjaxException; use October\Rain\Exception\ValidationException; use October\Rain\Parse\Bracket as TextParser; @@ -585,34 +580,8 @@ protected function postProcessResult($page, $url, $content) */ protected function initTwigEnvironment() { - $this->loader = new TwigLoader; - - $useCache = !Config::get('cms.twigNoCache'); - $isDebugMode = Config::get('app.debug', false); - $strictVariables = Config::get('cms.enableTwigStrictVariables', false); - $strictVariables = $strictVariables ?? $isDebugMode; - $forceBytecode = Config::get('cms.forceBytecodeInvalidation', false); - - $options = [ - 'auto_reload' => true, - 'debug' => $isDebugMode, - 'strict_variables' => $strictVariables, - ]; - - if ($useCache) { - $options['cache'] = new Twig_Cache_Filesystem( - storage_path().'/cms/twig', - $forceBytecode ? Twig_Cache_Filesystem::FORCE_BYTECODE_INVALIDATION : 0 - ); - } - - $this->twig = new Twig_Environment($this->loader, $options); - $this->twig->addExtension(new CmsTwigExtension($this)); - $this->twig->addExtension(new SystemTwigExtension); - - if ($isDebugMode) { - $this->twig->addExtension(new DebugExtension($this)); - } + $this->loader = App::make('cms.twig.loader'); + $this->twig = App::make('cms.twig.environment'); } /** diff --git a/modules/cms/twig/ComponentNode.php b/modules/cms/twig/ComponentNode.php index db3ae85da0..e282ea5ce6 100644 --- a/modules/cms/twig/ComponentNode.php +++ b/modules/cms/twig/ComponentNode.php @@ -34,7 +34,7 @@ public function compile(Twig_Compiler $compiler) } $compiler - ->write("echo \$this->env->getExtension('Cms\Twig\Extension')->componentFunction(") + ->write("echo \$this->env->getExtension('Cms\Twig\Extension')->componentFunction(\$context,") ->subcompile($this->getNode('nodes')->getNode(0)) ->write(", \$context['__cms_component_params']") ->write(");\n") diff --git a/modules/cms/twig/ContentNode.php b/modules/cms/twig/ContentNode.php index 280ea2ce28..8235088808 100644 --- a/modules/cms/twig/ContentNode.php +++ b/modules/cms/twig/ContentNode.php @@ -36,7 +36,7 @@ public function compile(Twig_Compiler $compiler) } $compiler - ->write("echo \$this->env->getExtension('Cms\Twig\Extension')->contentFunction(") + ->write("echo \$this->env->getExtension('Cms\Twig\Extension')->contentFunction(\$context,") ->subcompile($this->getNode('nodes')->getNode(0)) ->write(", \$context['__cms_content_params']") ->write(");\n") diff --git a/modules/cms/twig/DebugExtension.php b/modules/cms/twig/DebugExtension.php index 5046b57280..cab0a5e635 100644 --- a/modules/cms/twig/DebugExtension.php +++ b/modules/cms/twig/DebugExtension.php @@ -4,7 +4,6 @@ use Twig_Extension; use Twig_Environment; use Twig_SimpleFunction; -use Cms\Classes\Controller; use Cms\Classes\ComponentBase; use Illuminate\Pagination\Paginator; use Illuminate\Support\Collection; @@ -19,11 +18,6 @@ class DebugExtension extends Twig_Extension const OBJECT_CAPTION = 'Object variables'; const COMPONENT_CAPTION = 'Component variables'; - /** - * @var \Cms\Classes\Controller A reference to the CMS controller. - */ - protected $controller; - /** * @var integer Helper for rendering table row styles. */ @@ -52,15 +46,6 @@ class DebugExtension extends Twig_Extension 'offsetUnset' ]; - /** - * Creates the extension instance. - * @param \Cms\Classes\Controller $controller The CMS controller object. - */ - public function __construct(Controller $controller) - { - $this->controller = $controller; - } - /** * Returns a list of global functions to add to the existing list. * @return array An array of global functions diff --git a/modules/cms/twig/Extension.php b/modules/cms/twig/Extension.php index 4b1987f0da..28514e5681 100644 --- a/modules/cms/twig/Extension.php +++ b/modules/cms/twig/Extension.php @@ -5,7 +5,6 @@ use Twig_Extension; use Twig_SimpleFilter; use Twig_SimpleFunction; -use Cms\Classes\Controller; /** * The CMS Twig extension class implements the basic CMS Twig functions and filters. @@ -15,20 +14,6 @@ */ class Extension extends Twig_Extension { - /** - * @var \Cms\Classes\Controller A reference to the CMS controller. - */ - protected $controller; - - /** - * Creates the extension instance. - * @param \Cms\Classes\Controller $controller The CMS controller object. - */ - public function __construct(Controller $controller = null) - { - $this->controller = $controller; - } - /** * Returns a list of functions to add to the existing list. * @@ -37,10 +22,10 @@ public function __construct(Controller $controller = null) public function getFunctions() { return [ - new Twig_SimpleFunction('page', [$this, 'pageFunction'], ['is_safe' => ['html']]), - new Twig_SimpleFunction('partial', [$this, 'partialFunction'], ['is_safe' => ['html']]), - new Twig_SimpleFunction('content', [$this, 'contentFunction'], ['is_safe' => ['html']]), - new Twig_SimpleFunction('component', [$this, 'componentFunction'], ['is_safe' => ['html']]), + new Twig_SimpleFunction('page', [$this, 'pageFunction'], ['is_safe' => ['html'], 'needs_context' => true]), + new Twig_SimpleFunction('partial', [$this, 'partialFunction'], ['is_safe' => ['html'], 'needs_context' => true]), + new Twig_SimpleFunction('content', [$this, 'contentFunction'], ['is_safe' => ['html'], 'needs_context' => true]), + new Twig_SimpleFunction('component', [$this, 'componentFunction'], ['is_safe' => ['html'], 'needs_context' => true]), new Twig_SimpleFunction('placeholder', [$this, 'placeholderFunction'], ['is_safe' => ['html']]), ]; } @@ -53,8 +38,8 @@ public function getFunctions() public function getFilters() { return [ - new Twig_SimpleFilter('page', [$this, 'pageFilter'], ['is_safe' => ['html']]), - new Twig_SimpleFilter('theme', [$this, 'themeFilter'], ['is_safe' => ['html']]), + new Twig_SimpleFilter('page', [$this, 'pageFilter'], ['is_safe' => ['html'], 'needs_context' => true]), + new Twig_SimpleFilter('theme', [$this, 'themeFilter'], ['is_safe' => ['html'], 'needs_context' => true]), ]; } @@ -85,9 +70,9 @@ public function getTokenParsers() * This function should be used in the layout code to output the requested page. * @return string Returns the page contents. */ - public function pageFunction() + public function pageFunction($context) { - return $this->controller->renderPage(); + return $context['this']['controller']->renderPage(); } /** @@ -97,9 +82,9 @@ public function pageFunction() * @param bool $throwException Throw an exception if the partial is not found. * @return string Returns the partial contents. */ - public function partialFunction($name, $parameters = [], $throwException = false) + public function partialFunction($context, $name, $parameters = [], $throwException = false) { - return $this->controller->renderPartial($name, $parameters, $throwException); + return $context['this']['controller']->renderPartial($name, $parameters, $throwException); } /** @@ -108,9 +93,9 @@ public function partialFunction($name, $parameters = [], $throwException = false * @param array $parameters A optional list of parameters to pass to the content. * @return string Returns the file contents. */ - public function contentFunction($name, $parameters = []) + public function contentFunction($context, $name, $parameters = []) { - return $this->controller->renderContent($name, $parameters); + return $context['this']['controller']->renderContent($name, $parameters); } /** @@ -119,18 +104,18 @@ public function contentFunction($name, $parameters = []) * @param array $parameters A optional list of parameters to pass to the component. * @return string Returns the component default contents. */ - public function componentFunction($name, $parameters = []) + public function componentFunction($context, $name, $parameters = []) { - return $this->controller->renderComponent($name, $parameters); + return $context['this']['controller']->renderComponent($name, $parameters); } /** * Renders registered assets of a given type * @return string Returns the component default contents. */ - public function assetsFunction($type = null) + public function assetsFunction($context, $type = null) { - return $this->controller->makeAssets($type); + return $context['this']['controller']->makeAssets($type); } /** @@ -156,9 +141,9 @@ public function placeholderFunction($name, $default = null) * when creating the URL, set to false to disable this feature. * @return string */ - public function pageFilter($name, $parameters = [], $routePersistence = true) + public function pageFilter($context, $name, $parameters = [], $routePersistence = true) { - return $this->controller->pageUrl($name, $parameters, $routePersistence); + return $context['this']['controller']->pageUrl($name, $parameters, $routePersistence); } /** @@ -167,9 +152,9 @@ public function pageFilter($name, $parameters = [], $routePersistence = true) * @param mixed $url Specifies the theme-relative URL * @return string */ - public function themeFilter($url) + public function themeFilter($context, $url) { - return $this->controller->themeUrl($url); + return $context['this']['controller']->themeUrl($url); } /** diff --git a/modules/cms/twig/PageNode.php b/modules/cms/twig/PageNode.php index 39ef0a81b4..3a2f01a8cf 100644 --- a/modules/cms/twig/PageNode.php +++ b/modules/cms/twig/PageNode.php @@ -25,7 +25,7 @@ public function compile(Twig_Compiler $compiler) { $compiler ->addDebugInfo($this) - ->write("echo \$this->env->getExtension('Cms\Twig\Extension')->pageFunction();\n") + ->write("echo \$this->env->getExtension('Cms\Twig\Extension')->pageFunction(\$context);\n") ; } } diff --git a/modules/cms/twig/PartialNode.php b/modules/cms/twig/PartialNode.php index 003bcf2fcc..6cb94cce45 100644 --- a/modules/cms/twig/PartialNode.php +++ b/modules/cms/twig/PartialNode.php @@ -34,7 +34,7 @@ public function compile(Twig_Compiler $compiler) } $compiler - ->write("echo \$this->env->getExtension('Cms\Twig\Extension')->partialFunction(") + ->write("echo \$this->env->getExtension('Cms\Twig\Extension')->partialFunction(\$context,") ->subcompile($this->getNode('nodes')->getNode(0)) ->write(", \$context['__cms_partial_params']") ->write(", true") diff --git a/modules/cms/twig/ScriptsNode.php b/modules/cms/twig/ScriptsNode.php index 72324b6fbd..0257138bcb 100644 --- a/modules/cms/twig/ScriptsNode.php +++ b/modules/cms/twig/ScriptsNode.php @@ -25,7 +25,7 @@ public function compile(Twig_Compiler $compiler) { $compiler ->addDebugInfo($this) - ->write("echo \$this->env->getExtension('Cms\Twig\Extension')->assetsFunction('js');\n") + ->write("echo \$this->env->getExtension('Cms\Twig\Extension')->assetsFunction(\$context, 'js');\n") ->write("echo \$this->env->getExtension('Cms\Twig\Extension')->displayBlock('scripts');\n") ; } diff --git a/modules/cms/twig/StylesNode.php b/modules/cms/twig/StylesNode.php index 5905d001d0..695a854467 100644 --- a/modules/cms/twig/StylesNode.php +++ b/modules/cms/twig/StylesNode.php @@ -25,7 +25,7 @@ public function compile(Twig_Compiler $compiler) { $compiler ->addDebugInfo($this) - ->write("echo \$this->env->getExtension('Cms\Twig\Extension')->assetsFunction('css');\n") + ->write("echo \$this->env->getExtension('Cms\Twig\Extension')->assetsFunction(\$context, 'css');\n") ->write("echo \$this->env->getExtension('Cms\Twig\Extension')->displayBlock('styles');\n") ; }