diff --git a/core/core.services.yml b/core/core.services.yml
index cb935793a6b0..5e6e2d9a80a9 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -1553,13 +1553,9 @@ services:
- { name: service_collector, tag: 'twig.extension', call: addExtension }
twig.extension:
class: Drupal\Core\Template\TwigExtension
- arguments: ['@renderer']
+ arguments: ['@renderer', '@url_generator', '@theme.manager', '@date.formatter']
tags:
- { name: twig.extension, priority: 100 }
- calls:
- - [setUrlGenerator, ['@url_generator']]
- - [setThemeManager, ['@theme.manager']]
- - [setDateFormatter, ['@date.formatter']]
# @todo Figure out what to do about debugging functions.
# @see https://www.drupal.org/node/1804998
twig.extension.debug:
diff --git a/core/lib/Drupal/Core/Template/TwigExtension.php b/core/lib/Drupal/Core/Template/TwigExtension.php
index 3fcbe2c86f37..7d67ff991c4c 100644
--- a/core/lib/Drupal/Core/Template/TwigExtension.php
+++ b/core/lib/Drupal/Core/Template/TwigExtension.php
@@ -58,9 +58,18 @@ class TwigExtension extends \Twig_Extension {
*
* @param \Drupal\Core\Render\RendererInterface $renderer
* The renderer.
+ * @param \Drupal\Core\Routing\UrlGeneratorInterface $url_generator
+ * The URL generator.
+ * @param \Drupal\Core\Theme\ThemeManagerInterface $theme_manager
+ * The theme manager.
+ * @param \Drupal\Core\Datetime\DateFormatterInterface $date_formatter
+ * The date formatter.
*/
- public function __construct(RendererInterface $renderer) {
+ public function __construct(RendererInterface $renderer, UrlGeneratorInterface $url_generator, ThemeManagerInterface $theme_manager, DateFormatterInterface $date_formatter) {
$this->renderer = $renderer;
+ $this->urlGenerator = $url_generator;
+ $this->themeManager = $theme_manager;
+ $this->dateFormatter = $date_formatter;
}
/**
@@ -72,7 +81,6 @@ class TwigExtension extends \Twig_Extension {
* @return $this
*
* @deprecated in Drupal 8.0.x-dev, will be removed before Drupal 9.0.0.
- * Use \Drupal\Core\Template\TwigExtension::setUrlGenerator().
*/
public function setGenerators(UrlGeneratorInterface $url_generator) {
return $this->setUrlGenerator($url_generator);
@@ -85,6 +93,8 @@ class TwigExtension extends \Twig_Extension {
* The URL generator.
*
* @return $this
+ *
+ * @deprecated in Drupal 8.3.x-dev, will be removed before Drupal 9.0.0.
*/
public function setUrlGenerator(UrlGeneratorInterface $url_generator) {
$this->urlGenerator = $url_generator;
@@ -98,6 +108,8 @@ class TwigExtension extends \Twig_Extension {
* The theme manager.
*
* @return $this
+ *
+ * @deprecated in Drupal 8.3.x-dev, will be removed before Drupal 9.0.0.
*/
public function setThemeManager(ThemeManagerInterface $theme_manager) {
$this->themeManager = $theme_manager;
@@ -111,6 +123,8 @@ class TwigExtension extends \Twig_Extension {
* The date formatter.
*
* @return $this
+ *
+ * @deprecated in Drupal 8.3.x-dev, will be removed before Drupal 9.0.0.
*/
public function setDateFormatter(DateFormatterInterface $date_formatter) {
$this->dateFormatter = $date_formatter;
diff --git a/core/modules/system/tests/modules/twig_extension_test/src/TwigExtension/TestExtension.php b/core/modules/system/tests/modules/twig_extension_test/src/TwigExtension/TestExtension.php
index 4afa3a78cbdd..78d10202882f 100644
--- a/core/modules/system/tests/modules/twig_extension_test/src/TwigExtension/TestExtension.php
+++ b/core/modules/system/tests/modules/twig_extension_test/src/TwigExtension/TestExtension.php
@@ -2,12 +2,11 @@
namespace Drupal\twig_extension_test\TwigExtension;
-use Drupal\Core\Template\TwigExtension;
/**
* A test Twig extension that adds a custom function and a custom filter.
*/
-class TestExtension extends TwigExtension {
+class TestExtension extends \Twig_Extension {
/**
* Generates a list of all Twig functions that this extension defines.
diff --git a/core/tests/Drupal/Tests/Core/Template/TwigExtensionTest.php b/core/tests/Drupal/Tests/Core/Template/TwigExtensionTest.php
index 38373aa06739..396b2f9765ff 100644
--- a/core/tests/Drupal/Tests/Core/Template/TwigExtensionTest.php
+++ b/core/tests/Drupal/Tests/Core/Template/TwigExtensionTest.php
@@ -1,16 +1,9 @@
renderer = $this->getMock('\Drupal\Core\Render\RendererInterface');
+ $this->urlGenerator = $this->getMock('\Drupal\Core\Routing\UrlGeneratorInterface');
+ $this->themeManager = $this->getMock('\Drupal\Core\Theme\ThemeManagerInterface');
+ $this->dateFormatter = $this->getMock('\Drupal\Core\Datetime\DateFormatterInterface');
+
+ $this->systemUnderTest = new TwigExtension($this->renderer, $this->urlGenerator, $this->themeManager, $this->dateFormatter);
+ }
+
/**
* Tests the escaping
*
* @dataProvider providerTestEscaping
*/
public function testEscaping($template, $expected) {
- $renderer = $this->getMock('\Drupal\Core\Render\RendererInterface');
$twig = new \Twig_Environment(NULL, array(
'debug' => TRUE,
'cache' => FALSE,
'autoescape' => 'html',
- 'optimizations' => 0
+ 'optimizations' => 0,
));
- $twig->addExtension((new TwigExtension($renderer))->setUrlGenerator($this->getMock('Drupal\Core\Routing\UrlGeneratorInterface')));
+ $twig->addExtension($this->systemUnderTest);
$nodes = $twig->parse($twig->tokenize($template));
$this->assertSame($expected, $nodes->getNode('body')
- ->getNode(0)
- ->getNode('expr') instanceof \Twig_Node_Expression_Filter);
+ ->getNode(0)
+ ->getNode('expr') instanceof \Twig_Node_Expression_Filter);
}
/**
@@ -83,25 +124,19 @@ class TwigExtensionTest extends UnitTestCase {
* Tests the active_theme function.
*/
public function testActiveTheme() {
- $renderer = $this->getMock('\Drupal\Core\Render\RendererInterface');
- $extension = new TwigExtension($renderer);
- $theme_manager = $this->getMock('\Drupal\Core\Theme\ThemeManagerInterface');
$active_theme = $this->getMockBuilder('\Drupal\Core\Theme\ActiveTheme')
->disableOriginalConstructor()
->getMock();
- $active_theme
- ->expects($this->once())
+ $active_theme->expects($this->once())
->method('getName')
->willReturn('test_theme');
- $theme_manager
- ->expects($this->once())
+ $this->themeManager->expects($this->once())
->method('getActiveTheme')
->willReturn($active_theme);
- $extension->setThemeManager($theme_manager);
$loader = new \Twig_Loader_String();
$twig = new \Twig_Environment($loader);
- $twig->addExtension($extension);
+ $twig->addExtension($this->systemUnderTest);
$result = $twig->render('{{ active_theme() }}');
$this->assertEquals('test_theme', $result);
}
@@ -110,30 +145,21 @@ class TwigExtensionTest extends UnitTestCase {
* Tests the format_date filter.
*/
public function testFormatDate() {
- $date_formatter = $this->getMockBuilder('\Drupal\Core\Datetime\DateFormatter')
- ->disableOriginalConstructor()
- ->getMock();
- $date_formatter->expects($this->exactly(2))
+ $this->dateFormatter->expects($this->exactly(2))
->method('format')
->willReturn('1978-11-19');
- $renderer = $this->getMock('\Drupal\Core\Render\RendererInterface');
- $extension = new TwigExtension($renderer);
- $extension->setDateFormatter($date_formatter);
$loader = new StringLoader();
$twig = new \Twig_Environment($loader);
- $twig->addExtension($extension);
+ $twig->addExtension($this->systemUnderTest);
$result = $twig->render('{{ time|format_date("html_date") }}');
- $this->assertEquals($date_formatter->format('html_date'), $result);
+ $this->assertEquals($this->dateFormatter->format('html_date'), $result);
}
/**
* Tests the active_theme_path function.
*/
public function testActiveThemePath() {
- $renderer = $this->getMock('\Drupal\Core\Render\RendererInterface');
- $extension = new TwigExtension($renderer);
- $theme_manager = $this->getMock('\Drupal\Core\Theme\ThemeManagerInterface');
$active_theme = $this->getMockBuilder('\Drupal\Core\Theme\ActiveTheme')
->disableOriginalConstructor()
->getMock();
@@ -141,15 +167,13 @@ class TwigExtensionTest extends UnitTestCase {
->expects($this->once())
->method('getPath')
->willReturn('foo/bar');
- $theme_manager
- ->expects($this->once())
+ $this->themeManager->expects($this->once())
->method('getActiveTheme')
->willReturn($active_theme);
- $extension->setThemeManager($theme_manager);
$loader = new \Twig_Loader_String();
$twig = new \Twig_Environment($loader);
- $twig->addExtension($extension);
+ $twig->addExtension($this->systemUnderTest);
$result = $twig->render('{{ active_theme_path() }}');
$this->assertEquals('foo/bar', $result);
}
@@ -160,34 +184,32 @@ class TwigExtensionTest extends UnitTestCase {
* @covers ::escapeFilter
*/
public function testSafeStringEscaping() {
- $renderer = $this->getMock('\Drupal\Core\Render\RendererInterface');
$twig = new \Twig_Environment(NULL, array(
'debug' => TRUE,
'cache' => FALSE,
'autoescape' => 'html',
- 'optimizations' => 0
+ 'optimizations' => 0,
));
- $twig_extension = new TwigExtension($renderer);
// By default, TwigExtension will attempt to cast objects to strings.
// Ensure objects that implement MarkupInterface are unchanged.
$safe_string = $this->getMock('\Drupal\Component\Render\MarkupInterface');
- $this->assertSame($safe_string, $twig_extension->escapeFilter($twig, $safe_string, 'html', 'UTF-8', TRUE));
+ $this->assertSame($safe_string, $this->systemUnderTest->escapeFilter($twig, $safe_string, 'html', 'UTF-8', TRUE));
// Ensure objects that do not implement MarkupInterface are escaped.
$string_object = new TwigExtensionTestString("");
- $this->assertSame('<script>alert('here');</script>', $twig_extension->escapeFilter($twig, $string_object, 'html', 'UTF-8', TRUE));
+ $this->assertSame('<script>alert('here');</script>', $this->systemUnderTest->escapeFilter($twig, $string_object, 'html', 'UTF-8', TRUE));
}
/**
* @covers ::safeJoin
*/
public function testSafeJoin() {
- $renderer = $this->prophesize(RendererInterface::class);
- $renderer->render(['#markup' => 'will be rendered', '#printed' => FALSE])->willReturn('will be rendered');
- $renderer = $renderer->reveal();
+ $this->renderer->expects($this->any())
+ ->method('render')
+ ->with(['#markup' => 'will be rendered', '#printed' => FALSE])
+ ->willReturn('will be rendered');
- $twig_extension = new TwigExtension($renderer);
$twig_environment = $this->prophesize(TwigEnvironment::class)->reveal();
// Simulate t().
@@ -198,9 +220,9 @@ class TwigExtensionTest extends UnitTestCase {
$items = [
'will be escaped',
$markup,
- ['#markup' => 'will be rendered']
+ ['#markup' => 'will be rendered'],
];
- $result = $twig_extension->safeJoin($twig_environment, $items, '
');
+ $result = $this->systemUnderTest->safeJoin($twig_environment, $items, '
');
$this->assertEquals('<em>will be escaped</em>
will be markup
will be rendered', $result);
// Ensure safe_join Twig filter supports Traversable variables.
@@ -209,12 +231,12 @@ class TwigExtensionTest extends UnitTestCase {
$markup,
['#markup' => 'will be rendered'],
]);
- $result = $twig_extension->safeJoin($twig_environment, $items, ', ');
+ $result = $this->systemUnderTest->safeJoin($twig_environment, $items, ', ');
$this->assertEquals('<em>will be escaped</em>, will be markup, will be rendered', $result);
// Ensure safe_join Twig filter supports empty variables.
$items = NULL;
- $result = $twig_extension->safeJoin($twig_environment, $items, '
');
+ $result = $this->systemUnderTest->safeJoin($twig_environment, $items, '
');
$this->assertEmpty($result);
}
@@ -222,13 +244,12 @@ class TwigExtensionTest extends UnitTestCase {
* @dataProvider providerTestRenderVar
*/
public function testRenderVar($result, $input) {
- $renderer = $this->prophesize(RendererInterface::class);
- $renderer->render($result += ['#printed' => FALSE])->willReturn('Rendered output');
+ $this->renderer->expects($this->any())
+ ->method('render')
+ ->with($result += ['#printed' => FALSE])
+ ->willReturn('Rendered output');
- $renderer = $renderer->reveal();
- $twig_extension = new TwigExtension($renderer);
-
- $this->assertEquals('Rendered output', $twig_extension->renderVar($input));
+ $this->assertEquals('Rendered output', $this->systemUnderTest->renderVar($input));
}
public function providerTestRenderVar() {
@@ -247,7 +268,6 @@ class TwigExtensionTest extends UnitTestCase {
* @covers ::bubbleArgMetadata
*/
public function testEscapeWithGeneratedLink() {
- $renderer = $this->prophesize(RendererInterface::class);
$twig = new \Twig_Environment(NULL, [
'debug' => TRUE,
'cache' => FALSE,
@@ -256,22 +276,23 @@ class TwigExtensionTest extends UnitTestCase {
]
);
- $twig_extension = new TwigExtension($renderer->reveal());
- $twig->addExtension($twig_extension->setUrlGenerator($this->prophesize(UrlGeneratorInterface::class)->reveal()));
+ $twig->addExtension($this->systemUnderTest);
$link = new GeneratedLink();
$link->setGeneratedLink('');
$link->addCacheTags(['foo']);
$link->addAttachments(['library' => ['system/base']]);
- $result = $twig_extension->escapeFilter($twig, $link, 'html', NULL, TRUE);
- $renderer->render([
- "#cache" => [
- "contexts" => [],
- "tags" => ["foo"],
- "max-age" => -1
- ],
- "#attached" => ['library' => ['system/base']],
- ])->shouldHaveBeenCalled();
+ $this->renderer->expects($this->atLeastOnce())
+ ->method('render')
+ ->with([
+ "#cache" => [
+ "contexts" => [],
+ "tags" => ["foo"],
+ "max-age" => -1,
+ ],
+ "#attached" => ['library' => ['system/base']],
+ ]);
+ $result = $this->systemUnderTest->escapeFilter($twig, $link, 'html', NULL, TRUE);
$this->assertEquals('', $result);
}
@@ -280,22 +301,22 @@ class TwigExtensionTest extends UnitTestCase {
* @covers ::bubbleArgMetadata
*/
public function testRenderVarWithGeneratedLink() {
- $renderer = $this->prophesize(RendererInterface::class);
- $twig_extension = new TwigExtension($renderer->reveal());
$link = new GeneratedLink();
$link->setGeneratedLink('');
$link->addCacheTags(['foo']);
$link->addAttachments(['library' => ['system/base']]);
- $result = $twig_extension->renderVar($link);
- $renderer->render([
- "#cache" => [
- "contexts" => [],
- "tags" => ["foo"],
- "max-age" => -1
- ],
- "#attached" => ['library' => ['system/base']],
- ])->shouldHaveBeenCalled();
+ $this->renderer->expects($this->atLeastOnce())
+ ->method('render')
+ ->with([
+ "#cache" => [
+ "contexts" => [],
+ "tags" => ["foo"],
+ "max-age" => -1,
+ ],
+ "#attached" => ['library' => ['system/base']],
+ ]);
+ $result = $this->systemUnderTest->renderVar($link);
$this->assertEquals('', $result);
}
@@ -305,11 +326,9 @@ class TwigExtensionTest extends UnitTestCase {
* @covers ::createAttribute
*/
public function testCreateAttribute() {
- $renderer = $this->prophesize(RendererInterface::class);
- $extension = new TwigExtension($renderer->reveal());
$loader = new StringLoader();
$twig = new \Twig_Environment($loader);
- $twig->addExtension($extension);
+ $twig->addExtension($this->systemUnderTest);
$iterations = [
['class' => ['kittens'], 'data-toggle' => 'modal', 'data-lang' => 'es'],