Problem/Motivation
So \Drupal\Core\Theme\ThemeManager::render() provides the ability to convert 'attributes', 'title_attributes', 'content_attributes' variables into Attribute objects before they get passed into the Twig template:
if (!isset($default_attributes)) {
$default_attributes = new Attribute();
}
foreach ([
'attributes',
'title_attributes',
'content_attributes',
] as $key) {
if (isset($variables[$key]) && !$variables[$key] instanceof Attribute) {
if ($variables[$key]) {
$variables[$key] = new Attribute($variables[$key]);
}
else {
// Create empty attributes.
$variables[$key] = clone $default_attributes;
}
}
}
I'm finding that as I create custom render elements and templates for an organization's design system integration in Drupal, I commonly have a need for additional variables in my templates to be converted from an array to an Attribute object for use in Twig. Right now I have to do this myself:
/**
* Implements hook_theme().
*/
function design_system_theme($existing, $type, $theme, $path) {
return [
'design_system_content_teaser' => [
'render element' => 'element',
'variables' => [
'attributes' => [],
'heading' => NULL,
'heading_attributes' => [],
'intro' => NULL,
'button' => [],
],
],
];
}
/**
* Preprocess variables for design system content teaser templates.
*/
function template_preprocess_design_system_content_teaser(array &$variables) {
$variables['heading_attributes'] = new Attribute($variables['heading_attributes']);
}
Proposed resolution
I think there are two options:
- Automatically convert any variable that ends in _attributes in \Drupal\Core\Theme\ThemeManager::render() to an Attribute object. I think this has backwards-compatibility concerns.
- Allow the hook_theme() definition to provide a list of attribute variables that \Drupal\Core\Theme\ThemeManager::render() will convert to an Attribute object.
function design_system_theme($existing, $type, $theme, $path) {
return [
'design_system_content_teaser' => [
'render element' => 'element',
'variables' => [
'attributes' => [],
'heading' => NULL,
'heading_attributes' => [],
'intro' => NULL,
'button' => [],
],
'attribute variables' => [
'heading_attributes',
],
],
];
}
Remaining tasks
User interface changes
None
API changes
This would be a feature-addition to hook_theme().
Data model changes
Release notes snippet