[1.0.0-alpha2]Β Add content display overrides

Created on 9 June 2025, 3 months ago

Problem/Motivation

Now we have a:

  • a (WIP) entity view display integration in display_builder_entity_view
  • an experimental ui_patterns_field sub-module in UI Patterns 2

We can start working on content display overrides

Proposed resolution

Implement it like layout builder. With a "Display" tabs, instead of a "Layout" tab, in the entity edit tabs.

Locked / unlocked sub trees

Can we implement a layout_builder_lock β†’ like mechanism?

Layout Builder Lock allows administrators to lock sections of a default layout so users can't perform certain actions when overriding the layout for an individual entity.

Because we work on tree structure instead of flat sections, it is best described β†’ like that:

the ability to lock/unlock slots and component subtrees allows the Site Builder to define the creative freedom of the Content Creator on a per-content type basis, which is another way of saying: controlling how rigid/consistent/enforced the layouts are.

It may be a new "special" State property of the display builder, alongside _instance_id & _third_party_settings.

Translation

What do we decide?

  • Symmetric translations: The translations have the same state data tree, but some values (mostly strings…) need to be translated.
  • Asymmetric translations: The translations can have different data trees. The simpler solution.

Anyway, translations mechanisms must be implemented and managed at StateManager level and be the same for content display overrides and other translations uses cases (config translation of displays, of views...)

An override by display?

Layout Builder is allowing only the override of default display. I beleive Experience builder has not reached the moment they need to thing about that yet.

What do we do?

Restrictions

No need for a mechanism like layout_builder_restrictions β†’ or layout_builder_restrictions_by_role β†’ because it will be managed by the intersection between:

πŸ“Œ Task
Status

Active

Version

1.0

Component

display_builder_entity_view

Created by

πŸ‡«πŸ‡·France pdureau Paris

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

Merge Requests

Comments & Activities

  • Issue created by @pdureau
  • πŸ‡«πŸ‡·France pdureau Paris
  • πŸ‡«πŸ‡·France pdureau Paris
  • πŸ‡«πŸ‡·France pdureau Paris
  • πŸ‡«πŸ‡·France pdureau Paris

    You may need the Content context planned for UI Patterns2: ✨ [2.1.0] Add a ContentBlock source for slots with a Content entity context Active
    Also discussed in πŸ“Œ Align source contexts Active

  • πŸ‡«πŸ‡·France pdureau Paris

    Discussed with just_like_good_vibes:

    Override a full display

    we can override any display (not only the default one like Layout Builder), where do we put the information than this field override this display ?

    We store this information in the ui_patterns_source field instance config, so not in the content. So, it is up to the site builder to decide this.

    However, how do we know if the field is effectively used for override by the contributor?

    • If we rely on ListInterface::isEmpty(), how do we know for sure an empty ui_patterns_source field will empty the overridden display or will do nothing?
    • Do we add a new boolean field property in ui_patterns_source to tell if the field is used for override or not?

    None of those options is OK for just_like_good_vibes but the debate is ongoing.

    About tabs: instead of "Displays" with a sub-tab for each display, do we flat the list with "Display: Card", "Display: Full"... ?

    Use your content field in a slot

    How the widget will be rendered in entity form display? An iframe in order to get the front theme in the admin theme?

    A link to a display builder page, like in Display Builder Views.

  • πŸ‡«πŸ‡·France pdureau Paris

    However, how do we know if the field is effectively used for override by the contributor?

    I would prefer to rely on ListInterface::isEmpty() because i don't see the

    When we will be decided, the scope of this issue may be only:

    • a new display_builder field widget plugin for ui_patterns_source
    • a new override optional string enum setting in ui_patterns_source instance or storage
    • a mechanism to generate automatically tabs in content view/edit/delete tabs

    however, what is happening if 2 fields are override the same display?

    Oops! We need to address this too :) Christian prefer to store the link between a display and a display_builder field in the entity view display config entity instead on the ui_patterns_source instance or storage

    So, if we do that, we will need:

    • a new display_builder field widget plugin for ui_patterns_source
    • a new overriden_by optional string enum setting in entity view display config entity
    • a mechanism to generate automatically tabs in content view/edit/delete tabs
  • πŸ‡«πŸ‡·France pdureau Paris
  • πŸ‡«πŸ‡·France pdureau Paris
  • πŸ‡©πŸ‡ͺGermany Christian.wiedemann

    christian.wiedemann β†’ made their first commit to this issue’s fork.

  • Pipeline finished with Failed
    19 days ago
    Total: 214s
    #565207
  • πŸ‡©πŸ‡ͺGermany Christian.wiedemann

    I created a first draft. Lets discuss tommorow.

  • Pipeline finished with Failed
    19 days ago
    Total: 145s
    #565211
  • πŸ‡«πŸ‡·France Grimreaper France πŸ‡«πŸ‡·

    Hi Christian,

    Thanks for the first draft.

    Quickly looking, I think we need to introduce interface, like in Layout Builder LayoutBuilderOverridableInterface.

    Can we merge ✨ Remove Layout Builder dependency Active before this one please?

  • πŸ‡«πŸ‡·France pdureau Paris

    Christian,

    Can you name your context requirement simply "content" (instead of "display_builder_entity_view_override") in order to be ready for πŸ“Œ Align source contexts Active  and ✨ [2.1.0] Add a ContentBlock source for slots with a Content entity context Active ? And also (it is related) add the same requirement to ContentEntitySource so the source plugin will only be visible in entity view display overrides?

  • πŸ‡«πŸ‡·France pdureau Paris

    When finished, assign the issue to me. I will add the updated documentation before sending it to review.

  • πŸ‡«πŸ‡·France pdureau Paris

    Let's not forget this:

    Can we implement a layout_builder_lock β†’ like mechanism? Layout Builder Lock allows administrators to lock sections of a default layout so users can't perform certain actions when overriding the layout for an individual entity.

    Because we work on tree structure instead of flat sections, it is best described β†’ like "the ability to lock/unlock slots and component subtrees allows the Site Builder to define the creative freedom of the Content Creator on a per-content type basis, which is another way of saying: controlling how rigid/consistent/enforced the layouts are."

    It may be a new "special" State property of the display builder, alongside _instance_id & _third_party_settings.

    It may not be part of the current MR, we can create a follow-up ticket to deal with that. However, let's make it sure we are not blocking it here

  • πŸ‡«πŸ‡·France pdureau Paris

    Some parts of the initial goal were moved to beta: πŸ“Œ Allow override of displays not build with display builder Active

  • Pipeline finished with Failed
    15 days ago
    Total: 146s
    #568471
  • Pipeline finished with Failed
    15 days ago
    #568621
  • Pipeline finished with Failed
    14 days ago
    Total: 272s
    #568910
  • Pipeline finished with Failed
    14 days ago
    Total: 2916s
    #568911
  • Pipeline finished with Failed
    14 days ago
    Total: 335s
    #568928
  • Pipeline finished with Failed
    14 days ago
    Total: 3698s
    #568940
  • Assigned to Christian.wiedemann
  • Status changed to Needs work 14 days ago
  • πŸ‡«πŸ‡·France Grimreaper France πŸ‡«πŸ‡·
  • Pipeline finished with Canceled
    14 days ago
    Total: 81s
    #569288
  • Pipeline finished with Canceled
    14 days ago
    Total: 31s
    #569289
  • πŸ‡«πŸ‡·France Grimreaper France πŸ‡«πŸ‡·

    Rebased and code slightly improved with proper dependency injection on https://git.drupalcode.org/project/display_builder/-/merge_requests/66

    Not tested.

  • Pipeline finished with Failed
    14 days ago
    Total: 294s
    #569306
  • Pipeline finished with Failed
    13 days ago
    #569750
  • Pipeline finished with Failed
    13 days ago
    #569775
  • Pipeline finished with Success
    13 days ago
    #569808
  • Pipeline finished with Success
    13 days ago
    #569833
  • Pipeline finished with Failed
    13 days ago
    Total: 142s
    #570222
  • Pipeline finished with Failed
    13 days ago
    Total: 168s
    #570296
  • Pipeline finished with Success
    13 days ago
    Total: 144s
    #570299
  • Pipeline finished with Success
    13 days ago
    Total: 140s
    #570324
  • πŸ‡«πŸ‡·France pdureau Paris
  • πŸ‡«πŸ‡·France pdureau Paris

    I have updated the documentation and the wording of the two forms to make it more inline with Drupal Core "standard":

    • Imperative wording instead of casual
    • No "click here" link
    • A button to load the display builder

    https://git.drupalcode.org/project/display_builder/-/merge_requests/62/d...

    I will update again the documentation when the review will be OK.

    So, the review.

    Set the override:

    • ⚠️ When I add a source field from the modal or from Feild UI, I have this error: "Text format field is required.". I need to set a default value as a workaround change the WYSIWYG format and uncheck the default. If I forget to uncheck, the override is init from this default value instead of the entity view display.
    • ❌ The UI Patterns Source field is visible in Entity Form Display by default and it is preventing the content edit form to be submitted
    • βœ… It is not possible to pick the same field in many displays

    Use the override:

    • βœ… I see the tab(s) with "@display display"
    • ❌ However, there seems to be in random order. For example, I have: View, Edit, Default Display, Delete,Teaser display, Revisions
    • βœ… the override is init with the value of the entity view display
    • ❌ No"Revert" button in State island to revert the content override to the display config, but we can add it in a follow-up issue.
    • βœ… When I empty the override and I remove the default value from the field settings, it is falling back to the entity view display
    • ❌ "content entity" source is avaialble in overrides (which is OK) but also in enttiy view display config

    Advanced use: I have overridden two display (default & teaser) and I put the override field of teaser in the default entity view display:

    • TODO: I will do the test after the previous point are fixed or discarded

    Topics to discuss:

    • Does OVERRIDE_FIELD_PROPERTY constant belongs to ConfigFormBuilderInterface ?
    • What about translation? Have you tested?
    • What about lock mechanism? it is out of the scope of this issue (we need to create a follow-up but we need to be sure we are not blocking anything)
    • What about a default display with both Layout Builder overrides and display builder overrides? Who is winning? Is it the same rules as the entity view display one?
    • Do we need to add messages like Layout builder does: " You are editing the layout template for all Basic page content items. " "You are editing the layout for this Basic page content item. Edit the template for all Basic page content items instead."
  • πŸ‡«πŸ‡·France pdureau Paris

    I will add a second commit with:

    • Remove bundle from URL. Example: from /node/3/display-builder/article/teaser to /node/3/display/teaser
    • Add the list of overrides for each display in Manage display
    • Clean info.yml
  • Pipeline finished with Failed
    11 days ago
    Total: 177s
    #571433
  • πŸ‡«πŸ‡·France pdureau Paris

    Pierre: Little commit to add:

    • Some doc update
    • "edit' in permission
    • Remove the list of overrides
    • (without considering layout builder) Check what happen if you activate override in a entity view display, set a override in a content, and then deactivate override

    Pierre: To move to a follow-up issue

    • The UI Patterns Source field is visible in Entity Form Display by default. Can we disable it by default?
    • No"Revert" button in State island to revert the content override to the display config.
    • What about translation? Have you tested?
    • Do we need to add messages like Layout builder does: " You are editing the layout template for all Basic page content items. " "You are editing the layout for this Basic page content item. Edit the template for all Basic page content items instead."

    Christian: To do in the current issue:

    • Add a destination parameter in the add field modal
    • Tabs seem to be in random order. For example, I have: View, Edit, Default Display, Delete,Teaser display, Revisions >> Maybe having just "Display" tabs and a second row for each display?
    • Embedding a display (teaser) in the other (full/default) with the ui_patterns_field's: Render Source formatter. None of them are overridden: I don't see the teaser
    • Permissions: We add a Profile selector alongside the Field selector (mandatory, so no possible to pick none). If an user has both the entity.edit permission and the permission related to the chosen Profile, it can do the override.
    • The logic in DisplayBuilderSubscriber::onSave() is not clear. Why are there 3 calls to saveSources() >> Maybe a merge error. Need to be fixed. also, we have the same getContextRequirement value in the 2 cases.
    • Play with Layout Builder: activate both for config, both for override. Desactive one, active again, desactive both... You may find bugs to fixes.
  • πŸ‡«πŸ‡·France pdureau Paris
  • πŸ‡«πŸ‡·France pdureau Paris

    Follow-up tickets: πŸ“Œ Improve content display overrides Active  & πŸ“Œ Add "Revert" button in State island Active (and the already existing ✨ [1.0.0-alpha2] Add "content edit" panel Active )

  • Pipeline finished with Failed
    10 days ago
    Total: 272s
    #572424
  • πŸ‡©πŸ‡ͺGermany Christian.wiedemann

    Tabs seem to be in random order. For example, I have: View, Edit, Default Display, Delete,Teaser display, Revisions >> Maybe having just "Display" tabs and a second row for each display?
    >> I moved them under to an extra tab Display. Not sure how to sort type should be used. Maybe there is a weight. Did not investigate it right now.

    Embedding a display (teaser) in the other (full/default) with the ui_patterns_field's: Render Source formatter. None of them are overridden: I don't see the teaser
    >> Not checked right now

    Permissions: We add a Profile selector alongside the Field selector (mandatory, so no possible to pick none). If an user has both the entity.edit permission and the permission related to the chosen Profile, it can do the override.
    >> Add new select field and use it as profile for overriden tabs.
    >> Permissions are check in the custom permission handler

    The logic in DisplayBuilderSubscriber::onSave() is not clear. Why are there 3 calls to saveSources() >> Maybe a merge error. Need to be fixed. also, we have the same getContextRequirement value in the 2 cases.
    >> I removed the last saveSources call.

    Play with Layout Builder: activate both for config, both for override. Desactive one, active again, desactive both... You may find bugs to fixes.
    >> Works now

  • Pipeline finished with Failed
    10 days ago
    #572428
  • πŸ‡©πŸ‡ͺGermany Christian.wiedemann

    I think "display_builder_entity_view/src/EventSubscriber/DisplayBuilderSubscriber.php" is still wrong. Make sense that someone else has on eye on that for review.

  • Pipeline finished with Failed
    10 days ago
    Total: 156s
    #572432
  • πŸ‡«πŸ‡·France pdureau Paris
  • πŸ‡«πŸ‡·France pdureau Paris

    Rechecking what was already OK

    TODO

    Checking the new fixes

    Add a destination parameter in the add field modal

    Was it forgotten?

    Tabs seem to be in random order. For example, I have: View, Edit, Default Display, Delete,Teaser display, Revisions >> Maybe having just "Display" tabs and a second row for each display?
    >> I moved them under to an extra tab Display. Not sure how to sort type should be used. Maybe there is a weight. Did not investigate it right now.

    βœ… the second row of tabs is visible only if there is more than one override.

    βœ… It is in alphabetical order, like in Display Modes and Manage Display pages.

    Embedding a display (teaser) in the other (full/default) with the ui_patterns_field's: Render Source formatter. None of them are overridden: I don't see the teaser
    >> Not checked right now

    TO CHECK

    Permissions: We add a Profile selector alongside the Field selector (mandatory, so no possible to pick none). If an user has both the entity.edit permission and the permission related to the chosen Profile, it can do the override.
    >> Add new select field and use it as profile for overriden tabs.
    >> Permissions are check in the custom permission handler

    I have 2 profiles: default & devel.

    I have set the override profile to "devel" and tested with 3 users:

    • one with the permission of using all display builder profiles and node.edit >> ❌ "Access denied"
    • one with the permission of using only the default profile and node.edit >> ❌ "Access denied"
    • one with the permission of using only the default profile but not node.editβœ… "Access denied"

    The logic in DisplayBuilderSubscriber::onSave() is not clear. Why are there 3 calls to saveSources() >> Maybe a merge error. Need to be fixed. also, we have the same getContextRequirement value in the 2 cases.
    >> I removed the last saveSources call.
    I think "display_builder_entity_view/src/EventSubscriber/DisplayBuilderSubscriber.php" is still wrong. Make sense that someone else has on eye on that for review.

    I will ahve a look.

    Play with Layout Builder: activate both for config, both for override. Desactive one, active again, desactive both... You may find bugs to fixes.
    >> Works now

    Great. Thanks for the check. I will not check again.

  • πŸ‡«πŸ‡·France pdureau Paris

    pdureau β†’ changed the visibility of the branch 3529125-no-more-lb-dependency to hidden.

  • Pipeline finished with Success
    10 days ago
    Total: 146s
    #573283
  • Pipeline finished with Success
    10 days ago
    Total: 171s
    #573287
  • πŸ‡«πŸ‡·France pdureau Paris

    βœ… OK, finally, I did the fix about permissions in https://git.drupalcode.org/project/display_builder/-/merge_requests/73

    Embedding a display (teaser) in the other (full/default) with the ui_patterns_field's: Render Source formatter. None of them are overridden: I don't see the teaser

    Will be moved to a follow-up ticket.

  • πŸ‡«πŸ‡·France pdureau Paris

    Some last checks before review.

  • πŸ‡«πŸ‡·France pdureau Paris

    Hi Jean,

    This issue for review: rebased & cs-fixer executed (except ordered_class_elements on 2 files to not mess with the diff).

    The work will continue in beta with the follow-up issues:

  • πŸ‡«πŸ‡·France pdureau Paris

    pdureau β†’ changed the visibility of the branch 3529125-add-content-display to hidden.

  • πŸ‡«πŸ‡·France mogtofu33

    Thanks for the work, added tests and some minor refactoring.
    We are at the edge of using too much trait instead of abstract or services,this makes reading and tests harder to write, and ide failing completion. To discuss.

Production build 0.71.5 2024