Problem/Motivation
SDCs should be able to limit what components are allowed within its respective slots.
An example use case of this is that an accordion_group component should only allow an accordion_item component in it's main slot.
Similar use cases are tab groups and tab items, or a card carousel and a card.
We also need to ensure this works if the replaces key is being used where a theme replaces a module's component with its own.
Note that this is a vital use case for Canvas which is due Q4 this year.
Steps to reproduce
Proposed resolution
Add 3 new optional keywords in each SDC slot definition:
expectedwith a list of values: SDC plugin IDs (if they have a colon inside) or tags/groups (if no colon inside)minItemsandmaxItemswith a strictly positive integer value: Enforce a lower/maximum limit on the number of children
These will not get enforced on the render API / SDC level. It is up to the display building tool (display_builder, canvas...) to decide how strict it will be considering these.
Remaining tasks
User interface changes
Introduced terminology
API changes
Data model changes
Release notes snippet
| Comment | File | Size | Author |
|---|---|---|---|
| #85 | party-parrot.gif | 278.29 KB | mherchel |
Issue fork drupal-3514072
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
pdureau commentedThanks a lot Mike for this issue which will make a lot of people happy.
Instead of " are allowed" i would say "are suggested" because it would be a mistake for display building tools to strictly enforce this:
So, it is up to the display building too to decide how strict it will be considering this suggestion, but from a SDC point of view it is only a suggestion.
So, an early proposal with an example similar to yours, Bootstrap's accordion:
Example with DaisyUI's Card:
What do you think?
Comment #3
mherchelIt really depends on how XB and equivalents implement the UI.
I want XB to 100% limit
accordion_groupto only acceptaccordion_itemSDCs. The keysuggestedseems somewhat weak for this action.It also might be worth exploring whether we can limit an SDC to only appear in a specific slot of a specific SDC. A use case of this is that I don't want my end user to be able to place an
accordion_itemin the main content area. It only works when placed inside ofaccordion_groupComment #4
pdureau commentedJust a side-note: Let's not implement this fetaure only to please some specific display builders. Let's do it the better way from a SDC point of view, and the display building tools will be able to add features upon it.
Maybe we need different keys:
suggested: for the DaisyUI card example.enforced: for the Carousel exampleSo, let's see how a display building tool can handle those:
Interesting path to explore indeed:
enforced? So no need to add a new keyword?Let's be careful with any restriction we would add. For example, if the design system is expanded by a distinct team with new components, and one of the also want to use
accordion_itemin of those slots, we need to allow that.Comment #5
larowlanComment #6
quietone commentedComment #7
nod_I agree with pdureau that at the SDC level there shouldn't be any restriction on what can go in a slot. The HTML spec does not have any restrictions apart from the content of the slot being valid HTML. If we're starting to Drupalify the term "slot" by adding some implicit features, we might have a bad time later on.
The restrictions should be declared/implemented at a higher level. I like the idea of "suggested", because there is no code beside a new optional key in the yaml to support that. It's up to display builders to treat that as they want. XB could even take "suggested" key from yaml and make that "required" in the UI and adding the validation code there, nothing holding that up.
Comment #8
effulgentsia commentedI don't think that specifying rules for which components can go into which slots is about Drupalifying, I think it's about encoding the rules of a design system. If you're building a design system for broad consumption, like Bootstrap, DaisyUI, etc., then you probably don't want to be overly prescriptive, and instead leave as much creative freedom to put almost any component into almost any slot as possible to the users of the design system. However, what if you're building a design system for a single customer, such as a university (or any other type of organization with different units within it), and that university wants every department's website to have some creative freedom, but also stay on brand? So even though functionally you could put any component into any slot, because after all, it's all just HTML, the creator of this type of design system wants to impose some rules. Where should those rules be encoded? It could be in Drupal config entities, but I don't think these are Drupal-related rules, they are an aspect of the design system. Should they be in the SDC's YAML files? Or at some other level, but if some other level, what is that level?
Comment #9
nod_Yes that was not clear on my part, let me try to be clearer :)
SDC is not the right level because we would still want the design system rules to be applied when the component is overridden (I assume). And overriding a component just to change the rules for a slot in a yaml file is going to be a nightmare, now you own the whole component just to change a couple of YAML lines, how do you make sure it's updated? now the design system allows something else in that slot, how does it work with your overridden component? do you have one component by website if the rules are different? All these problems can go away if we work at a higher level, the declaration and enforcement of the restrictions should be at a higher level.
Declaring the restrictions at the theme level could work. IF at the theme level there is nothing that require changing a file on the filesystem to change the rules. We could have a file that declare the "default" restrictions but it's imported once or in an update hook and the file is not used at runtime. We want themes to be reusable so the rules should be easy to change by site builders without the need to deploy anything (designers will be happy about that too).
The way I see it at the moment is that restrictions should be tied to the website itself (maybe having a companion module for design system themes would be a good idea?) with the basic restrictions for reuse. If it's in a config entity we could even implement some of the rules though ECA, or let people alter them "easily" with ECA when necessary. Also we need to keep in mind all of this should be theme dependent, if you switch theme the restrictions should not apply anymore.
Not sure where the actual enforcement of the rules should happen (or if it should happen at all). I'm of the opinion that we need to let people do whatever if they access this from the code/render arrays directly, so enforcing would be only at the UI level in the various display builders interfaces. I don't think we should have code that check if this component is allowed in that slot at render time. That would mean only showing/hiding things in the display builder interface where/when necessary.
I'm just seeing a lot of complexity for a feature that will get in the way of the ambitious site builder (which is our focus, or marketers in the case of Drupal CMS) or, as Pierre said in #2, developers that need to implement a business requirement that doesn't follow design system rules but that was greenlit despite the Design team's opinion.
Comment #10
mherchelI agree with this.
This functionality would radically simplify the page building experience for site builders / content editors / marketers by removing a significant amount of cognitive load, and removing the need for custom documentation.
I'm personally indifferent if the suggestions/restrictions are created at the SDC or in config, just as long as it's possible for the theme to ship the suggestions/restrictions.
Comment #11
nod_Sounds good, the complexity I'm worried about is if we try to enforce this at render time. Having a way to filter the elements in the UI is good I agree.
Comment #13
wim leersClosed #3493078: per-slot tag/category-based restrictions in favor of this one 😊 Crediting @gryffinh
Comment #14
luke.leberI would second the notion of not enforcing this at the SDC layer due to inherent limitations. I can think up a couple of scenarios where having access to the entire working render tree may be beneficial to effectively enforcing design expectations.
Layout builder restrictions offers an API that does offer quite a bit of additional context in ways that make non-trivial business logic able to be enforced. The "in the weeds" bits here are quite niche in nature, and will likely vary from design system to design system. Is providing an API for restriction management / XB tree validation on the table?
Comment #15
g4mbiniFollowing #03 @mherchel I have a counter-example for accordion.
In DaisyUI accordion component expects collapse components. But the collapse component could be use individually :)
BTW +1 in favor of an
enforced:AND/ORsuggested:mechanism(s) as it is often requested by end-users.Comment #16
wim leersBased on the issue summary and #2, this is really about the tight coupling between 2 or more specific components. IOW: it's about compatibility, not semantics/purpose?
@nod_ in #7:
But a
<ul>can only contain a<li>, a<dl>can contain only<dt>s and<dd>s, etc.This discussion so far makes me think we're reinventing DTDs?! 😅 The HTML DTD defines exactly this: the DL element in the DTD allows specific elements as children, while the P element in the DTD allows any inline element and text nodes.
@nod_ in #9:
+1
Comment #17
wim leersAs alluded to in #16, I think this issue is conflating two fairly different needs.
XB Product Lead @lauriii has always indicated that for XB, it should be tag/group/category-based (hence #3493078: per-slot tag/category-based restrictions's title), not about specific SDCs. AFAIK he's been mostly thinking about design choices. So … I don't think the proposals so far scale to that? 🫣
Can we learn from DTDs? The HTML DTD kind of has two "tags/categories":
inline elementsandblock elements. What if SDCs would be able to define slot restrictions using those 2, but would be able to define additional ones, relevant for the theme's design system?Comment #18
larowlanHere's a concrete example use-case - https://www.previousnext.com.au/blog/creating-cards-section-layout-builder
A 'cards' component that has a slot for cards and props for title, intro text and read more link.
You want to prevent adding anything other than card-like components into the slot.
Comment #19
effulgentsia commentedTrying to synthesize all the comments here, here's a proposal. I hope the terminology is clear enough to convey the concepts, but we can refine the terminology as needed.
Within the SDC's YML, we introduce two new top-level keys (i.e., information about the component):
istraitsAnd for each slot, we also introduce two keys:
slottedtraitsAnd we define a set of traits. This can grow over time, but to give some examples:
widthluminanceAn example of what an
accordion_groupcomponent might look like:An example of what an
accordion_itemcomponent might look like:Traits, at the component level, or at the slot level, can also be conditional on the values of enum and boolean props. For example:
Trait values descend. Meaning, if a slot doesn't specify a trait, it inherits the value from its component. If a component doesn't specify a trait, it inherits the value from the slot that it's in.
All of the above is info that's in the SDC's YAML. In addition, we define a Drupal config entity type that can store policies. Themes (or modules, recipes, etc.) can include these policies within their
config/installdirectory, just like any other default config. Exact syntax for these policies TBD, but for example, there could be:isand the slot'sslotted.Policies can be enabled/disabled, and they're only applied by builder tools (e.g., Experience Builder), not when rendering.
What do you all think? Is this a reasonable partitioning of concerns?
Comment #20
nod_I'm missing some infos somewhere because I do not know how we went from "restrict what's in a slot", to "let's add simple suggestions for the UI" to a whole new YAML condition API. I think I missed some IRL discussions somewhere. The terminology is confusing me too, at first I was wondering if the comment was on the right issue :p
I like the "policies" config idea.
I do not understand why the slot restrictions/conditions are in the SDC definition. @Wim talked about DTDs, huge fan, it's in a separate file that's specially made for that. Anything beyond "suggested" (and even that is arguably not at the right place) doesn't belong on the SDC layer for me, especially now that we agree this is a UI concern, not a technical (as in render-time validation) concern.
Additionally I'm thinking that adding all this at the slot level in SDC will make it very hard share SDCs across themes/modules. We'd need to have dependencies on other components to make it work. Not having this inter-components dependency mechanism is a feature, not a bug.
Comment #21
luke.leberI think the proposal in #19 is a rational start, but am slightly concerned that not all business rules can be represented in YML fashion.
I'm still of the mind that power users will require some degree of programmatic interface to check all the boxes that are presently fulfilled by things like LB Restrictions.
Whether these traits exist on the SDC or in a parallel XB-only configuration is the question.
This is a great point. I do rather struggle to see how SDC's would be able to be mixed and matched across different themes in ways that wouldn't end up "looking weird" from a branding perspective though. My mind immediately went to an example like "I'd like a header from Princeton's design system, a footer from Harvard's, and accordions from Yale's -- which would result in a very odd looking thing from a branding perspective.
Are there any concrete use cases for wanting to mix and match SDC's across different themes? Typically I'd think that there wouldn't be the desire for design systems to be arbitrarily mixed and matched in that fashion.
Comment #22
nod_WordPress core defines about 90+ components that are reused and customized though classes and some custom API. They have more than a 100 fully "block themes" that are build on those (few themes define their own components, they mostly reuse the core ones to build pages) and since they consider their "hybrid themes" as block theme they're announcing more than a thousand block themes available, all built on those core components. It works for them and we don't have a radically different needs (XB has a lot in commun with gutenberg: problem space, technologies) so it'd work for us.
Closer to home, we have the navigation module that provides a "badge" SDC, no reason it couldn't be a global SDC that core and contrib can use. The goal is for core to move to SDC as a step to simplify the render API, see #2702061-106: Unify & simplify render & theme system: component-based rendering (enables pattern library, style guides, interface previews, client-side re-rendering).
It's not about a header from this and a footer from that, it's lower level. Like a card component, buttons it's always mostly the same. So yes, reusable SDC is definitely something that is necessary.
Comment #23
nod_Changing title and component because it's about the UI, not about the capabilities of SDC themselves
Comment #24
effulgentsia commentedMaybe, but not in relation to comment #19. My proposal in that comment came directly from reading this issue's comments.
The issue summary gives the example of an accordion_group component containing a slot into which only accordion_item components make sense to be slotted. The IS also points out that the concept of an accordion_item isn't unique to just one SDC: you can have multiple SDCs (e.g., one from a module, one from a theme) that are all accordion items. #18 provides a similar use case of 'cards', but is even more explicit about the concept that multiple SDCs can be "card-like". I think #19's suggestion of
isandslottedaddresses those use cases: a components can identify what itis, and a slot can identify what kind ofslottedcontent it's designed for.That addresses the direct slot/slotted relationship, but comment #14 mentions additional use cases of context that should affect more distant descendants. #19 proposes
traitsas the way to represent that.#9 argues for the restriction rules to live in a different level than the SDCs, so #19 incorporates that via the separation between SDCs just declaring information about themselves, while the
policiesthat act on that information being defined in Drupal config.The
is,slotted, andtraitskeys I'm proposing in #19 would all be optional. SDCs that are designed to be super generic and flexible don't need to populate those keys. But what other than the SDC itself should be declaring that it's an accordion item, or card-like, or that it's full-width, or has a certain luminance, for the cases where the SDC author knows that information and wants to make that information available, so that policies can be created around that information?The SDC YAML already provides information about itself that isn't a render-time concern. For example,
examplesanddescription. A big selling point of SDCs is that everything about the SDC is colocated: the YAML, the Twig, the JS, the CSS. What's proposed in #19 is additional optional metadata about the SDC: why break the colocation advantage of SDCs by forcing that additional metadata to be somewhere else?Comment #25
effulgentsia commentedComment #26
ctrladelOverall I think #19 is headed in the right direction but also don't find the terms used obvious. When reading through the comment
islacked any hints or context to the purpose/intent of the value andslottedto me implied components that had been placed in the slot. Can't think of any good alternatives toisbut forslottedsomething likewants,accepts,intendedFor,canContainare more clear to me.+1 to
isbeing multi valuePolicies are a really interesting abstraction to handle enforcing restrictions and I think with an extensible implementation would address #21's concern about needing to apply advanced logic. Traits with conditions I'm not so sure about. Even in the short example the inclusion of conditions adds a lot of complexity to the definition. A simpler structure that's just a place to put arbitrary information for policies to interpret would be more approachable. One downside to such a flexible system is we are bordering on violating the concept that everything you need to know about a component is in the directory which has been part of the reasoning behind not allowing preprocessing in #3321203: Have a way to implement the a preprocess function per each SDC component (ideally in the same folder)
Could policies also be used to add slot limits similar to https://www.drupal.org/project/layout_builder_limit?
Comment #27
nod_We're talking about adding something optional for which the only existing/current need is accordion/accordion_item. From there we assume things will get more complicated and try to come up with a solution, that doesn't sound like a plan that will address our users needs. In that situation where the needs are not clearly defined, contrib will implement it, battle test/refine the requirements and we get it in core once we know more about how it's used.
On the technical side of things It's totally possible for XB to add an extra yml file to SDCs that it will use (and maybe other modules can end up using the file too), core is not blocking anything except for this annoying restriction with finding SDC yaml files: #3475153: Make DirectoryWithMetadataDiscovery generic and reusable. As wim said in that very same issue: "In Drupal core, we generally only introduce an abstraction once there's >=3 uses for it." From what we talked about here, we're not there yet.
To me this issue should be postponed on XB implementing this, finding what works and what doesn't and we get the parts that are actually needed and helpful then.
Comment #28
pdureau commentedThe complexity of #19 proposal (6 new keywords! a full rule system! 1 config entity!) show how risky the subject and how careful we need to be.
Let's go back to the start of this issue, when we were still proposing straightforward solutions. Maybe using component IDs in our new keyword is too limiting:
The suggestion of "tags/categories" system, or a DTD like system, as proposed by Wim in #16 & #17 is interesting.
Just brainstorming with you here...
Considering:
metadata,flow,sectioning,heading,phrasing,embeddedandinteractive). Example: P element expects phrasing content. https://html.spec.whatwg.org/multipage/grouping-content.html#the-p-elementLet's leverage this information, and only this information, coming from an industry standard source, without the temptation of adding drupalisms.
Proposal
By adding only 2 simple additions:
1. A single keyword:
model(or something else, let's discuss) which can be optionally used both in a component definition and a slot definition:Front devs own both the definition and the templates, and they all know what an HTML is. It will be easy for them.
2. A simple service with a registry of the content model all HTML elements (no need to put much data inside thanks to the HTML content model information) and:
::checkElementModel(string $parent_element_tag, string $child_element_tag): bool;::checkComponentModel(string $parent_component_id, string $parent_component_slot, string $child_component_id): bool;A display building tool will be able to use this service for altering its UI and mechanisms.
With this simple system:
Example
I took the most radical example i can find in the wild 😉
https://git.drupalcode.org/project/ui_suite_bootstrap/-/tree/5.1.x/compo...
https://git.drupalcode.org/project/ui_suite_bootstrap/-/tree/5.1.x/compo...
https://git.drupalcode.org/project/ui_suite_bootstrap/-/tree/5.1.x/compo...
⚠️ To be clear, we are not putting here what we expect in slots or as parent, but what we have as component or slot wrapper. So no unexpected behaviours.
Comment #29
pdureau commentedDiscussed with Laurii which is agreeing with keeping this simple, with ideally a single keyword in the component definition, nothing more, but not using such logic based on HTML elements.
We also agreeing on not enforcing on render level, only on UI/UX level.
So, other proposal...
1. A single keyword:
model(or something else, let's discuss) which can be optionally used both in a component definition and a slot definition:my_theme:accordion_item) OR a keyword (ex: "section", "flow", "content"... from a fixed or opened list?)Example with component ID
my_theme:accordionparent component:Matching
my_theme:accordion_itemchild component:Example with a keyword
my_theme:accordionparent component:Matching
my_theme:accordion_itemchild component:Pierre's personal note
I like the keyword-based proposal as much as my previous HTML-based proposal, but I struggle to anticipate the situation when a component author will add a restriction blocking expected usages and forcing the other components (which may be in the scope of a different author) to alter their definitions. Let's be careful.
However, I am afraid using component ID will be considered as bad practices (because too constraining) after a while.
Comment #30
effulgentsia commentedResponding to earlier comments, not #29...
+1. I moved my proposal, with this suggestion incorporated, into #3513563-12: [later phase] [META] Component slot restrictions ("which?") + limits ("how many?").
Love it! I incorporated it into that issue comment.
I think we need it to support use cases like #14, because whether a component is wide or narrow, light or dark, often depends on prop values. From an Experience Builder perspective, what this would mean is as long as the component has some prop values that are compatible with the policies, we'd let you put the component into the slot and then restrict the props form to only the policy-compatible values.
I agree with simplifying how to express the conditions. I incorporated that into #3513563-12: [later phase] [META] Component slot restrictions ("which?") + limits ("how many?").
The key to #19 / #3513563-12: [later phase] [META] Component slot restrictions ("which?") + limits ("how many?") is that everything that's about the component is still in the SDC's directory. Whereas the policies aren't about individual components, they're about component traits. For example, a policy about contrast ratios or width compatibilities is based purely on comparing the slot's computed traits (its own traits plus ones inherited by ancestors in the layout tree) with the component's computed traits. Even a policy that says "there must be an intersection between a component's
istrait and a slot'sintendedFortrait" isn't about a specific component, just about that general rule.Comment #31
effulgentsia commentedI like #29, but I think it's confusing for the same word,
model, to mean something different for a component (what the component is) than for a slot (what the slot is intended to contain).Personally, I'd suggest renaming it to something like
isat the component level andintendedForat the slot level.I think the keywords within each can also include HTML tags where appropriate. For example:
The above example might seem redundant, but something like
[card, div]might not be.Comment #32
effulgentsia commentedOther terminology brainstorming...
We could shorten
intendedForto justfor:Or, if we like the idea of using
modelin both places, we could qualify the one for the slot withslotted:Comment #33
effulgentsia commented#32.2 would leave room for also being able to identify the model of the slot distinctly from either the containing component or the slotted components. For example:
Don't know if there's practical use cases for that though.
Comment #34
pdureau commented@effulgentsia
I don't have strong opinion about the naming of the properties we may add. Let's focus on mechanisms first.
I still believe the logic based on HTML elements in #28 is the best for now. Not because it is dealing with HTML elements, but because we are not adding information about what we expect in slots or as parent, but information about what we are as component or slot wrapper. It delegates the logic to an external, alterable, service and keep component definitions "clean" and furire proof while doing the expected job.
In #31, you propose to use both tags and HTML elements, but your example is dealing with the expectations (
cellslot is expectingtdcomponents):How can we achieve that with your new proposals?
Anyway, all those proposals from everybody are useful. Step by step, we are approaching a solution.
Comment #35
lauriiiI've been thinking how we should name this. I'm thinking
supportsandconflictswould be nice because it would make it explicit that we're documenting what components work nicely in the slot. This is relevant meta information even outside of page builders because it would allow developers to document what set of components should be tested with the component.I think we need to support minimum and maximum children too. Often times there's a limit to how many components a slot is able to accommodate.
Allowing the use of categories and tags allows building design systems that are flexible without introducing a high number of direct dependencies between components. Adding tags besides categories allows managing situations where there's tension between categories which would be used for categorizing components in the UI and the restrictions.
Some example uses of tags could be:
full_widtheditorial_contentdarkandlightThis way one could configure that XB root only supports
full_widthcomponents. If you have components that specify a dark or light background, you could specify that the component only supportsdarkorlightcomponents.I'm thinking that the following schema would be able to satisfy all of the use cases I have in mind:
Here are some example configuration which would support components tagged as "feature" to be added. There could be anywhere between 1 and 6 items. Example values allow specifying content that a page builder could add to the slot by default:
Comment #36
mherchelI like the naming in #35!
Should there be a reverse relationship too? An example of this would be to limit people to put accordion_items only into accordion_group components.
Comment #37
pdureau commentedThanks you @laurii to restart this thread and for your proposal. The
minimum/maximumproperties are interesting.For this proposal as for the previous, I am mainly hoping component authors will not rely on those indications to allow themselves to do weaker or dirtier component templating. They have to understand those indications will not always be strictly enforced.
To complement, this, here is a study of what the other technologies do. Maybe we can find there something which will validate one of our existing proposals or a new idea to explore.
Oracle Content Management
For any layout slot, you can specify certain restrictions on the components allowed in the slot.
If you restrict components in a slot, any user dragging a component that is not allowed will see a warning message and will not be able to add or move a component to that slot.
Example:
https://docs.oracle.com/en/cloud/paas/content-cloud/creating-experiences...
Analysis:
Vuejs's defineSlots()
The purpose of the macro is to improve Developer Experience (DX) by adding suggestions and type validation directly in your code editor/IDE. defineSlots accepts a literal type as its parameter, where each property represents the name of a slot, and the value is a function defining the props the slot accepts.
Suppose in your AppProducts component you want to provide product information and define their types.
https://vuejs.org/api/sfc-script-setup#defineslots
https://escuelavue.es/en/devtips/typescript-vue-scoped-slots-defineslots
Analysis:
What else?
Does someone want to share other examples, from UI components tech or display building tools?
Comment #38
pdureau commentedIndeed Mike. Let's not forget this.
Comment #39
lauriiiI was thinking about this but I'm not sure that we can do that because components can include multiple slots and we don't have the concept of a default slot. We don't know which slots these restrictions would apply to in the case that a component includes multiple slots. I would recommend opening a follow-up issue to consider this after we've added slot restrictions in this issue. This seems something that could be easily added as a new API there.
Comment #40
pdureau commentedTotally agree.
I still think this is the way to go. We are struggling finding the perfect balance between covering the expected mechanisms and staying simple. Let's have a look on what other community are doing.
I already shared examples from Oracle Content Management and VueJS. What else can we find?
In my humble opinion, it is better to not have this feature than having a bad implementation of this feature. There is a high risk of doing something we may regret later.
Comment #41
pdureau commented@lauriii has found other examples:
Builder.io
https://www.builder.io/c/docs/register-components-options#child-requirem...
component?stringOptional. Specifies a component name. This property provides a direct way to enforce that the children must be of a specific component type.
messagestringMessage to show when the child requirements are not met. Use to provide information or instructions to the user about the expected child components. For example, "Children of 'Columns' must be a 'Column'".
query?anyOptional. Use for more advanced requirements by specifying a MongoDB-style query using the sift.js library. Use to define complex conditions that the children objects must match. You can use various operators, such as
$in,$eq,$ne,$gt,$lt, to create the desired conditions.Example of
childRequirementswith a query:querylooks interesting but maybe too complexStoryblok
https://www.storyblok.com/docs/concepts/fields#blocks
In the 2 first properties, does "block" here means "component" or "renderable" for us? Sometimes, a single Drupal renderable (example: a View) can have multiple components (example: each row is an SDC).
Too bad there is no example in the doc because the 3rd property is not clear. Why is it a boolean instead of a list of components, tags, folders?
In SDC, we have providers and groups/categories instead of tags and folders. UI Patterns 2 is adding "tags" but it as not proposed for Core inclusion yet.
Anyway, it looks a lot like Laurii's proposal.
Magnolia
https://docs.magnolia-cms.com/product-docs/6.3/developing/templating/tem...
It is interesting but let's avoid the role keyword because an user role (config entity) is specific to each website and too business for UI components
Comment #42
pdureau commentedComment #43
dhansen commentedAnother example for the pile:
Gutenberg (WordPress)
https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/nested-blocks-inner-blocks/#using-parent-ancestor-and-children-relationships-in-blocks
I think
ancestoris an interesting part of the specification, though I question it's utility. It's also interesting that the limits can be bi-directional: inner components can limit components they're in, and outer components can limit what is inside them.I don't have much to add in the way of commentary at this time, but I did want to make sure this was included as an example if we are collecting examples.
Comment #44
pdureau commentedSo, I guess we have enough data to decide and start this long awaited feature:
allowed-itemsdisallowed-itemsallowed-itemsdisallowed-itemsdefineSlotscomponentavailableComponentsallowedBlocksparentandancestorSo, the proposal based on what other display building tools do: 3 new optional keywords in each SDC slot definition:
expectedwith a list of values: SDC plugin IDs (if they have a colon inside) or tags/groups (if no colon inside)minimumandmaximumwith a strictly positive integer value: Enforce a lower/maximum limit on the number of childrenAnyway, we can decide anything, but let's not enforce it at the Render API / SDC level, as shared in comment #2:
Because of that, at Core level, the change will mostly (only?) happen in the SDC schema, so it must be a small and safe change, without the need of back compatibility and related unit/kernel tests.
Who want to take the job? Can we target 11.3?
EDIT 1st September:
expectedinstead ofallowedComment #45
d34dman commentedI share this thought as well. Otherwise, would be a very difficult system to work with. Because it would often conflict with the distributed sdc component architecture we would like to have in core and contrib, to promote re-usablity of components.
The current definition of SDC is very modular. That means it does allow choice of mixing and matching at composition level.
However, the moment we add restriction on SDC component regarding which other component it is compatible with, it breaks this modularity.
Lets take an example: "accordion item" can only go into "accordion".
If we add restrictions on "accordion" to accept only "accordion item" it leads to a problem.
It makes it difficult to use "accordion item" like components (e.g. enhanced accordion item) inside "accordion".
As the system grows over time, it is possible that more components become compatible with each other. And the decision of which component can go where depends on variables that are not known to SDC components.
Maybe am complicating this too much, we could possibly start with restrictions and provide an alter hook. So that a module (in contrib/core) can provide a UI and some config to let Site Builder re-define the restrictions?
Comment #46
lauriii+1 for #44.
@d34dman Isn't the solution to what you're describing using categories / tags instead of specific components? I'm hesitant to add an alter hook for this because the DX of SDCs is intended to be as simple as possible and as the name suggest, everything related to a component should be found in a single directory.
Comment #47
pdureau commentedAs Laurrii, I would prefer to not add an alter hook. Let's keep PHP far away from SDC and theming in general.
I have changed my proposal from
allowedtoexpectedto show it is not enforced on lower levels, and tools will be able to decide the level of enforcement.Comment #48
d34dman commentedThe pattern I had is more like declaring
TabItemInterfacevsTabItemas compatible type.Good idea. +1.
Regarding naming, this feels more like a suggestion that a SDC can make. I usually tend to think of what can "fit" into the component. As in any "suitable" component can "fit" into the slot. So by that reasoning "expected" is closer in this regard for me. +1 for expected. Maybe a native english speaker can decide the right form of the word to use (expects vs expected).
Comment #49
pdureau commentedFor information, the related issue in Display Builder project: #3544026: Cardinality & suggested components constraints for slots
Comment #51
anmolgoyal74 commentedComment #52
pdureau commentedHi @anmolgoyal74, thanks for the commit. However, the MR has not been created.
Comment #54
pdureau commentedIssue summary updated according to last discussion and MR in review.
Comment #55
kristen polChanged from experience builder to canvas
Comment #56
effulgentsia commented+1 to
expected.For minimum and maximum, would
minItemsandmaxItemsbe closer aligned to JSON schema semantics, which uses the latter pair for arrays whereas the former pair is only for numbers?For the tags/groups case to work, do SDCs already have a way to identify which tags/groups they're in? If not, can this issue's scope also include defining such a property?
Comment #57
pdureau commentedI like
minItemsandmaxItemsbecause it is more explicit thatminimumandmaximumbut it has been a few weeks I am telling the SDC community that "we have reached a consensus, you can start implementation even if not merged yet" ;)So, if we change that, we need to share the information with:
Comment #58
lauriii+1 for
minItemsandmaxItems. This seems like a minor revision of what we have agreed. Most likely it only takes a simple search and replace at this point since it doesn't seem anyone has released anything where the old keys are being used. If that's the case, let's go ahead with it.What's needed for this to be committed other than updating the MR to account for ^?
Comment #59
effulgentsia commentedThere's still the last sentence of #56: we're saying that
expectedcan include tags or groups, but what should display builders match that against? Shouldn't this issue also standardize on that: e.g., atagsorgroupsor some other top-level key of *.component.yml file?Comment #60
lauriiiSDCs already allow using the
groupproperty: https://www.drupal.org/docs/develop/theming-drupal/using-single-director... which is what it should match against. We haven't defined how we'd reference those which is an interesting question given that groups don't have a machine readable name defined today.I believe we discussed at some that tags is something we we'd likely want to support (and it's supported by UI Patterns already). However, if it's something we'd, we'd do it in a later issue.
Comment #61
effulgentsia commentedAh, thanks! I missed that the
groupkey was already a thing. I'm happy to RTBC or merge this once #58 is resolved.Comment #62
mherchelFWIW, I don't believe we should use the
groupkey as tags forexpected.The
groupkey organizes the components within the Ui. Which is a very different task than anexpectedtag.An example of this is I want the tab_group and tab_item components to be in the same folder within the builder's UI, however, tab_item might have a tag that's in the tab_group's
expectedvalueComment #63
effulgentsia commentedGiven #62, why not add
tagsin this issue and documentexpectedas being able to contain SDC IDs or tags, but not group?Comment #64
podarokAdded functional Parent-Child working reference
demo https://youtu.be/QT4cPzMBTr4
Comment #65
mherchelI'm happy with this!
Comment #66
pdureau commentedSo, if my understanding of the recent proposals is right, from the current state of the MR, we can do those changes:
minimumwithminItemsandmaximumwithmaxItemstagsproperty with{ "type": "array"; "items": { "type": "string" }schematitleanddescriptionproperties to ,minItemsandmaxItemsto document their usageexpected, in this description, tell the list of values can contain:Am I right?
By the way, I don't find
group(with{"type": "string" }schema) in https://git.drupalcode.org/project/drupal/-/blob/11.x/core/assets/schema... I was pretty sure it was already part of SDC. Is it something to add even if we don't use it inexpected?Comment #68
mherchel@pdureau that (#66) sounds correct to me!
Comment #69
f0ns commentedThanks for the work on this one, just read it all and the last comments read like this is on the right path.
Really looking forward to the
expectedbit here as I'll use it a lot.Comment #71
svendecabooterComment #72
svendecabooterI have added the changes mentioned in #66, as there seemed to be consensus around them.
Tests were failing earlier, but they seem OK now on a rerun.
Please check if these updates are as desired.
Comment #73
podarokAdded to Canvas both
expectedandtagssupport in https://www.drupal.org/project/canvas/issues/3563163#mr414-note716607Comment #74
phenaproximaBack to the drawing board for a small change that is needed, but otherwise I understand this and have no particular objection. I reviewed it in person with @lauriii, @pdureau, and @mherchel at DrupalCon Chicago.
Comment #75
pdureau commentedDecided in DrupalCon with the team: I will do the change, Mike or Adam will RTBC, I will commit to main.
Comment #76
pdureau commentedChange done. Pipeline OK
Comment #77
phenaproximaThat looks good to me.
Comment #78
pdureau commentedGreat. Commiting soon.
Comment #79
pdureau commentedRenaming the issue to make it fit better with the upcoming commit message.
Comment #81
pdureau commentedCommitted a9bb3cd and pushed to main. Thanks to everybody!
Because this feature is at API level and only some declarative stuff, it doesn't unlock proper "features" to devs and users. We need the contrib space (Canvas, Display Builder, SDC Display, UI Patterns...) to embrace this first. So, no change notice needed in my opinion.
Comment #82
pdureau commentedComment #84
grimreaperHi,
Thanks for these new features.
Even if there is no direct impact in Core, is there a change record in preparation for component authors to be aware of this change?
Comment #85
mherchelYay!
Yeah, I kind of agree. I think people need to be aware of it. We could also update the docs (with notes saying that page builders have yet to support this).
Thoughts?
Comment #86
phenaproximaVibed one: https://www.drupal.org/node/3582722
Comment #87
phenaproximaAny chance of this being ported to 11.4? I hope so, so changing status accordingly.
Comment #88
nod_I think it's safe to backport, @pdureau go for it
Comment #89
grimreaperThanks @phenaproxima