Content templates, part 2: store a component tree in the template, and allow individual entities to fill in specific slots in that tree

Created on 7 April 2025, about 1 month ago

Overview

Following up from ✨ Content type templates, part 1: introduce a ContentTemplate config entity which always renders an empty component tree for a particular entity display Active , we need the ability for a content template to store a component tree, and to designate certain empty slots therein as "exposed", meaning that they will be filled in at render time by pulling subtrees from a field stored with the individual entity being render.

Proposed resolution

Bring the rest of πŸ“Œ [PoC] Introduce a `ContentTypeTemplate` config entity Active into XB -- the stuff that wasn't in ✨ Content type templates, part 1: introduce a ContentTemplate config entity which always renders an empty component tree for a particular entity display Active :

  • Storing a component tree in the content template
  • Marking certain slots in that tree as exposed slots, which are empty slots that will be filled in by individual entities that use the template

User interface changes

TBD

✨ 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

Merge Requests

Comments & Activities

  • Issue created by @phenaproxima
  • πŸ‡ΊπŸ‡ΈUnited States phenaproxima Massachusetts
  • πŸ‡ΊπŸ‡ΈUnited States phenaproxima Massachusetts
  • πŸ‡ΊπŸ‡ΈUnited States phenaproxima Massachusetts
  • πŸ‡ΊπŸ‡ΈUnited States phenaproxima Massachusetts
  • πŸ‡ΊπŸ‡ΈUnited States phenaproxima Massachusetts

    This is quasi-blocked on ✨ Content templates, part 2: Using the templates for rendering Active , in that I'd rather build on the test coverage being added over there than have to scaffold in wholly new test coverage.

    But, everything else about that can happen now, so I'll start on that tomorrow.

  • Merge request !888Resolve #3517845 "Content templates part" β†’ (Merged) created by phenaproxima
  • Pipeline finished with Failed
    about 1 month ago
    Total: 1496s
    #471412
  • Pipeline finished with Failed
    about 1 month ago
    Total: 1772s
    #471452
  • πŸ‡ΊπŸ‡ΈUnited States phenaproxima Massachusetts

    Wim and I talked about this issue today and we agreed to split it into two issues:

    1. This issue, which will add the exposed slots data structure on the ContentTemplate entity itself, with validation. It won't be used for anything yet.
    2. In another issue, the entity-side storage for what goes into the exposed slots. Wim feels that this should involve making the component_tree field item support infinite cardinality, and adding a nullable slot_name column to it. This is appropriate for a number of future-focused reasons that Wim articulated to me, along with making it much easier to detect if a content creator is about to make a destructive change that will affect exposed slots in extant entities.

    The only work still needed here, I think, is making sure that only the content templates for the full view mode actually allow exposed slots. Hopefully this can be done with some config schema magic, but it might call for a new validation constraint.

  • Pipeline finished with Failed
    28 days ago
    Total: 1651s
    #474280
  • πŸ‡ΊπŸ‡ΈUnited States phenaproxima Massachusetts

    So I cannot use config schema by itself to enforce that exposed slots are only allowed in the full view mode, for a couple of reasons.

    • This is a config entity, which means there's always an exposed_slots property, even if unused. If it's present (which it will be) in content templates in other view modes, those are automatically config schema errors.
    • experience_builder.content_template.*.*.full cannot resolve to a type unless it was also based on some kind of meta-type like experience_builder.content_template.*.*.[view_mode]. There's precedent in core for something like this (editor.schema.yml), but not for config entities.

    The proper path here looks like a validation constraint at the entity level which confirms that exposed_slots is empty in a non-canonical view mode. I think it probably makes more sense to just graft this into the ValidExposedSlot constraint.

  • πŸ‡ΊπŸ‡ΈUnited States phenaproxima Massachusetts
  • Pipeline finished with Failed
    28 days ago
    Total: 1600s
    #474305
  • πŸ‡ΊπŸ‡ΈUnited States phenaproxima Massachusetts

    Opened ✨ Content templates, part 3b: store exposed slot subtrees on individual entities Active for the entity-specific stuff.

  • Pipeline finished with Canceled
    28 days ago
    Total: 300s
    #474322
  • Pipeline finished with Failed
    28 days ago
    Total: 1602s
    #474326
  • πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

    #9 Thanks so much for writing up your research in detail! πŸ‘πŸ™

    • experience_builder.content_template.*.*.full cannot resolve to a type unless it was also based on some kind of meta-type like experience_builder.content_template.*.*.[view_mode]. There's precedent in core for something like this (editor.schema.yml), but not for config entities.

    But Editor is a config entity too, so that does seem fine?

    • This is a config entity, which means there's always an exposed_slots property, even if unused. If it's present (which it will be) in content templates in other view modes, those are automatically config schema errors.

    That's a great point! So given that, the best we can do anyway is to restricted exposed_slots on view modes other than full to the empty array. And we need a validation constraint anyway. So then doing what you did here seems reasonable.

  • πŸ‡ΊπŸ‡ΈUnited States phenaproxima Massachusetts

    But Editor is a config entity too, so that does seem fine?

    Editor uses this pattern for a subset of its values (image_upload.1 and image_upload.0), but the config schema type for the whole entity is not polymorphic.

  • Pipeline finished with Canceled
    27 days ago
    Total: 688s
    #475144
  • Pipeline finished with Failed
    27 days ago
    Total: 1894s
    #475155
  • πŸ‡ΊπŸ‡ΈUnited States phenaproxima Massachusetts

    Two threads are still unresolved, but they need answers from Wim (or someone else knowledgeable). Otherwise this is probably ready, as far as I can tell.

  • Pipeline finished with Failed
    27 days ago
    Total: 1945s
    #475226
  • Pipeline finished with Failed
    27 days ago
    Total: 2879s
    #475266
  • πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

    Not passing tests.

  • πŸ‡ΊπŸ‡ΈUnited States mglaman WI, USA

    nit: "For nodes, that's the full view mode."

    It's not just nodes, technically the canonical view mode is always "full" per the default parameter value of \Drupal\Core\Entity\EntityViewBuilderInterface::view and \Drupal\Core\Entity\EntityViewBuilderInterface::viewMultiple

  • πŸ‡ΊπŸ‡ΈUnited States mglaman WI, USA

    Tests are passing now, validation and test cover looks solid.

  • Pipeline finished with Failed
    27 days ago
    Total: 2723s
    #475324
  • πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

    Looks fantastic!

    The only thing that was inaccurate was the distinction between

    1. the machine name of the component slot that is being exposed (e.g. the "two column" SDC's column_one)
    2. the machine name of the exposed slot itself, i.e. the name being picked by the Content Template author

    which per the example in the config schema are two different things:

              # exposed_slots:
              #  profile_bio:
              #    label: 'Profile Bio!'
              #    component_uuid: 28bcab26-e434-4ad4-9eaf-0520bdb32fcc
              #    slot_name: column_two
    

    πŸ‘† profile_bio is the machine name of the exposed slot, column_two is the name of the component slot.

    I clarified that.

    What added to that confusion is that XB is not yet sufficiently restricting this across ComponentSource plugins, so created πŸ“Œ Constraint slot names allowed by XB in its component tree Active for that!

  • Pipeline finished with Canceled
    26 days ago
    Total: 741s
    #476596
  • πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

    🚒

  • Pipeline finished with Success
    26 days ago
    Total: 1730s
    #476605
  • Pipeline finished with Skipped
    26 days ago
    #476620
  • πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί
  • πŸ‡ͺπŸ‡ΈSpain penyaskito Seville πŸ’ƒ, Spain πŸ‡ͺπŸ‡Έ, UTC+2 πŸ‡ͺπŸ‡Ί
  • πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί
  • Automatically closed - issue fixed for 2 weeks with no activity.

Production build 0.71.5 2024