Skip to main content
drupalreleases

Use direct release data with your AI assistant.

Learn more

Display Builder for Page Manager

No security coverage Under active development

Build Page Manager page variants visually with the Display Builder.

The variant's whole source tree is persisted in the page variant's own
variant_settings, so it travels with the page configuration
(export, duplicate, translation overrides). The dynamic contexts the page
collects at runtime are forwarded to every source, so context-aware sources
(entity fields, tokens, ...) behave consistently on the builder and
front-end paths.

Features

1. The "Display Builder" page variant plugin

DisplayBuilderVariant
(@PageDisplayVariant(id = "display_builder_page_manager"))
implements ContextAwareVariantInterface:

  • The variant settings store profile (the Display Builder
    profile) and sources (the source tree).
  • build() merges the builder-side contexts
    (getRuntimeContexts()) with the
    real request contexts of the page variant (injected by
    page manager through setContexts(), gathered by the
    PageManagerEvents::PAGE_CONTEXT subscribers: current user,
    language, upcast route parameters), real values winning on name
    collisions; every context's cacheability is bubbled to the render result.
  • getWizardOperations() adds the "Display Builder" step to page
    manager's edit wizard (DisplayBuilderForm); both the wizard's
    General step and the variant configuration form carry a
    "Build this variant" shortcut link.

2. The buildable plugin (builder integration)

PageManagerVariant
(@DisplayBuildable(id = "page_manager_variant")) registers a
page variant as a buildable "display":

  • Configuration is storage: the source tree and profile are read from and
    written to page_variant.variant_settings
    (ConfigBuildablePluginBase); saving clears the plugin cache.
  • Instance IDs look like
    page_manager_variant__<variant_id>; hyphens in the
    variant machine name are escaped to DASH so the ID stays a
    valid CSS, JS and HTMX identifier.
  • collectInstances() / collectDisplays() aggregate
    all variants of this type into the builder's instance and display lists;
    getPreviewPagePath() returns the preview path for fixed-path
    pages (NULL for wildcard paths); previews render inside the theme's page
    chrome (previewWithChrome()).
  • Access control: the administer page_manager permission (both
    the legacy static checkAccess() and the beta9
    AccessibleInterface::access()).

3. Dynamic context awareness (the core of this module)

The builder runs on an admin route, so the page's route parameters are not on
the request. getRuntimeContexts() fills the gap in four layers so
that context-aware sources are visible, selectable and configurable in the
builder, while front-end rendering always resolves real values:

  1. Page context collection:
    PageVariant::getContexts() dispatches
    PageManagerEvents::PAGE_CONTEXT, so the static contexts, the
    current user, the language contexts and the route parameter context
    definitions are all in place (route parameter values empty).
  2. Sample entities (fillSampleContexts()): every
    entity:* typed context without a value is stood in by an
    unsaved sample entity from
    ui_patterns.sample_entity_generator, marked by
    DisplayBuilderHelpers::markSampleEntity() so no formatter
    mistakes it for real content. Sample contexts carry max-age: 0.
  3. The names ui_patterns expects
    (aliasEntityContext()): ui_patterns' context-aware sources ask
    for contexts by literal name - [Entity] ➜
    [Field] and friends want one named entity, the
    derived per-field definitions additionally want bundle. Page
    manager names its contexts after route parameters (node,
    current_user), so the entity context of the page's route
    parameter (preferred) or any other non-user entity context is also
    published as entity, together with a bundle
    (string) context.
  4. The access configuration is authoritative
    (accessConditionBundles() / applyConfiguredBundle()):
    the entity_bundle conditions on the page's Access tab declare
    the bundles the page actually serves. The sample entity is generated for
    that bundle, and the bundle context answers with it under an
    AllowedValues constraint - the field lists are thereby narrowed to exactly
    the fields of the served bundle.

Front-end rendering (DisplayBuilderVariant::build()) merges the
real contexts over the builder ones by name, then
stripSampleContexts() removes any sample that leaked through
(value is an unsaved entity, or max-age: 0), and the
entity / bundle aliases are rebuilt from the real
values - a visitor never sees sample content, and when a real request lacks
the route parameter the bound sources fall back to display_builder's
degradation path instead of erroring.

4. Builder UI route

/admin/structure/page-manager/display-builder/{page_variant}
(DisplayBuilderController), requiring the
administer page_manager permission plus view access
on the variant.
hook_display_builder_page_displays() registers "this page's
variant" as the display entry point in the builder.

Dependencies

Module Used for display_builder (>= 1.0.0-beta9) Builder core: buildable plugin system, Instance, Profile, island UI, degradation validation page_manager Page and variant entities, the PAGE_CONTEXT event, the wizard (page_manager_ui optional, the wizard form uses it) ui_patterns Source filtering (SourcePluginManager), SampleEntityGenerator, RequirementsContext, ComponentElementBuilder Drupal ^11.4 PHP 8.3+, hook attributes, the PageDisplayVariant attribute

Install with composer require drupal/display_builder_page_manager and enable it. To use it: pick the "Display Builder" variant plugin on a page variant and select a profile in the wizard step.

Known behaviour

  • Sample entities are never saved: preview values in the
    builder come from unsaved sample entities (uuid-marked); once published,
    the front end reads the real route parameter. When a real request lacks the
    parameter (e.g. an optional one), sources bound to that context render a
    placeholder through display_builder's degradation mechanism and log a
    warning.
  • A static context resolving to nothing is treated the same
    way; bindings resolved in the Context/Access configuration
    (context_mapping) are unaffected.
  • Multiple bundles in one access condition: the sample and
    the published bundle context answer with the first configured bundle (the
    AllowedValues constraint still lists all of them), so the field lists show
    the first bundle's fields. A single bundle context can only answer for one
    value.
  • Preview paths are unavailable for pages whose path is a wildcard
    (getPreviewPagePath() returns NULL).

Ask your assistant about Display Builder for Page Manager

Check compatibility with your Drupal and PHP version, maintenance and security coverage, from current release data. How it works

Depends on

Dependencies of the latest stable release

No dependencies recorded for this project.

Required by

Tracked projects that depend on this one

No tracked projects depend on this one yet.

Activity

Tracked releases
1
Tracked since
Oct 2026
Latest release
1 hour ago
Releases (12 mo)
1 ▲ from 0
Maintenance
Active

Releases

Version Type Core PHP Release date
1.0.0-beta1 Pre-release 11 Oct 28, 2026