feat: #3588108 Add domain_menu_extras submodule with domain-aware menu plugin manager(s)
Adds a new domain_menu_extras submodule shipping a domain-aware LocalTaskManager so derivers reading overridable configuration (e.g. system.theme.default flowing into the block administration "default theme" tab) don't freeze their result on the first domain that populates the per-language plugin definition cache.
Mechanism
DomainMenuExtrasServiceProvider::alter() swaps plugin.manager.menu.local_task to DomainAwareLocalTaskManager via setClass() + addArgument(@domain.negotiation_context) — inheriting core's argument list keeps the swap resilient to upstream constructor changes. The subclass rebinds the cache backend with a domain-aware key (local_task_plugins:LANGCODE:DOMAIN_ID), falling back to the und sentinel when no domain has been negotiated yet (CLI, install hooks, …).
Why a submodule and not the base module
Cache fragmentation is a real cost (entries multiply by domains actually visited). Sites that don't override per-domain configuration affecting menu task derivers shouldn't pay it. Opt-in via module install makes the trade-off explicit and matches the established domain_extras submodule pattern (domain_config_entity_ui).
The parallel base-module proposal — domain MR !367 / #3588057 — has been closed as won't fix in favour of this submodule.
Scope
LocalTaskManager only. LocalActionManager and ContextualLinkManager key their plugin definition caches the same way and would benefit from the same treatment; deliberately out of scope for v1, follow-up tracking issue welcome.
Test coverage
Kernel test DomainAwareLocalTaskManagerTest — 2 tests / 12 assertions:
testCacheKeyIncludesActiveDomainId— class swap takes effect and the cache key composition flips when the active domain changes (covers a→b transitions).testCacheKeyFallsBackToUndWhenNoDomainIsBound—undsentinel applies for CLI / install-hook contexts where no domain has been negotiated.
Notes
- Module ships zero hooks (just a service provider) — no
#[LegacyHook].moduleboilerplate needed. - Performance trade-off (cache fragmentation, cold-cache miss rate, tag invalidation unchanged) is documented in
docs/domain_menu_extras/index.md.
Closes #3588108