diff --git a/core/core.services.yml b/core/core.services.yml index ee5c7f047d95683cf52ab58d7e6913b47118041b..8fdb3055779bd578a8632c00bcf37af911636cda 100644 --- a/core/core.services.yml +++ b/core/core.services.yml @@ -1125,7 +1125,7 @@ services: class: Drupal\Core\Extension\InfoParser twig: class: Drupal\Core\Template\TwigEnvironment - arguments: ['@app.root', '@twig.loader', '@module_handler', '@theme_handler', '%twig.config%'] + arguments: ['@app.root', '@twig.loader', '%twig.config%'] tags: - { name: service_collector, tag: 'twig.extension', call: addExtension } twig.extension: @@ -1142,10 +1142,24 @@ services: tags: - { name: twig.extension } twig.loader: - alias: twig.loader.filesystem + class: Twig_Loader_Chain + public: false + tags: + - { name: service_collector, tag: twig.loader, call: addLoader, required: TRUE } twig.loader.filesystem: - class: Twig_Loader_Filesystem - arguments: ['@app.root'] + class: Drupal\Core\Template\Loader\FilesystemLoader + arguments: ['@app.root', '@module_handler', '@theme_handler'] + tags: + - { name: twig.loader, priority: 100 } + twig.loader.theme_registry: + class: Drupal\Core\Template\Loader\ThemeRegistryLoader + arguments: ['@theme.registry'] + tags: + - { name: twig.loader, priority: 0 } + twig.loader.string: + class: Twig_Loader_String + tags: + - { name: twig.loader, priority: -100 } element_info: alias: plugin.manager.element_info file.mime_type.guesser: diff --git a/core/lib/Drupal/Core/DependencyInjection/Compiler/TaggedHandlersPass.php b/core/lib/Drupal/Core/DependencyInjection/Compiler/TaggedHandlersPass.php index 18927ca99dda31c07b581ab5b4c9228390db5dad..fb733ba03aa8f0fb2a1da872bfbc15b4fcb3fc54 100644 --- a/core/lib/Drupal/Core/DependencyInjection/Compiler/TaggedHandlersPass.php +++ b/core/lib/Drupal/Core/DependencyInjection/Compiler/TaggedHandlersPass.php @@ -53,6 +53,8 @@ class TaggedHandlersPass implements CompilerPassInterface { * - Optionally the handler's priority as second argument, if the method * accepts a second parameter and its name is "priority". In any case, all * handlers registered at compile time are sorted already. + * - required: Boolean indicating if at least one handler service is required. + * Defaults to FALSE. * * Example (YAML): * @code @@ -74,12 +76,15 @@ class TaggedHandlersPass implements CompilerPassInterface { * interface. * @throws \Symfony\Component\DependencyInjection\Exception\LogicException * If a tagged handler does not implement the required interface. + * @throws \Symfony\Component\DependencyInjection\Exception\LogicException + * If at least one tagged service is required but none are found. */ public function process(ContainerBuilder $container) { foreach ($container->findTaggedServiceIds('service_collector') as $consumer_id => $passes) { foreach ($passes as $pass) { $tag = isset($pass['tag']) ? $pass['tag'] : $consumer_id; $method_name = isset($pass['call']) ? $pass['call'] : 'addHandler'; + $required = isset($pass['required']) ? $pass['required'] : FALSE; // Determine parameters. $consumer = $container->getDefinition($consumer_id); @@ -122,6 +127,9 @@ public function process(ContainerBuilder $container) { $handlers[$id] = isset($attributes[0]['priority']) ? $attributes[0]['priority'] : 0; } if (empty($handlers)) { + if ($required) { + throw new LogicException(sprintf("At least one service tagged with '%s' is required.", $tag)); + } continue; } // Sort all handlers by priority. diff --git a/core/lib/Drupal/Core/Template/Loader/FilesystemLoader.php b/core/lib/Drupal/Core/Template/Loader/FilesystemLoader.php new file mode 100644 index 0000000000000000000000000000000000000000..f9098091a83071dae87899ed3ee9d82388412461 --- /dev/null +++ b/core/lib/Drupal/Core/Template/Loader/FilesystemLoader.php @@ -0,0 +1,52 @@ +<?php + +/** + * @file + * Contains \Drupal\Core\Template\Loader\FilesystemLoader. + */ + +namespace Drupal\Core\Template\Loader; + +use Drupal\Core\Extension\ModuleHandlerInterface; +use Drupal\Core\Extension\ThemeHandlerInterface; + +/** + * Loads templates from the filesystem. + * + * This loader adds module and theme template paths as namespaces to the Twig + * filesystem loader so that templates can be referenced by namespace, like + * @block/block.html.twig or @mytheme/page.html.twig. + */ +class FilesystemLoader extends \Twig_Loader_Filesystem { + + /** + * Constructs a new FilesystemLoader object. + * + * @param string|array $paths + * A path or an array of paths to check for templates. + * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler + * The module handler service. + * @param \Drupal\Core\Extension\ThemeHandlerInterface $theme_handler + * The theme handler service. + */ + public function __construct($paths = array(), ModuleHandlerInterface $module_handler, ThemeHandlerInterface $theme_handler) { + parent::__construct($paths); + + // Add namespaced paths for modules and themes. + $namespaces = array(); + foreach ($module_handler->getModuleList() as $name => $extension) { + $namespaces[$name] = $extension->getPath(); + } + foreach ($theme_handler->listInfo() as $name => $extension) { + $namespaces[$name] = $extension->getPath(); + } + + foreach ($namespaces as $name => $path) { + $templatesDirectory = $path . '/templates'; + if (file_exists($templatesDirectory)) { + $this->addPath($templatesDirectory, $name); + } + } + } + +} diff --git a/core/lib/Drupal/Core/Template/Loader/ThemeRegistryLoader.php b/core/lib/Drupal/Core/Template/Loader/ThemeRegistryLoader.php new file mode 100644 index 0000000000000000000000000000000000000000..fe1ae25fa7638e9f1c9fdc7d261ee2256901b792 --- /dev/null +++ b/core/lib/Drupal/Core/Template/Loader/ThemeRegistryLoader.php @@ -0,0 +1,69 @@ +<?php + +/** + * @file + * Contains \Drupal\Core\Template\Loader\ThemeRegistryLoader. + */ + +namespace Drupal\Core\Template\Loader; + +use Drupal\Core\Theme\Registry; + +/** + * Loads templates based on information from the Drupal theme registry. + * + * Allows for template inheritance based on the currently active template. + */ +class ThemeRegistryLoader extends \Twig_Loader_Filesystem { + + /** + * The theme registry used to determine which template to use. + * + * @var \Drupal\Core\Theme\Registry + */ + protected $themeRegistry; + + /** + * Constructs a new ThemeRegistryLoader object. + * + * @param \Drupal\Core\Theme\Registry $theme_registry + * The theme registry. + */ + public function __construct(Registry $theme_registry) { + $this->themeRegistry = $theme_registry; + } + + /** + * Finds the path to the requested template. + * + * @param string $name + * The name of the template to load. + * + * @return string + * The path to the template. + * + * @throws \Twig_Error_Loader + * Thrown if a template matching $name cannot be found. + */ + protected function findTemplate($name) { + // Allow for loading based on the Drupal theme registry. + $hook = str_replace('.html.twig', '', strtr($name, '-', '_')); + $theme_registry = $this->themeRegistry->getRuntime(); + + if ($theme_registry->has($hook)) { + $info = $theme_registry->get($hook); + if (isset($info['path'])) { + $path = $info['path'] . '/' . $name; + } + elseif (isset($info['template'])) { + $path = $info['template'] . '.html.twig'; + } + if (isset($path) && is_file($path)) { + return $this->cache[$name] = $path; + } + } + + throw new \Twig_Error_Loader(sprintf('Unable to find template "%s" in the Drupal theme registry.', $name)); + } + +} diff --git a/core/lib/Drupal/Core/Template/TwigEnvironment.php b/core/lib/Drupal/Core/Template/TwigEnvironment.php index 371627706b7fd5eef7b190259130d7d895edc540..e09d9f6bab7a4b8bd71003f4fb91e37ef4237ada 100644 --- a/core/lib/Drupal/Core/Template/TwigEnvironment.php +++ b/core/lib/Drupal/Core/Template/TwigEnvironment.php @@ -8,8 +8,6 @@ namespace Drupal\Core\Template; use Drupal\Core\PhpStorage\PhpStorageFactory; -use Drupal\Core\Extension\ModuleHandlerInterface; -use Drupal\Core\Extension\ThemeHandlerInterface; /** * A class that defines a Twig environment for Drupal. @@ -35,9 +33,13 @@ class TwigEnvironment extends \Twig_Environment { * internally. * * @param string $root - * The app root; + * The app root. + * @param \Twig_LoaderInterface $loader + * The Twig loader or loader chain. + * @param array $options + * The options for the Twig environment. */ - public function __construct($root, \Twig_LoaderInterface $loader = NULL, ModuleHandlerInterface $module_handler, ThemeHandlerInterface $theme_handler, $options = array()) { + public function __construct($root, \Twig_LoaderInterface $loader = NULL, $options = array()) { // @todo Pass as arguments from the DIC. $this->cache_object = \Drupal::cache(); @@ -45,22 +47,6 @@ public function __construct($root, \Twig_LoaderInterface $loader = NULL, ModuleH // template because functions like twig_drupal_escape_filter are called. require_once $root . '/core/themes/engines/twig/twig.engine'; - // Set twig path namespace for themes and modules. - $namespaces = array(); - foreach ($module_handler->getModuleList() as $name => $extension) { - $namespaces[$name] = $extension->getPath(); - } - foreach ($theme_handler->listInfo() as $name => $extension) { - $namespaces[$name] = $extension->getPath(); - } - - foreach ($namespaces as $name => $path) { - $templatesDirectory = $path . '/templates'; - if (file_exists($templatesDirectory)) { - $loader->addPath($templatesDirectory, $name); - } - } - $this->templateClasses = array(); $options += array( @@ -72,7 +58,7 @@ public function __construct($root, \Twig_LoaderInterface $loader = NULL, ModuleH // Ensure autoescaping is always on. $options['autoescape'] = TRUE; - $this->loader = new \Twig_Loader_Chain([$loader, new \Twig_Loader_String()]); + $this->loader = $loader; parent::__construct($this->loader, $options); } diff --git a/core/modules/system/src/Tests/Theme/TwigLoaderTest.php b/core/modules/system/src/Tests/Theme/TwigLoaderTest.php new file mode 100644 index 0000000000000000000000000000000000000000..91de1e4ac7be7e226b8e8a47cc4ad7a869ff2d68 --- /dev/null +++ b/core/modules/system/src/Tests/Theme/TwigLoaderTest.php @@ -0,0 +1,39 @@ +<?php + +/** + * @file + * Contains \Drupal\system\Tests\Theme\TwigLoaderTest. + */ + +namespace Drupal\system\Tests\Theme; + +use Drupal\simpletest\WebTestBase; + +/** + * Tests adding Twig loaders. + * + * @group Theme + */ +class TwigLoaderTest extends WebTestBase { + + /** + * Modules to enable. + * + * @var array + */ + public static $modules = ['twig_loader_test']; + + /** + * Tests adding an additional twig loader to the loader chain. + */ + public function testTwigLoaderAddition() { + $environment = \Drupal::service('twig'); + + $template = $environment->loadTemplate('kittens'); + $this->assertEqual($template->render(array()), 'kittens', 'Passing "kittens" to the custom Twig loader returns "kittens".'); + + $template = $environment->loadTemplate('meow'); + $this->assertEqual($template->render(array()), 'cats', 'Passing something other than "kittens" to the custom Twig loader returns "cats".'); + } + +} diff --git a/core/modules/system/src/Tests/Theme/TwigRegistryLoaderTest.php b/core/modules/system/src/Tests/Theme/TwigRegistryLoaderTest.php new file mode 100644 index 0000000000000000000000000000000000000000..589632b9025c3d29687f3e238842e2c3ac5a7044 --- /dev/null +++ b/core/modules/system/src/Tests/Theme/TwigRegistryLoaderTest.php @@ -0,0 +1,70 @@ +<?php + +/** + * @file + * Contains \Drupal\system\Tests\Theme\TwigRegistryLoaderTest. + */ + +namespace Drupal\system\Tests\Theme; + +use Drupal\simpletest\WebTestBase; + +/** + * Tests Twig registry loader. + * + * @group Theme + */ +class TwigRegistryLoaderTest extends WebTestBase { + + /** + * Modules to enable. + * + * @var array + */ + public static $modules = array('twig_theme_test', 'block'); + + /** + * @var \Drupal\Core\Template\TwigEnvironment + */ + protected $twig; + + protected function setUp() { + parent::setUp(); + \Drupal::service('theme_handler')->install(array('test_theme_twig_registry_loader')); + $this->twig = \Drupal::service('twig'); + } + + /** + * Checks to see if a value is a Twig template. + */ + public function assertTwigTemplate($value, $message = '', $group = 'Other') { + $this->assertTrue($value instanceof \Twig_Template, $message, $group); + } + + /** + * Tests template discovery using the Drupal theme registry. + */ + public function testTemplateDiscovery() { + $this->assertTwigTemplate($this->twig->resolveTemplate('block.html.twig'), 'Found block.html.twig in block module.'); + } + + /** + * Tests template extension and includes using the Drupal theme registry. + */ + public function testTwigNamespaces() { + // Test the module-provided extend and insert templates. + $this->drupalGet('twig-theme-test/registry-loader'); + $this->assertText('This line is from twig_theme_test/templates/twig-registry-loader-test-extend.html.twig'); + $this->assertText('This line is from twig_theme_test/templates/twig-registry-loader-test-include.html.twig'); + + // Enable a theme that overrides the extend and insert templates to ensure + // they are picked up by the registry loader. + $this->config('system.theme') + ->set('default', 'test_theme_twig_registry_loader') + ->save(); + $this->drupalGet('twig-theme-test/registry-loader'); + $this->assertText('This line is from test_theme_twig_registry_loader/templates/twig-registry-loader-test-extend.html.twig'); + $this->assertText('This line is from test_theme_twig_registry_loader/templates/twig-registry-loader-test-include.html.twig'); + } + +} diff --git a/core/modules/system/templates/block--system-branding-block.html.twig b/core/modules/system/templates/block--system-branding-block.html.twig index 4cf0f1a8823c81a6b48207d2cab32b6eacc23b16..f648773492b6511548ab06fca174d7dfbc7b06fc 100644 --- a/core/modules/system/templates/block--system-branding-block.html.twig +++ b/core/modules/system/templates/block--system-branding-block.html.twig @@ -1,4 +1,4 @@ -{% extends "@block/block.html.twig" %} +{% extends "block.html.twig" %} {# /** * @file diff --git a/core/modules/system/tests/modules/twig_loader_test/src/Loader/TestLoader.php b/core/modules/system/tests/modules/twig_loader_test/src/Loader/TestLoader.php new file mode 100644 index 0000000000000000000000000000000000000000..9f32969af5929762ecf41ea20fba385cc5db8f03 --- /dev/null +++ b/core/modules/system/tests/modules/twig_loader_test/src/Loader/TestLoader.php @@ -0,0 +1,50 @@ +<?php + +/** + * @file + * Contains \Drupal\twig_loader_test\Loader\TestLoader. + */ + +namespace Drupal\twig_loader_test\Loader; + +use Drupal\Core\Template\Loader; + +/** + * A test Twig loader. + */ +class TestLoader implements \Twig_LoaderInterface, \Twig_ExistsLoaderInterface { + + /** + * {@inheritdoc} + */ + public function getSource($name) { + if ($name == 'kittens') { + return $name; + } + else { + return 'cats'; + } + } + + /** + * {@inheritdoc} + */ + public function exists($name) { + return TRUE; + } + + /** + * {@inheritdoc} + */ + public function getCacheKey($name) { + return $name; + } + + /** + * {@inheritdoc} + */ + public function isFresh($name, $time) { + return TRUE; + } + +} diff --git a/core/modules/system/tests/modules/twig_loader_test/twig_loader_test.info.yml b/core/modules/system/tests/modules/twig_loader_test/twig_loader_test.info.yml new file mode 100644 index 0000000000000000000000000000000000000000..cf04aaeae3f29dd6d0f66143f57618df0964f3c3 --- /dev/null +++ b/core/modules/system/tests/modules/twig_loader_test/twig_loader_test.info.yml @@ -0,0 +1,6 @@ +name: 'Twig Loader Test' +type: module +description: 'Support module for testing adding Twig loaders.' +package: Testing +version: VERSION +core: 8.x diff --git a/core/modules/system/tests/modules/twig_loader_test/twig_loader_test.services.yml b/core/modules/system/tests/modules/twig_loader_test/twig_loader_test.services.yml new file mode 100644 index 0000000000000000000000000000000000000000..1b1994861e7635c184eda02c6e23fc27b2617972 --- /dev/null +++ b/core/modules/system/tests/modules/twig_loader_test/twig_loader_test.services.yml @@ -0,0 +1,5 @@ +services: + twig_loader_test.twig.test_loader: + class: Drupal\twig_loader_test\Loader\TestLoader + tags: + - { name: twig.loader } 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 96fcb67e11314c485b4d25b5984809dfd5017995..2bf5394a5683cfa3180c7c1a8084cb4d5504ab87 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 @@ -58,4 +58,11 @@ public function fileUrlRender() { ); } + /** + * Menu callback for testing the Twig registry loader. + */ + public function registryLoaderRender() { + return array('#theme' => 'twig_registry_loader_test'); + } + } diff --git a/core/modules/system/tests/modules/twig_theme_test/templates/twig-registry-loader-test-extend.html.twig b/core/modules/system/tests/modules/twig_theme_test/templates/twig-registry-loader-test-extend.html.twig new file mode 100644 index 0000000000000000000000000000000000000000..e18e68ef443cb39429b53e1f6546f85bdd7acca9 --- /dev/null +++ b/core/modules/system/tests/modules/twig_theme_test/templates/twig-registry-loader-test-extend.html.twig @@ -0,0 +1,5 @@ +This line is from twig_theme_test/templates/twig-registry-loader-test-extend.html.twig + +{% block content %} +This text is in a block. +{% endblock %} diff --git a/core/modules/system/tests/modules/twig_theme_test/templates/twig-registry-loader-test-include.html.twig b/core/modules/system/tests/modules/twig_theme_test/templates/twig-registry-loader-test-include.html.twig new file mode 100644 index 0000000000000000000000000000000000000000..438fd2b6988f56372623136ffe4a5138efde9ed9 --- /dev/null +++ b/core/modules/system/tests/modules/twig_theme_test/templates/twig-registry-loader-test-include.html.twig @@ -0,0 +1 @@ +This line is from twig_theme_test/templates/twig-registry-loader-test-include.html.twig diff --git a/core/modules/system/tests/modules/twig_theme_test/templates/twig-registry-loader-test.html.twig b/core/modules/system/tests/modules/twig_theme_test/templates/twig-registry-loader-test.html.twig new file mode 100644 index 0000000000000000000000000000000000000000..a3723b5a390e5a2628b9196bb787dd0d58d10d29 --- /dev/null +++ b/core/modules/system/tests/modules/twig_theme_test/templates/twig-registry-loader-test.html.twig @@ -0,0 +1,5 @@ +{% extends "twig-registry-loader-test-extend.html.twig" %} + +{% block content %} + {% include "twig-registry-loader-test-include.html.twig" %} +{% endblock %} 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 4a415cd0b314fc6bb951904768221cf3f45ee2c8..e42b020824640ffee7767b70fc5b54c4f79183b7 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 @@ -19,6 +19,15 @@ function twig_theme_test_theme($existing, $type, $theme, $path) { 'variables' => array(), 'template' => 'twig_namespace_test', ); + $items['twig_registry_loader_test'] = array( + 'variables' => array(), + ); + $items['twig_registry_loader_test_include'] = array( + 'variables' => array(), + ); + $items['twig_registry_loader_test_extend'] = array( + 'variables' => array(), + ); $items['twig_raw_test'] = array( 'variables' => array('script' => ''), ); 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 d2abf916a931aa543985c1db851a55145fb8bbb9..4d30bb95096f6c3bda0db5d168bff543a888a883 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 @@ -32,3 +32,10 @@ twig_theme_test_file_url: _controller: '\Drupal\twig_theme_test\TwigThemeTestController::fileUrlRender' requirements: _access: 'TRUE' + +twig_theme_test_registry_loader: + path: '/twig-theme-test/registry-loader' + defaults: + _controller: '\Drupal\twig_theme_test\TwigThemeTestController::registryLoaderRender' + requirements: + _access: 'TRUE' diff --git a/core/modules/system/tests/themes/test_theme_twig_registry_loader/templates/twig-registry-loader-test-extend.html.twig b/core/modules/system/tests/themes/test_theme_twig_registry_loader/templates/twig-registry-loader-test-extend.html.twig new file mode 100644 index 0000000000000000000000000000000000000000..e1a9eee41a7bfc0a4c2858740ff362b702ef0194 --- /dev/null +++ b/core/modules/system/tests/themes/test_theme_twig_registry_loader/templates/twig-registry-loader-test-extend.html.twig @@ -0,0 +1,5 @@ +This line is from test_theme_twig_registry_loader/templates/twig-registry-loader-test-extend.html.twig + +{% block content %} +This text is in a block. +{% endblock %} diff --git a/core/modules/system/tests/themes/test_theme_twig_registry_loader/templates/twig-registry-loader-test-include.html.twig b/core/modules/system/tests/themes/test_theme_twig_registry_loader/templates/twig-registry-loader-test-include.html.twig new file mode 100644 index 0000000000000000000000000000000000000000..3a1f395dedb3c16ffcb80d97cb8b2d0099df7d4d --- /dev/null +++ b/core/modules/system/tests/themes/test_theme_twig_registry_loader/templates/twig-registry-loader-test-include.html.twig @@ -0,0 +1 @@ +This line is from test_theme_twig_registry_loader/templates/twig-registry-loader-test-include.html.twig diff --git a/core/modules/system/tests/themes/test_theme_twig_registry_loader/test_theme_twig_registry_loader.info.yml b/core/modules/system/tests/themes/test_theme_twig_registry_loader/test_theme_twig_registry_loader.info.yml new file mode 100644 index 0000000000000000000000000000000000000000..9ee01c5364e649a378265c53cb023442c1a4b716 --- /dev/null +++ b/core/modules/system/tests/themes/test_theme_twig_registry_loader/test_theme_twig_registry_loader.info.yml @@ -0,0 +1,5 @@ +name: 'Twig registry loader test' +type: theme +description: 'Support module for Twig registry loader testing.' +version: VERSION +core: 8.x diff --git a/core/modules/text/templates/field--text-long.html.twig b/core/modules/text/templates/field--text-long.html.twig index 5f201f053dc974d995dbf280c71a15d93aabebea..07ce721d2d70e767cb74b466243e590f97dfe5ef 100644 --- a/core/modules/text/templates/field--text-long.html.twig +++ b/core/modules/text/templates/field--text-long.html.twig @@ -1 +1 @@ -{% extends "@text/field--text.html.twig" %} +{% extends "field--text.html.twig" %} diff --git a/core/modules/text/templates/field--text-with-summary.html.twig b/core/modules/text/templates/field--text-with-summary.html.twig index 5f201f053dc974d995dbf280c71a15d93aabebea..07ce721d2d70e767cb74b466243e590f97dfe5ef 100644 --- a/core/modules/text/templates/field--text-with-summary.html.twig +++ b/core/modules/text/templates/field--text-with-summary.html.twig @@ -1 +1 @@ -{% extends "@text/field--text.html.twig" %} +{% extends "field--text.html.twig" %} diff --git a/core/modules/text/templates/field--text.html.twig b/core/modules/text/templates/field--text.html.twig index 6a63a0c8d2b6d7130bd19aa38e0220df1eaea18f..9cd1ab9faf904b6002e088739c237ca749549239 100644 --- a/core/modules/text/templates/field--text.html.twig +++ b/core/modules/text/templates/field--text.html.twig @@ -1,4 +1,4 @@ -{% extends "@system/field.html.twig" %} +{% extends "field.html.twig" %} {# /** * @file diff --git a/core/tests/Drupal/Tests/Core/DependencyInjection/Compiler/TaggedHandlersPassTest.php b/core/tests/Drupal/Tests/Core/DependencyInjection/Compiler/TaggedHandlersPassTest.php index dd03a1fe5527c7387acace45d9fcccb8bb6e0d23..db6f39fcfab98df4551d703e7cdc48c072b1de30 100644 --- a/core/tests/Drupal/Tests/Core/DependencyInjection/Compiler/TaggedHandlersPassTest.php +++ b/core/tests/Drupal/Tests/Core/DependencyInjection/Compiler/TaggedHandlersPassTest.php @@ -41,6 +41,25 @@ public function testProcessNoConsumers() { $this->assertFalse($container->getDefinition('consumer_id')->hasMethodCall('addHandler')); } + /** + * Tests a required consumer with no handlers. + * + * @expectedException \Symfony\Component\DependencyInjection\Exception\LogicException + * @expectedExceptionMessage At least one service tagged with 'consumer_id' is required. + * @covers ::process + */ + public function testProcessRequiredHandlers() { + $container = $this->buildContainer(); + $container + ->register('consumer_id', __NAMESPACE__ . '\ValidConsumer') + ->addTag('service_collector', array( + 'required' => TRUE, + )); + + $handler_pass = new TaggedHandlersPass(); + $handler_pass->process($container); + } + /** * Tests consumer with missing interface in non-production environment. * diff --git a/core/themes/bartik/templates/block--system-branding-block.html.twig b/core/themes/bartik/templates/block--system-branding-block.html.twig index f6147a67e758cf549b2df3162303ccfe2340d3a3..4a4b733aebc612698cfceea437134e076b983a9f 100644 --- a/core/themes/bartik/templates/block--system-branding-block.html.twig +++ b/core/themes/bartik/templates/block--system-branding-block.html.twig @@ -1,4 +1,4 @@ -{% extends "@block/block.html.twig" %} +{% extends "block.html.twig" %} {# /** * @file