Problem/Motivation
I'm trying to identify exactly how an entity's layout has been overridden from the default settings set at the entity type display level in the layout builder settings report module (#3202578: Improve Override Report).
So for example suppose you have a content type with the following sections defined in the entity type display settings:
- Label: "Section 9", Layout ID: "onecol", Components: x, y
- Label: "Section 20", Layout ID: "twocol", Components: m, n, o
- Label: "Section 30", Layout ID: "onecol", Components: q, r
Now assume that an individual node overrides that layout such that the layout structure looks like this:
- Label: "Section 10", Layout ID: "onecol", Components: x, y
- Label: "Section 30", Layout ID: "twocol", Components: r, s
- Label: "Section 40", Layout ID: "onecol", Components: z
What I'd like to be able to do is take the above, and automatically produce an output that looks something like this (not exactly this, but just to demonstrate what I'm trying to do):
- Renamed "Section 9" to "Section 10"
- Removed "Section 20" with 3 components
- Components Updated in "Section 30": (Added "s", Removed "q")
- Added "Section 40" with 1 component
But the problem is that there doesn't seem to be a way to clearly identify which sections are which.
LayoutSectionItemList::getSections() produces "a sequentially and numerically keyed array of section objects."
Since it only position-based, it's not immediately obvious whether or not "Section 9" was renamed to "Section 10" or if "Section 9" was removed and "Section 10" was added.
Additionally, since labels are optional, it's not something that can be reliably keyed off of in the first place.
Proposed resolution
- Generate a UUID for each layout section when it gets created (but shouldn't change when a section is updated)
- Add Drupal\layout_builder\Section::getUuid() method that can be used to retrieve the uuid for the respective section.
- Either replace LayoutSectionItemList::getSections() with UUIDs as keys instead of indexes (potential BC break), or create a separate LayoutSectionItemList::getSectionsByUuid() method to get the sections keyed by their uuid instead.
- Write a post_update hook to generate a UUID for all existing layout sections (both entity type displays and entity overrides). Alternatively, instead of an update hook, we could maybe modify the Section::getUuid() to generate one if one doesn't already exist for the respective layout section, but that does require updating layout settings on a getter method, so I'm unsure if that's actually ideal here or not. In either case, there's still no clear way of knowing whether a section had been overridden or not, so presumably, all sections in existing overrides would be considered changed, but I'm personally okay with that.
It's worth pointing out, there is already similar UUID behavior with Drupal\layout_builder\SectionComponent so this doesn't feel too far off from what is already happening elsewhere.
Remaining tasks
- Add a UUID property to the
Section
class. - Determine whether we will also need a weight property.
- Update appropriate calls to
new Section()
to include UUID when appropriate. Write an update hook to add UUID's to existing section instances.No need of update hook because existing sections are also updated see\Drupal\layout_builder\Entity\LayoutBuilderEntityViewDisplayStorage::mapFromStorageRecords()
and\Drupal\layout_builder\Section::fromArray()
- Update demo_umami and test profile config to include UUID's on sections in appropriate
core.entity_view_display.*
files. - Update existing tests where needed.
- Add new test to check UUID is present.
User interface changes
None
API changes
TBD
Data model changes
Sections in config would be an associative array based on a UUID instead of a numerically indexed array:
third_party_settings:
layout_builder:
allow_custom: true
enabled: true
sections:
-
layout_id: onecol
layout_settings:
label: Section 10
components:
b2b52d3d-749f-4ef4-a4f0-dd187ea3a10e:
uuid: b2b52d3d-749f-4ef4-a4f0-dd187ea3a10e
region: body
configuration:
id: some_block
label: 'Some Block'
provider: some_provider
label_display: '0'
context_mapping: { }
additional: { }
weight: 0
third_party_settings: { }
Becomes:
third_party_settings:
layout_builder:
allow_custom: true
enabled: true
sections:
364e88fc-e764-43c8-8273-e89fe355d6d4:
uuid: 364e88fc-e764-43c8-8273-e89fe355d6d4
layout_id: onecol
layout_settings:
label: Section 10
components:
b2b52d3d-749f-4ef4-a4f0-dd187ea3a10e:
uuid: b2b52d3d-749f-4ef4-a4f0-dd187ea3a10e
region: body
configuration:
id: some_block
label: 'Some Block'
provider: some_provider
label_display: '0'
context_mapping: { }
additional: { }
weight: 0
third_party_settings: { }
Release notes snippet
https://www.drupal.org/node/3401886 To allow for predictability in config comparison operations, UUID and weight properties have been added to the Layout Builder sections.