diff --git a/core/core.services.yml b/core/core.services.yml
index 8ce9b11..cf36009 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -1279,6 +1279,7 @@ services:
- { name: service_collector, tag: 'twig.extension', call: addExtension }
twig.extension:
class: Drupal\Core\Template\TwigExtension
+ arguments: ['@renderer']
tags:
- { name: twig.extension, priority: 100 }
calls:
diff --git a/core/lib/Drupal/Core/Template/TwigExtension.php b/core/lib/Drupal/Core/Template/TwigExtension.php
index 551e3cb..a2b1f59 100644
--- a/core/lib/Drupal/Core/Template/TwigExtension.php
+++ b/core/lib/Drupal/Core/Template/TwigExtension.php
@@ -12,6 +12,7 @@
namespace Drupal\Core\Template;
+use Drupal\Core\Render\RendererInterface;
use Drupal\Core\Routing\UrlGeneratorInterface;
use Drupal\Core\Url;
use Drupal\Core\Utility\LinkGeneratorInterface;
@@ -40,10 +41,29 @@ class TwigExtension extends \Twig_Extension {
protected $linkGenerator;
/**
+ * The renderer.
+ *
+ * @var \Drupal\Core\Render\RendererInterface
+ */
+ protected $renderer;
+
+ /**
* Constructs \Drupal\Core\Template\TwigExtension.
*
+ * @param \Drupal\Core\Render\RendererInterface $renderer
+ * The renderer.
+ */
+ public function __construct(RendererInterface $renderer) {
+ $this->renderer = $renderer;
+ }
+
+ /**
+ * Sets the URL generator.
+ *
* @param \Drupal\Core\Routing\UrlGeneratorInterface $url_generator
* The URL generator.
+ *
+ * @return $this
*/
public function setGenerators(UrlGeneratorInterface $url_generator) {
$this->urlGenerator = $url_generator;
@@ -77,6 +97,7 @@ public function getFunctions() {
new \Twig_SimpleFunction('url_from_path', array($this, 'getUrlFromPath'), array('is_safe_callback' => array($this, 'isUrlGenerationSafe'))),
new \Twig_SimpleFunction('link', array($this, 'getLink')),
new \Twig_SimpleFunction('file_url', 'file_create_url'),
+ new \Twig_SimpleFunction('attach_library', array($this, 'attachLibrary'))
);
}
@@ -257,4 +278,22 @@ public function isUrlGenerationSafe(\Twig_Node $args_node) {
return array();
}
+ /**
+ * Attaches an asset library to the template, and hence to the response.
+ *
+ * Allows Twig templates to attach asset libraries using
+ * @code
+ * {{ attach_library('extension/library_name') }}
+ * @endcode
+ *
+ * @param string $library
+ * An asset library.
+ */
+ public function attachLibrary($library) {
+ // Use Renderer::render() on a temporary render array to get additional
+ // bubbleable metadata on the render stack.
+ $template_attached = ['#attached' => ['library' => [$library]]];
+ $this->renderer->render($template_attached);
+ }
+
}
diff --git a/core/modules/system/src/Tests/Theme/EngineTwigTest.php b/core/modules/system/src/Tests/Theme/EngineTwigTest.php
index 750ae2e..ff84af7 100644
--- a/core/modules/system/src/Tests/Theme/EngineTwigTest.php
+++ b/core/modules/system/src/Tests/Theme/EngineTwigTest.php
@@ -111,4 +111,12 @@ public function testTwigFileUrls() {
$this->assertRaw('
file_url: ' . $filepath . '
');
}
+ /**
+ * Tests the attach of asset libraries.
+ */
+ public function testTwigAttachLibrary() {
+ $this->drupalGet('/twig-theme-test/attach-library');
+ $this->assertRaw('ckeditor.js');
+ }
+
}
diff --git a/core/modules/system/tests/modules/twig_extension_test/twig_extension_test.services.yml b/core/modules/system/tests/modules/twig_extension_test/twig_extension_test.services.yml
index 8784c0f..491d1e8 100644
--- a/core/modules/system/tests/modules/twig_extension_test/twig_extension_test.services.yml
+++ b/core/modules/system/tests/modules/twig_extension_test/twig_extension_test.services.yml
@@ -1,5 +1,6 @@
services:
twig_extension_test.twig.test_extension:
+ arguments: ['@renderer']
class: Drupal\twig_extension_test\TwigExtension\TestExtension
tags:
- { name: twig.extension }
diff --git a/core/modules/system/tests/modules/twig_theme_test/src/TwigThemeTestController.php b/core/modules/system/tests/modules/twig_theme_test/src/TwigThemeTestController.php
index ff49bd6..50d6c99 100644
--- a/core/modules/system/tests/modules/twig_theme_test/src/TwigThemeTestController.php
+++ b/core/modules/system/tests/modules/twig_theme_test/src/TwigThemeTestController.php
@@ -69,6 +69,15 @@ public function fileUrlRender() {
}
/**
+ * Renders for testing attach_library functions in a Twig template.
+ */
+ public function attachLibraryRender() {
+ return array(
+ '#theme' => 'twig_theme_test_attach_library',
+ );
+ }
+
+ /**
* Menu callback for testing the Twig registry loader.
*/
public function registryLoaderRender() {
diff --git a/core/modules/system/tests/modules/twig_theme_test/twig_theme_test.module b/core/modules/system/tests/modules/twig_theme_test/twig_theme_test.module
index 7f6fe35..021d039 100644
--- a/core/modules/system/tests/modules/twig_theme_test/twig_theme_test.module
+++ b/core/modules/system/tests/modules/twig_theme_test/twig_theme_test.module
@@ -50,6 +50,10 @@ function twig_theme_test_theme($existing, $type, $theme, $path) {
'variables' => array(),
'template' => 'twig_theme_test.file_url',
);
+ $items['twig_theme_test_attach_library'] = array(
+ 'variables' => array(),
+ 'template' => 'twig_theme_test.attach_library',
+ );
return $items;
}
diff --git a/core/modules/system/tests/modules/twig_theme_test/twig_theme_test.routing.yml b/core/modules/system/tests/modules/twig_theme_test/twig_theme_test.routing.yml
index 1001b47..c372c22 100644
--- a/core/modules/system/tests/modules/twig_theme_test/twig_theme_test.routing.yml
+++ b/core/modules/system/tests/modules/twig_theme_test/twig_theme_test.routing.yml
@@ -40,6 +40,13 @@ twig_theme_test_file_url:
requirements:
_access: 'TRUE'
+twig_theme_test_attach_library:
+ path: '/twig-theme-test/attach-library'
+ defaults:
+ _controller: '\Drupal\twig_theme_test\TwigThemeTestController::attachLibraryRender'
+ requirements:
+ _access: 'TRUE'
+
twig_theme_test_registry_loader:
path: '/twig-theme-test/registry-loader'
defaults:
diff --git a/core/tests/Drupal/Tests/Core/Template/TwigExtensionTest.php b/core/tests/Drupal/Tests/Core/Template/TwigExtensionTest.php
index 31352a6..3866965 100644
--- a/core/tests/Drupal/Tests/Core/Template/TwigExtensionTest.php
+++ b/core/tests/Drupal/Tests/Core/Template/TwigExtensionTest.php
@@ -25,13 +25,14 @@ class TwigExtensionTest extends UnitTestCase {
* @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' => TRUE,
'optimizations' => 0
));
- $twig->addExtension((new TwigExtension())->setGenerators($this->getMock('Drupal\Core\Routing\UrlGeneratorInterface')));
+ $twig->addExtension((new TwigExtension($renderer))->setGenerators($this->getMock('Drupal\Core\Routing\UrlGeneratorInterface')));
$nodes = $twig->parse($twig->tokenize($template));
diff --git a/core/themes/bartik/bartik.libraries.yml b/core/themes/bartik/bartik.libraries.yml
index 23ba491..a273f96 100644
--- a/core/themes/bartik/bartik.libraries.yml
+++ b/core/themes/bartik/bartik.libraries.yml
@@ -22,7 +22,6 @@ global-styling:
css/components/region-help.css: {}
css/components/item-list.css: {}
css/components/list-group.css: {}
- css/components/messages.css: {}
css/components/node-preview.css: {}
css/components/pager.css: {}
css/components/panel.css: {}
@@ -46,6 +45,12 @@ global-styling:
css/colors.css: {}
css/print.css: { media: print }
+messages:
+ version: VERSION
+ css:
+ theme:
+ css/components/messages.css: { preprocess: false }
+
color.preview:
version: VERSION
css:
diff --git a/core/themes/bartik/templates/status-messages.html.twig b/core/themes/bartik/templates/status-messages.html.twig
index a3b5d49..96188d3 100644
--- a/core/themes/bartik/templates/status-messages.html.twig
+++ b/core/themes/bartik/templates/status-messages.html.twig
@@ -24,6 +24,7 @@
#}
{% block messages %}
{% if message_list is not empty %}
+ {{ attach_library('bartik/messages') }}