Process #attributes render property

Created on 26 March 2025, 11 days ago

Problem/Motivation

SDC automatically add a \Drupal\Core\Template\Attribute attributes prop in ComponentsTwigExtension::mergeAdditionalRenderContext.

This prop can be used as any "normal" prop:

$element['#props']['attributes'] = $value;

Some existing Drupal mechanisms, in Core & Contrib, expect and leverage this prop. For example, |add_class() Twig filter:

  public function addClass(array $element, ...$classes): array {
    $attributes = new Attribute($element['#attributes'] ?? []);
    $attributes->addClass(...$classes);
    $element['#attributes'] = $attributes->toArray();
    // Make sure element gets rendered again.
    unset($element['#printed']);
    return $element;
  }

However, calling $element['#attributes'] is not currently working with an SDC component, causing unexpected behaviours.

Proposed resolution

Simply move the value of #attributes property to $element["#props"]["attributes"] before the rendering.

You can take inspiration from ComponentElementAlter::processAttributesRenderProperty

  public function processAttributesRenderProperty(array $element): array {
    if (!isset($element["#attributes"])) {
      return $element;
    }
    if (is_a($element["#attributes"], '\Drupal\Core\Template\Attribute')) {
      $element["#attributes"] = $element["#attributes"]->toArray();
    }
    // Like \Drupal\Core\Template\Attribute::merge(), we use
    // NestedArray::mergeDeep().
    // This function is similar to PHP's array_merge_recursive() function, but
    // it handles non-array values differently. When merging values that are
    // not both arrays, the latter value replaces the former rather than
    // merging with it.
    $element["#props"]["attributes"] = NestedArray::mergeDeep(
      $element["#attributes"],
      $element["#props"]["attributes"] ?? []
    );
    return $element;
  }

And add a related test.

API changes

We don't break anything, we just improve compatibility with existing Drupal mechanisms.

Feature request
Status

Active

Version

11.0 🔥

Component

single-directory components

Created by

🇫🇷France pdureau Paris

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

Production build 0.71.5 2024