Display Builder¶
frontend_editing_display_builder makes the action links work on displays managed by
Display Builder.
drush en frontend_editing_display_builder
Dependencies: frontend_editing, display_builder_entity_view, ui_patterns_field_formatters.
Drupal 10 or 11.
Requires Display Builder 1.0.0-beta10 or later
Display Builder 1.0.0-beta10 removed the entity view display classes and interfaces this
sub-module used to detect a Display Builder display (DisplayBuilderEntityDisplayInterface,
isDisplayBuilderEnabled() and isDisplayBuilderOverridable()). It now asks the
entity_view and entity_view_override buildable plugins instead, which earlier releases do
not provide. On an older release the sub-module does not work.
After updating Display Builder, run drush updb: its post-update functions create the
missing Display Builder instances. Kernel tests that save a display with a Display Builder
profile need $this->installEntitySchema('display_builder_instance').
See the change record.
Why it is needed¶
The base module finds fields by scanning the top level of an entity's render array. Display Builder does not leave them there: it rebuilds the array into its own tree of sources, components and slots, so a plain scan finds nothing and no action links attach.
Worse, a field placed through the Display Builder UI is not even built yet at the moment the base module looks. It is a lazy scaffold whose slots are filled later, during rendering.
The sub-module handles both shapes a field can take:
| Shape | When it is built | How it is handled |
|---|---|---|
| A top-level source, a sibling of the components | Eagerly, before the render alter runs | Scanned immediately |
| Nested inside a component's slot, the usual UI result | Lazily, after the render alter has finished | A pre-render callback is inserted into the component's own chain, and runs once the slots exist |
Both paths end in the same code attaching the same action callbacks.
Configuration¶
Nothing beyond the normal three steps. The sub-module reads the Frontend Editing third-party
settings out of the field's field_formatter source in the Display Builder tree, so the settings
are configured exactly as they are for any other display.
The extra field needs somewhere to live¶
Display Builder rebuilds an entity's whole render output from its sources tree, discarding anything
not in it. An extra_field_frontend_editing extra field placed on a Display-Builder-managed
display is discarded with everything else.
That matters because the extra field is what attaches the module's JavaScript. Without it on the page, the links still render but nothing responds: delete does nothing, and add navigates away instead of opening the sidebar.
Put the extra field on a different entity nested in the tree whose own display is not managed by Display Builder. In a typical setup that is the paragraph bundles' own displays. Their build, and the library attached to it, then bubbles up into the page.
If links render but do not react, check this first. It looks like a JavaScript attachment bug, and it is not: the library was never on the page.
Per-content overrides and the builder preview¶
When a display lets each content override it, the action links follow the override. The sub-module reads the Frontend Editing settings from the override's sources tree if the content has one, and from the display's tree otherwise.
While you preview an override in the Display Builder, the preview shows the real page rendered from the unsaved draft. The links follow that draft as well: a field you added, or a setting you changed, shows its actions in the preview before you publish. Outside the preview the saved override is used.
Preview coverage¶
Preview of unsaved values works for entity reference fields, including paragraphs fields, because each referenced entity is rendered through its own view builder and therefore goes through the normal path.
A plain field placed directly on a Display-Builder-managed display, a text summary for example, is not covered. A plain field's rendering never recurses into another entity, so there is no second pass to hook into. If the editing surface is paragraph-based, which is the common case, this gap does not come up.