Content templates, the boss battle: create a UI for editing templates

Created on 9 April 2025, 12 days ago

Overview

This is the final part of 📌 [PoC] Introduce a `ContentTypeTemplate` config entity Active . Once content templates are a thing, and are used for rendering, and support exposed slots, how do we tie this all together in the XB UI?

Proposed resolution

Quoting from #3518013-12: Content templates, part 2: Using the templates for rendering , which arose from discussion with Callum and Lauri:

  • Visiting the node type's "Manage display" page will always kick you into XB.
  • If there is no existing template for the canonical view mode (which we can currently assume is either full or default), you see an error-like page that prompts you create a template for that view mode. If there is an extant template for the canonical view mode, that'll be the one you're editing by default.
  • The other enabled view modes (e.g. RSS, Search index, etc.) are visible in the sidebar, under "Templates". If you click on any of those, you'll be creating (or editing) a content template for that view mode.

So, to summarize: when you opt a node type into XB, you manage the displays for that node type in XB only.

User interface changes

We need to implement the following in and around the XB UI:

  • Hijacking the "Manage display" local task so that it takes you into the XB UI for opted-in content entity bundles/view modes.
  • The Templates list in the XB UI sidebar, which is really just a list of view modes.
  • The error-like page that you see if you're looking a view mode for which no template exists.
  • Ensuring that the XB UI can load and save templates correctly.

We can maybe punt exposed slots to another issue, but I'm not sure about that yet.

Feature request
Status

Active

Version

0.0

Component

Theme builder

Created by

🇺🇸United States phenaproxima Massachusetts

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

Comments & Activities

  • Issue created by @phenaproxima
  • 🇺🇸United States phenaproxima Massachusetts
  • 🇺🇸United States phenaproxima Massachusetts
  • 🇺🇸United States phenaproxima Massachusetts
  • 🇧🇪Belgium wim leers Ghent 🇧🇪🇪🇺

    I think this issue summary is too broad to be actionable. Starting smaller would make this more actionable.

    I'd descope:

    • The Templates list in the XB UI sidebar, which is really just a list of view modes.

    … because that requires significant client-side work.

    Restricting the scope to everything else means you only need to touch /src (aka PHP code) and not /ui (aka JS code).

    Because then to make an existing ContentTemplate visible, you'd

    1. update the experience_builder.experience_builder route’s controller (path: '/xb/{entity_type}/{entity}') to support receiving a ContentTemplate config entity
    2. … and then update LayoutController::get() and ::post() to treat them the same as a content entity’s XB component tree field (which you made easy in 🐛 Create a centralized service to handle loading component trees Active ! :D)

    Result: the XB UI (thanks to docs/adr/0005-Keep-the-front-end-simple.md! 🤩) will happily load the component tree stored in the ContentTemplate: both the canvas and the panel on the left will render! Clicking a component instance will show the component instance form on the right!

  • 🇧🇪Belgium wim leers Ghent 🇧🇪🇪🇺

    In addition to the tighter scope proposed in #5:

    1. I'd also descope the "connecting of component instances' explicit inputs" to structured data using DynamicPropSources.
    2. I'd even descope being able to render the component instance form for a component with >=1 explicit input populated by a DynamicPropSource (which is required for it to be valid per Content type templates, part 1: introduce a ContentTemplate config entity which always renders an empty component tree for a particular entity display Active !).

    Then both of those can be done in a separate issue. Note that /xb/api/config/component has been providing the necessary information for picking a matching DynamicPropSource for an explicit input of a component instance already exists: /xb/api/config/component provides it!
    See \Drupal\Tests\experience_builder\Functional\PropSourceEndpointTest::getExpected() for the test coverage proving it works — for example for the all_props SDC's test_string_format_email and test_string_html_block props, it automatically finds/matches/suggests:

          'sdc.sdc_test_all_props.all-props' => [
            'id' => 'sdc.sdc_test_all_props.all-props',
            'dynamic_prop_source_candidates' => [
              …
              'test_string_format_email' => [
                "This Article's Revision user" => 'ℹ︎␜entity:node:article␝revision_uid␞␟entity␜␜entity:user␝mail␞␟value',
                "This Article's Authored by" => 'ℹ︎␜entity:node:article␝uid␞␟entity␜␜entity:user␝mail␞␟value',
              ],
              …
              'test_string_html_block' => [
                "Subset of this Article's Body: processed (1 of 5 props — absent: value, format, summary, summary_processed)" => 'ℹ︎␜entity:node:article␝body␞␟processed',
                "Subset of this Article's Body: summary_processed (1 of 5 props — absent: value, format, processed, summary)" => 'ℹ︎␜entity:node:article␝body␞␟summary_processed',
                "This Article's Tags" => 'ℹ︎␜entity:node:article␝field_tags␞␟entity␜␜entity:taxonomy_term␝description␞␟processed',
              ],
    …
    

    That information was added to that API at a time (>6 months ago!) where it seemed that we'd be allowing Content Creators to use structured data in the component instances they're placing. But Product + Design's thinking has evolved ( 📌 Tighten validation: only allow StaticPropSource in XB fields + PageTemplate, DynamicPropSource in ContentTypeTemplate Active ) since then; and we're only going to allow structured data (so: DynamicPropSources) to be used on ContentTemplates.

    (That wasn't mentioned here, but I don't see an issue for it yet either. And it's critical.)

  • 🇺🇸United States phenaproxima Massachusetts
  • 🇺🇸United States phenaproxima Massachusetts
  • 🇺🇸United States phenaproxima Massachusetts
  • 🇺🇸United States mglaman WI, USA

    ++ to "The full view mode is created if it doesn't exist."

    In Drupal Commerce we didn't implement this properly. We ship "default" view mode and displays for products. So this will self-heal/fix contrib or userland code.

  • 🇧🇪Belgium wim leers Ghent 🇧🇪🇪🇺

    🐛 Component trees with dynamic prop sources that introspect field values don't add the relevant fields to their dependencies Active should happen before we allow users creating ContentTemplates in the UI 🙏

Production build 0.71.5 2024