Skip to content
Snippets Groups Projects

Draft: Resolve #3511366 "Poc content type template config entity type"

Compare and
12 files
+ 812
14
Compare changes
  • Side-by-side
  • Inline
Files
12
@@ -397,6 +397,127 @@ field.field_settings.component_tree:
constraints:
FullyValidatable: ~
experience_builder.content_type_template.*.*.*:
type: config_entity
constraints:
FullyValidatable: ~
mapping:
id:
# This ID intentionally does not use `type: machine_name`, because it is a composite ID that is better validated
# using the `StringParts` constraint than the `RegEx` constraint.
type: string
label: 'ID'
constraints:
StringParts:
separator: .
reservedCharacters:
- ':'
reservedCharactersSubstitute: .
parts:
- '%parent.content_entity_type_id'
- '%parent.content_entity_type_bundle'
- '%parent.content_entity_type_view_mode'
Length:
# @see \Drupal\Core\Config\Entity\ConfigEntityStorage::MAX_ID_LENGTH
max: 166
content_entity_type_id:
type: string
label: 'Content Entity Type ID'
constraints:
PluginExists:
manager: entity_type.manager
interface: Drupal\Core\Entity\ContentEntityInterface
content_entity_type_bundle:
type: string
label: 'Bundle'
constraints:
EntityBundleExists: '%parent.target_entity_type_id'
content_entity_type_view_mode:
type: string
label: 'View mode'
constraints:
# @todo Definitely require the corresponding EntityViewMode config entity to exist. This would require adding support for dynamic values to be specified in the `prefix` option for \Drupal\Core\Config\Plugin\Validation\Constraint\ConfigExistsConstraintValidator, or for XB to subclass it. The latter is the only pragmatic choice that avoids being blocked on core. Note that core's \Drupal\Core\Validation\Plugin\Validation\Constraint\EntityBundleExistsConstraintValidator already supports this.
ConfigExists:
# @see \Drupal\Core\Entity\Entity\EntityViewMode
prefix: core.entity_view_mode.[%parent.content_entity_type_id]
# A single component tree.
component_tree:
constraints:
ComponentTreeMeetRequirements:
# Both StaticPropSource and DynamicPropSources may be used, because this can rely on an entity of a particular
# type and bundle to be present everywhere it is inserted/used.
inputs:
absence:
- adapter
- url-preview
# In fact, it MUST use DynamicPropSources, otherwise it would not be a template for a content entity type:
# it would be presenting static data.
presence:
- dynamic
tree:
absence:
# Components implementing either of these 2 interfaces are only
# allowed to live at the PageRegion level.
# @see \Drupal\experience_builder\Entity\PageRegion
# @see `type: experience_builder.page_region.*`
- Drupal\Core\Block\TitleBlockPluginInterface
- Drupal\Core\Block\MessagesBlockPluginInterface
presence: ~
type: experience_builder.component_tree
label: 'The component tree to present an entity of this content entity type in this view mode.'
# Content type templates for the `default` view mode are special: they're the only ones that are allowed
# to have exposed slots. For example:
# exposed_slots:
# profile_bio:
# label: 'Profile Bio!'
# component_uuid: 28bcab26-e434-4ad4-9eaf-0520bdb32fcc
# slot_name: column_two
# intro:
# label: 'Intro'
# component_uuid: 98bcab26-e434-4ad4-9eaf-0520bdb32fcc
# slot_name: body
experience_builder.content_type_template.*.*.default:
type: experience_builder.content_type_template.*.*.*
constraints:
FullyValidatable: ~
mapping:
exposed_slots:
type: sequence
label: 'Exposed slots'
# Note: this is a sequence ordered by key, because the keys must be the machine names assigned to the
# exposed slots. These machine names are essentially "aliases" for a particular slot of a particular
# component instance in the template's tree.
# @todo Validate that the exposed slots' machine names are, well, valid machine names.
orderby: key
sequence:
# Note: if this sequence is empty, no Content Type Slots are exposed to the Content Creator by the Site Builder
# that crafted this Content Type Template. Consequentially, there would be NOTHING for the end user to do, other
# than entering values in the content entity form under the "Page Data" tab.
type: mapping
mapping:
# The UUID of a component instance that contains the slot which we are exposing. This CANNOT be
# \Drupal\experience_builder\Plugin\DataType\ComponentTreeStructure::ROOT_UUID, because that would mean the
# entire template was being overridden by an individual content entity, which is what our special
# landing page content entity type is meant for.
# @todo Validate that this component exists in the template's tree, and that the slot we're exposing is
# empty in that instance.
component_uuid:
type: uuid
label: 'UUID of the component instance which contains the slot being exposed'
constraints: {}
# The name of the slot that is being exposed. For example, if the component that contains
# this exposed slot is a `two_column` SDC, this could be `column_one`.
# @todo Validate that this slot is actually defined by the component.
slot_name:
type: string
constraints: {}
# A human-readable name for the exposed slot.
label:
type: required_label
label: 'Exposed slot label'
# @todo In the future, we may define per-slot restrictions here for product requirement `17. Restrict nested components`
experience_builder.pattern.*:
type: config_entity
constraints:
Loading