Change record status: 
Project: 
Introduced in branch: 
3.x
Introduced in version: 
3.0.0-alpha1
Description: 

Custom elements can be output according to a layout defined with Drupal's Layout Builder; e.g. JSON output would look roughly like:

  "content": {
    "element": "node",
    "type": "NODE-TYPE",
    "sections": [
      {
        "element": "layout-section",
        "layout": "layout_onecol",
        "settings": {
          "label": "",
          "width": "regular"
        },
        "content": [
  ( ... content of blocks in a layout section, possibly followed by more sections ... )

In version 2, it was possible to add extra attributes to this output.

Reason: the code to decide whether a layout would be used, was inside the DefaultContentEntityProcessor class, which could be subclassed like e.g.:

class MyProcessor extends extends DefaultContentEntityProcessor {

  /**
   * {@inheritdoc}
   */
  public function supports($data, $viewMode) {
    return ....;
  }

  /**
   * {@inheritdoc}
   */
  public function addtoElement($node, CustomElement $element, $viewMode) {
    // Build a custom element according to a layout (because Layout Builder is
    // enabled on the corresponding entity view display).
    parent::addtoElement($node, $element, $viewMode);
    // Add extra attribute
    $element->setAttribute('extraAttribute', ATTRIBUTE_VALUE);
  }

}

In version 3, the decision to use a layout has been moved from DefaultContentEntityProcessor into the CustomElementsGenerator class (which preempts / is responsible for choosing which processors to use). Now, it is only possible to use either a layout, or processors / "automatic processing". So the above does not work anymore.

The currently available solutions are:

1. Work on #3470343: Move layout builder code into processor service which moves the layout-building code back into a processor. Then extend that processor instead.

2. Create a Custom Elements display that has "Use Layout Builder" enabled. Then set the attributes in an alter hook instead, e.g.:

/**
 * Implements hook_custom_element_entity_alter().
 */
function mymodule_custom_element_entity_alter(CustomElement $element, EntityInterface $entity, string $viewMode): void {
  if (this_is_my_element()) {
      // This element was built using Layout Builder settings (not a processor
      // or CE display), so it could not have custom attributes added in
      // another way.
    $element->setAttribute('extraAttribute', ATTRIBUTE_VALUE);
  }
}
Impacts: 
Module developers