Global Elements: Reusable Content of Blocks - #22448
Merged
Merged
Conversation
A block layout item's contentKey can point to either local inline content or a library element. For shared content, the `isSharedContent` flag is set to `true`.
Critical: - disconnectFromLibrary now sets initial expose for new local content and cleans up resolved variant state entry - Extract #updateExposedState() in entry elements, called from all three observers (hasExpose, isLibraryElement, sharedContentVariantState) to prevent stale unpublished state on library blocks Important: - Guard #fetchLibraryElement against already-resolved elements to prevent redundant server requests - Hoist UmbElementDetailRepository to class field in entry elements to avoid accumulating dead controllers Suggestion: - Fix umb-localize key attributes to use literal keys instead of resolved strings from localize.term()
…rch and output rendering
# Conflicts: # src/Umbraco.Web.UI.Client/src/packages/block/block/context/block-entry.context.ts
- Use DocumentVariantStateModel.DRAFT enum instead of magic string in both block-list and block-grid entry elements - Strip isSharedContent from layout during clipboard write to prevent pasted blocks from incorrectly appearing as library references - Guard #setInitialBlockExpose in disconnectFromLibrary against missing content type structure - Store all element variants and resolve against active variantId for correct multi-culture state display - Add already-resolved guard to #fetchLibraryElement - Add JSDoc on isLibraryElement and sharedContentVariantState observables - Add .trim() to transfer modal name validation
BREAKING: UmbBlockLayoutBaseModel now requires a `key: string` property. Plugin code that creates layout objects without `key` will get a compile error. - Change UmbArrayState identity functions to use `(x) => x.key` - Add `layout` setter on entry elements (list, grid, single, rte) that extracts both layoutKey and contentKey from the layout object - Deprecate `contentKey` setter on entry elements (use `layout` instead) - Add `layoutKey` read-only getter for sorter identity - Add `setLayoutKey()` / `layoutByKey()` / `getLayoutByKey()` methods - Update `transferToLibrary` and `disconnectFromLibrary` to take layoutKey - Update delete operations to find by layout key, only remove shared content/settings/exposes if no other layout references the same contentKey - Migrate grid recursive area operations to use key for identity - Update `unique` observable on entry context to derive from layout key - Generate new key on property value clone - Backwards compat: `setLayouts` assigns `key ??= contentKey` for persisted data without key - Strip `isSharedContent` from clipboard layout clone - Update sorter configs and repeat key functions
- requestTransferToElementLibrary / requestDisconnectFromElementLibrary → requestTransferToExternalContent / requestDisconnectFromExternalContent (manager + entry context + action callers)
- .addAdditionalPath('library') → 'element'
- #resolvedExternalContent / #resolvedExternalContentVariants → #externalContentValues / #externalContentVariants
- elementStateOf → externalContentStateOf
- hrefObservable / validationDataPathObservable → href / validationDataPath (interface + action impls + default kind element)
- _hasExpose → _localExpose (grid, list, single entry elements)
- BlockWorkspaceHasContentConditionConfig / BlockEntryHasSettingsConditionConfig: type alias → interface
- Remove implementation-specific / AI-ish comments from block-entry, block-manager, action files, block-workspace
- Reuse #elementRepository field in requestTransfer/Disconnect; remove local instantiations
- #fetchExternalContent now accepts an array — one call per layout-state update instead of N
- getHref / getValidationDataPath in edit-content/edit-settings actions now resolve via the observable
…s empty-interface rule
|
Azure Static Web Apps: Your stage site is ready! Visit it here: https://victorious-ground-017b08103-22448.westeurope.6.azurestaticapps.net |
|
Azure Static Web Apps: Your stage site is ready! Visit it here: https://orange-sea-0c7411a03-22448.westeurope.6.azurestaticapps.net |
leekelleher
approved these changes
Jun 23, 2026
6 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Part of Global Elements — Phase 2. This adds Reusable Content of Blocks: a block in any Block Editor (Block List, Block Grid, Single Block, and Rich Text blocks) can now reference a shared Element from the Library instead of holding its own local content. Editing the Library Element updates every block that references it.
What you can do
Referenced blocks are visually distinguished from local blocks with a dedicated reference colour.
Behind the scenes
IBlockElementService/BlockElementServiceresolve shared element content.key(distinct fromcontentKey), and block identity is keyed on the layoutkey. This lets the same Element be referenced by multiple layout items unambiguously.Breaking change
UmbBlockLayoutBaseModelnow requires akey: stringproperty. Plugin/extension code that constructs block layout objects directly must supply akey. Persisted data without a key is handled on load (a key is derived from the existingcontentKey).How to test