mirror of
https://github.com/wintercms/winter.git
synced 2024-06-28 05:33:29 +02:00
Fix issues with accessing the expected context variables inside of Twig macros.
This fixes #578 by adding the ability to pass the CMS Controller instance to the CMS Twig Extension removing the reliance on context variables as well as making the expected "global" twig variables inside of the CMS Twig environment actually global within that environment. Replaces #598 & #593. Credit to @RomainMazB for the initial implementation.
This commit is contained in:
parent
e2683d8041
commit
5b8d189df4
2
.github/workflows/code-quality.yaml
vendored
2
.github/workflows/code-quality.yaml
vendored
@ -26,7 +26,7 @@ jobs:
|
||||
- name: Install PHP and PHP Code Sniffer
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: 7.3
|
||||
php-version: 8.0
|
||||
extensions: curl, fileinfo, gd, mbstring, openssl, pdo, pdo_sqlite, sqlite3, xml, zip
|
||||
tools: phpcs
|
||||
|
||||
|
@ -47,8 +47,7 @@
|
||||
},
|
||||
"scripts": {
|
||||
"post-create-project-cmd": [
|
||||
"@php artisan key:generate",
|
||||
"@php artisan package:discover"
|
||||
"@php artisan key:generate"
|
||||
],
|
||||
"post-update-cmd": [
|
||||
"@php artisan winter:version",
|
||||
|
@ -306,7 +306,7 @@ class Controller
|
||||
/*
|
||||
* The 'this' variable is reserved for default variables.
|
||||
*/
|
||||
$this->vars['this'] = [
|
||||
$this->getTwig()->addGlobal('this', [
|
||||
'page' => $this->page,
|
||||
'layout' => $this->layout,
|
||||
'theme' => $this->theme,
|
||||
@ -314,7 +314,7 @@ class Controller
|
||||
'controller' => $this,
|
||||
'environment' => App::environment(),
|
||||
'session' => App::make('session'),
|
||||
];
|
||||
]);
|
||||
|
||||
/*
|
||||
* Check for the presence of validation errors in the session.
|
||||
@ -584,6 +584,7 @@ class Controller
|
||||
protected function initTwigEnvironment()
|
||||
{
|
||||
$this->twig = App::make('twig.environment.cms');
|
||||
$this->twig->getExtension(\Cms\Twig\Extension::class)->setController($this);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
namespace Cms\Tests\Classes;
|
||||
|
||||
use Cms;
|
||||
use System\Tests\Bootstrap\TestCase;
|
||||
use Cms\Classes\Theme;
|
||||
use Cms\Classes\Controller;
|
||||
@ -589,7 +590,7 @@ ESC;
|
||||
$response = $controller->run('/with-macro')->getContent();
|
||||
|
||||
$this->assertStringContainsString(
|
||||
'<p><a href="/">with-macro.htm</a><strong>with-macro.htm</strong></p>',
|
||||
'<p><a href="' . Cms::url('/') . '">with-macro.htm</a><strong>with-macro.htm</strong></p>',
|
||||
$response
|
||||
);
|
||||
}
|
||||
|
@ -3,5 +3,4 @@ url = "/with-macro"
|
||||
{% macro pageTest(_context) -%}
|
||||
<a href="{{ 'index' | page }}">{{ this.page.fileName }}</a>
|
||||
{%- endmacro pageTest %}
|
||||
|
||||
<p>{{ _self.pageTest() }}<strong>{{ this.page.fileName }}</strong></p>
|
||||
|
@ -34,7 +34,7 @@ class ComponentNode extends TwigNode
|
||||
}
|
||||
|
||||
$compiler
|
||||
->write("echo \$this->env->getExtension('Cms\Twig\Extension')->componentFunction(\$context,")
|
||||
->write("echo \$this->env->getExtension('Cms\Twig\Extension')->componentFunction(")
|
||||
->subcompile($this->getNode('nodes')->getNode(0))
|
||||
->write(", \$context['__cms_component_params']")
|
||||
->write(");\n")
|
||||
|
@ -36,7 +36,7 @@ class ContentNode extends TwigNode
|
||||
}
|
||||
|
||||
$compiler
|
||||
->write("echo \$this->env->getExtension('Cms\Twig\Extension')->contentFunction(\$context,")
|
||||
->write("echo \$this->env->getExtension('Cms\Twig\Extension')->contentFunction(")
|
||||
->subcompile($this->getNode('nodes')->getNode(0))
|
||||
->write(", \$context['__cms_content_params']")
|
||||
->write(");\n")
|
||||
|
@ -5,6 +5,7 @@ use Event;
|
||||
use Twig\Extension\AbstractExtension as TwigExtension;
|
||||
use Twig\TwigFilter as TwigSimpleFilter;
|
||||
use Twig\TwigFunction as TwigSimpleFunction;
|
||||
use Cms\Classes\Controller;
|
||||
|
||||
/**
|
||||
* The CMS Twig extension class implements the basic CMS Twig functions and filters.
|
||||
@ -14,6 +15,27 @@ use Twig\TwigFunction as TwigSimpleFunction;
|
||||
*/
|
||||
class Extension extends TwigExtension
|
||||
{
|
||||
/**
|
||||
* The instanciated CMS controller
|
||||
*/
|
||||
protected Controller $controller;
|
||||
|
||||
/**
|
||||
* Sets the CMS controller instance
|
||||
*/
|
||||
public function setController(Controller $controller)
|
||||
{
|
||||
$this->controller = $controller;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the CMS controller instance
|
||||
*/
|
||||
public function getController(): Controller
|
||||
{
|
||||
return $this->controller;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of functions to add to the existing list.
|
||||
*/
|
||||
@ -21,7 +43,6 @@ class Extension extends TwigExtension
|
||||
{
|
||||
$options = [
|
||||
'is_safe' => ['html'],
|
||||
'needs_context' => true,
|
||||
];
|
||||
|
||||
return [
|
||||
@ -40,7 +61,6 @@ class Extension extends TwigExtension
|
||||
{
|
||||
$options = [
|
||||
'is_safe' => ['html'],
|
||||
'needs_context' => true,
|
||||
];
|
||||
|
||||
return [
|
||||
@ -73,41 +93,41 @@ class Extension extends TwigExtension
|
||||
/**
|
||||
* Renders a page; used in the layout code to output the requested page.
|
||||
*/
|
||||
public function pageFunction(array $context): string
|
||||
public function pageFunction(): string
|
||||
{
|
||||
return $context['this']['controller']->renderPage();
|
||||
return $this->controller->renderPage();
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the requested partial with the provided parameters. Optionally throw an exception if the partial cannot be found
|
||||
*/
|
||||
public function partialFunction(array $context, string $name, array $parameters = [], bool $throwException = false): string
|
||||
public function partialFunction(string $name, array $parameters = [], bool $throwException = false): string
|
||||
{
|
||||
return $context['this']['controller']->renderPartial($name, $parameters, $throwException);
|
||||
return $this->controller->renderPartial($name, $parameters, $throwException);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the requested content file.
|
||||
*/
|
||||
public function contentFunction(array $context, string $name, array $parameters = []): string
|
||||
public function contentFunction(string $name, array $parameters = []): string
|
||||
{
|
||||
return $context['this']['controller']->renderContent($name, $parameters);
|
||||
return $this->controller->renderContent($name, $parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a component's default partial.
|
||||
*/
|
||||
public function componentFunction(array $context, string $name, array $parameters = []): string
|
||||
public function componentFunction(string $name, array $parameters = []): string
|
||||
{
|
||||
return $context['this']['controller']->renderComponent($name, $parameters);
|
||||
return $this->controller->renderComponent($name, $parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders registered assets of a given type or all types if $type not provided
|
||||
*/
|
||||
public function assetsFunction(array $context, string $type = null): ?string
|
||||
public function assetsFunction(string $type = null): ?string
|
||||
{
|
||||
return $context['this']['controller']->makeAssets($type);
|
||||
return $this->controller->makeAssets($type);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -126,26 +146,24 @@ class Extension extends TwigExtension
|
||||
/**
|
||||
* Returns the relative URL for the provided page
|
||||
*
|
||||
* @param array $context The Twig context for the call (relies on $context['this']['controller'] to exist)
|
||||
* @param mixed $name Specifies the Cms Page file name.
|
||||
* @param array|bool $parameters Route parameters to consider in the URL. If boolean will be used as the value for $routePersistence
|
||||
* @param bool $routePersistence Set to false to exclude the existing routing parameters from the generated URL
|
||||
*/
|
||||
public function pageFilter(array $context, $name, $parameters = [], $routePersistence = true): ?string
|
||||
public function pageFilter($name, $parameters = [], $routePersistence = true): ?string
|
||||
{
|
||||
return $context['this']['controller']->pageUrl($name, $parameters, $routePersistence);
|
||||
return $this->controller->pageUrl($name, $parameters, $routePersistence);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts supplied URL to a theme URL relative to the website root. If the URL provided is an
|
||||
* array then the files will be combined.
|
||||
*
|
||||
* @param array $context The Twig context for the call (relies on $context['this']['controller'] to exist)
|
||||
* @param mixed $url Specifies the input to be turned into a URL (arrays will be passed to the AssetCombiner)
|
||||
*/
|
||||
public function themeFilter(array $context, $url): string
|
||||
public function themeFilter($url): string
|
||||
{
|
||||
return $context['this']['controller']->themeUrl($url);
|
||||
return $this->controller->themeUrl($url);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -25,7 +25,7 @@ class PageNode extends TwigNode
|
||||
{
|
||||
$compiler
|
||||
->addDebugInfo($this)
|
||||
->write("echo \$this->env->getExtension('Cms\Twig\Extension')->pageFunction(\$context);\n")
|
||||
->write("echo \$this->env->getExtension('Cms\Twig\Extension')->pageFunction();\n")
|
||||
;
|
||||
}
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ class PartialNode extends TwigNode
|
||||
}
|
||||
|
||||
$compiler
|
||||
->write("echo \$this->env->getExtension('Cms\Twig\Extension')->partialFunction(\$context,")
|
||||
->write("echo \$this->env->getExtension('Cms\Twig\Extension')->partialFunction(")
|
||||
->subcompile($this->getNode('nodes')->getNode(0))
|
||||
->write(", \$context['__cms_partial_params']")
|
||||
->write(", true")
|
||||
|
@ -25,7 +25,7 @@ class ScriptsNode extends TwigNode
|
||||
{
|
||||
$compiler
|
||||
->addDebugInfo($this)
|
||||
->write("echo \$this->env->getExtension('Cms\Twig\Extension')->assetsFunction(\$context, 'js');\n")
|
||||
->write("echo \$this->env->getExtension('Cms\Twig\Extension')->assetsFunction('js');\n")
|
||||
->write("echo \$this->env->getExtension('Cms\Twig\Extension')->displayBlock('scripts');\n")
|
||||
;
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ class StylesNode extends TwigNode
|
||||
{
|
||||
$compiler
|
||||
->addDebugInfo($this)
|
||||
->write("echo \$this->env->getExtension('Cms\Twig\Extension')->assetsFunction(\$context, 'css');\n")
|
||||
->write("echo \$this->env->getExtension('Cms\Twig\Extension')->assetsFunction('css');\n")
|
||||
->write("echo \$this->env->getExtension('Cms\Twig\Extension')->displayBlock('styles');\n")
|
||||
;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user