Registering Twig namespaces
Adding a Twig namespace
Here's how you would register a "myComponents" component library residing in a myFiles directory of your theme or module. In your .info.yml file, add these lines:
components:
namespaces:
myComponents: myFiles
As long as your theme's or module's directory contains a myFiles/box/box.twig Twig template, you can extends, include or embed it using a reference to @myComponents/box/box.twig. For example, in your [my theme directory]/templates/page.html.twig you could add:
{% extends "@myComponents/box/box.twig" %}
This allows you to specify the exact component in your component library no matter how Drupal normally requires you to organize the Drupal-style Twig templates.
New in 3.0.0: You can now skip the path to the Twig file if the component is deeply nested in your namespace’s path. For example, a Twig file located at myFiles/containers/box/box.twig can be referenced with @myComponents/containers/box/box.twig or with @myComponents/box.twig.
API details
In your module or theme's .info.yml file, you can specify multiple namespaces and each namespace can have multiple directories.
# This example YAML creates 3 namespaces: @atoms, @quarks, @universe
components:
namespaces:
# If your namespace only has one directory,
# you can use this simple YAML syntax.
atoms: library/atoms
quarks: library/quarks
# If you want to search multiple directories when
# using a namespace, use the YAML list syntax.
universe:
- library/universe
- deprecated/universe
Normally, the directory paths you specify are relative to the .info.yml file that defines them. If, instead, the path starts with a /, then the path is relative to the Drupal root directory. For example:
# If this file is located at
# themes/contrib/standard_model/standard_model.info.yml
# then...
components:
namespaces:
# The @atoms namespace will point to:
# themes/contrib/standard_model/library/atoms
atoms: library/atoms
# The @quarks namespace will point to:
# sites/all/libraries/quarks
quarks: /sites/all/libraries/quarks
# The @fermions namespace will point to:
# ../vendor/fermions/fermions
fermions: /../vendor/fermions/fermionsExtending a Twig namespace
If the same Twig namespace is defined by multiple themes and modules, the directories specified by each of those definitions will be added together. When searching for a Twig template, the Components module will search through directories in the following order:
- The directories specified by the active theme. If the active theme specifies a namespace, Drupal will search through the directories in the same order as in the theme's
.info.ymlfile. - The directories specified by the base theme(s) of the active theme. If base themes specify a namespace, each of the directories from each of the base themes will be searched starting with base theme of the active theme and continuing with that base theme's base theme until the no more base themes are specified.
- The directories specified by any module. If a module specifies a namespace, Drupal will search through the directories in the same order as in a module's
.info.ymlfile. - If the namespace is a default namespace of a module, the directories specified by that module are searched last.
Extending a default Twig namespace
Drupal core registers a default Twig namespace for each installed module and active theme; e.g., for the Block module, Drupal registers the @block Twig namespace with the path core/modules/block/templates.
The Components module will allow a theme or module to add additional directory paths to its own default namespace, but not the default namespaces of other modules and themes. This is to prevent accidentally creating a Twig template for your component library that conflicts with the Drupal Twig template of a module. If you attempt to alter a protected default Twig namespace, the Components module will log a warning on Drupal's "Recent log messages" page under: Administration → Reports → Recent log messages.
If you are certain you are not creating conflicting Twig templates, the protective behavior of the Components module can be overridden by doing one of the following:
- the module who owns the default Twig namespace can set the
components.allow_default_namespace_reuseflag totruein its.info.ymlfile. This gives the module the ability to opt-in to allowing the alteration of its default Twig namespace. For example, the Components module allows its@componentsTwig namespace to be altered (since it has no templates of its own); see the components.info.yml file. - any module or theme can use
hook_protected_twig_namespaces_alter()to remove a default Twig namespace from the Components module's list of protected namespaces. See the components.api.php file for more details.
<?php // Place inside your theme's [myTheme].theme file. /** * Implements hook_protected_twig_namespaces_alter(). */ function hook_protected_twig_namespaces_alter(array &$protectedNamespaces) { // Allow the "block" Twig namespace to be altered. unset($protectedNamespaces['block']); }
Dynamically adding/extending Twig namespaces
In Components 3.x, you can dynamically alter the list of namespaces and their paths with hook_components_namespaces_alter. Each active theme has its own unique set of namespaces, based on its base themes and enabled modules. A module or a theme can implement hook_components_namespaces_alter to change the list of namespaces and namespace paths.
function hook_components_namespaces_alter(array &$namespaces, string $theme) {
// Add a new namespace.
$namespaces['new_namespace'] = [
// Paths must be relative to the Drupal root.
'libraries/new-components',
'themes/contrib/zen/new-components',
// Even paths adjacent to the Drupal root will work.
'../vendor/newFangled/new-components',
];
// If you only want to change namespaces for a specific theme the $theme
// parameter has the name of the currently active theme.
if ($theme === 'zen') {
// Append a path to an existing namespace.
$namespaces['components'][] = drupal_get_path('theme', 'zen') . '/components';
}
}
Old API in 8.x-1.x
The following API was used in Components 8.x-1.x and deprecated in Components 8.x-2.x. This API was removed from Components 3.x.
Here's how you would register a "myComponents" component library residing in a myFiles directory of your theme or module. In your .info.yml file, add these lines:
component-libraries:
myComponents:
paths:
- myFiles
Help improve this page
You can:
- Log in, click Edit, and edit this page
- Log in, click Discuss, update the Page status value, and suggest an improvement
- Log in and create a Documentation issue with your suggestion