diff --git a/core/lib/Drupal/Core/CoreServiceProvider.php b/core/lib/Drupal/Core/CoreServiceProvider.php index 098b165..d99ae28 100644 --- a/core/lib/Drupal/Core/CoreServiceProvider.php +++ b/core/lib/Drupal/Core/CoreServiceProvider.php @@ -134,6 +134,8 @@ public static function registerTwig(ContainerBuilder $container) { 'debug' => settings()->get('twig_debug', FALSE), 'auto_reload' => settings()->get('twig_auto_reload', NULL), )) + ->addArgument(new Reference('module_handler')) + ->addArgument(new Reference('theme_handler')) ->addMethodCall('addExtension', array(new Definition('Drupal\Core\Template\TwigExtension'))) // @todo Figure out what to do about debugging functions. // @see http://drupal.org/node/1804998 diff --git a/core/lib/Drupal/Core/Template/TwigEnvironment.php b/core/lib/Drupal/Core/Template/TwigEnvironment.php index 2ac1d9d..886f555 100644 --- a/core/lib/Drupal/Core/Template/TwigEnvironment.php +++ b/core/lib/Drupal/Core/Template/TwigEnvironment.php @@ -8,6 +8,8 @@ namespace Drupal\Core\Template; use Drupal\Component\PhpStorage\PhpStorageFactory; +use Drupal\Core\Extension\ModuleHandlerInterface; +use Drupal\Core\Extension\ThemeHandlerInterface; /** * A class that defines a Twig environment for Drupal. @@ -32,10 +34,23 @@ class TwigEnvironment extends \Twig_Environment { * Constructs a TwigEnvironment object and stores cache and storage * internally. */ - public function __construct(\Twig_LoaderInterface $loader = NULL, $options = array()) { + public function __construct(\Twig_LoaderInterface $loader = NULL, $options = array(), ModuleHandlerInterface $module_handler, ThemeHandlerInterface $theme_handler) { // @todo Pass as arguments from the DIC. $this->cache_object = cache(); + // Set twig path namespace for themes and modules + $namespaces = $module_handler->getModuleList(); + foreach ($theme_handler->listInfo() as $theme => $info) { + $namespaces[$theme] = $info->filename; + } + + foreach ($namespaces as $name => $filename) { + $templatesDirectory = dirname($filename) . '/templates'; + if (file_exists($templatesDirectory)) { + $loader->addPath($templatesDirectory, $name); + } + } + $this->templateClasses = array(); parent::__construct($loader, $options); diff --git a/core/modules/system/lib/Drupal/system/Tests/Theme/TwigNamespaceTest.php b/core/modules/system/lib/Drupal/system/Tests/Theme/TwigNamespaceTest.php new file mode 100644 index 0000000..1068a3f --- /dev/null +++ b/core/modules/system/lib/Drupal/system/Tests/Theme/TwigNamespaceTest.php @@ -0,0 +1,66 @@ + 'Twig Namespaces', + 'description' => 'Tests Twig namespaces.', + 'group' => 'Theme', + ); + } + + function setUp() { + parent::setUp(); + theme_enable(array('test_theme', 'bartik')); + $this->twig = \Drupal::service('twig'); + } + + /** + * Check to see if a value is a twig template. + */ + public function assertTwigTemplate($value, $message = '', $group = 'Other') { + $this->assertTrue($value instanceof \Twig_Template, $message, $group); + } + + public function testTemplateDiscovery() { + // Enabled module + $this->assertTwigTemplate($this->twig->resolveTemplate('@node/node.html.twig'), 'Found node.tpl.php in node module.'); + + // Enabled theme + $this->assertTwigTemplate($this->twig->resolveTemplate('@bartik/page.html.twig'), 'Found page.html.twig in bartik theme.'); + } + + public function testTwigNamespaces() { + // Test twig @extends and @include in template files. + $this->drupalSetContent(theme('twig_namespace_test')); + + $this->assertText('This line is from twig_namespace_a/templates/test.html.twig'); + $this->assertText('This line is from twig_namespace_b/templates/test.html.twig'); + } + +} diff --git a/core/modules/system/tests/modules/twig_theme_test/modules/twig_namespace_a/templates/test.html.twig b/core/modules/system/tests/modules/twig_theme_test/modules/twig_namespace_a/templates/test.html.twig new file mode 100644 index 0000000..ed52e5e --- /dev/null +++ b/core/modules/system/tests/modules/twig_theme_test/modules/twig_namespace_a/templates/test.html.twig @@ -0,0 +1,5 @@ +This line is from twig_namespace_a/templates/test.html.twig + +{% block content %} +This text is in a block. +{% endblock %} diff --git a/core/modules/system/tests/modules/twig_theme_test/modules/twig_namespace_a/twig_namespace_a.info.yml b/core/modules/system/tests/modules/twig_theme_test/modules/twig_namespace_a/twig_namespace_a.info.yml new file mode 100644 index 0000000..d007f21 --- /dev/null +++ b/core/modules/system/tests/modules/twig_theme_test/modules/twig_namespace_a/twig_namespace_a.info.yml @@ -0,0 +1,7 @@ +name: 'Twig namespace test: Module A' +type: module +description: 'Support module for Twig namespace testing.' +package: Testing +version: VERSION +core: 8.x +hidden: true diff --git a/core/modules/system/tests/modules/twig_theme_test/modules/twig_namespace_a/twig_namespace_a.module b/core/modules/system/tests/modules/twig_theme_test/modules/twig_namespace_a/twig_namespace_a.module new file mode 100644 index 0000000..37a5536 --- /dev/null +++ b/core/modules/system/tests/modules/twig_theme_test/modules/twig_namespace_a/twig_namespace_a.module @@ -0,0 +1,6 @@ + array(), 'template' => 'twig_theme_test.trans', ); + $items['twig_namespace_test'] = array( + 'variables' => array(), + 'template' => 'twig_namespace_test', + ); return $items; }