- Issue created by @wim leers
- ๐ง๐ชBelgium wim leers Ghent ๐ง๐ช๐ช๐บ
See, I knew I vaguely recalled seeing that somewhere! ๐ Had no idea how to find it. Thanks, @lauriii! ๐
- ๐ฌ๐งUnited Kingdom longwave UK
Ah that makes sense but I also think that all these component listings/groupings should be 100% controllable from the server side, we shouldn't have any hardcoded restrictions - we should be flexible in allowing developers to customise the XB UI from PHP wherever possible. This means that even if the library and top bar have groupings (like the Sections/Components split we have at the moment), the number/names of those groups should be sent from the server.
- ๐ฆ๐บAustralia larowlan ๐ฆ๐บ๐.au GMT+10
This means that even if the library and top bar have groupings (like the Sections/Components split we have at the moment), the number/names of those groups should be sent from the server.
Agree ๐ฏ, this is the same sort of thing I was trying to say in ๐ Implement saving block settings forms Active but I think you've said it better with
we should be flexible in allowing developers to customise the XB UI from PHP wherever possible
- ๐
- ๐ฆ๐บAustralia larowlan ๐ฆ๐บ๐.au GMT+10
@effulgentsia asked me if I have thoughts on how to split up the server-side vs client-side responsibilities here and design the API between them.
I think this is where having an OpenAPI spec comes in handy. We can use that as the discussion point. I'll open an MR with some changes to demonstrate what @longwave is articulating in #4
- Merge request !535Issue #3498419: Support PHP defined component lists โ (Merged) created by larowlan
- ๐ฆ๐บAustralia larowlan ๐ฆ๐บ๐.au GMT+10
Proposed a change to the API spec for the components controller that should power this.
If we agree with this approach we can move to implementation
- ๐ฌ๐งUnited Kingdom longwave UK
Some nitpicks but the proposal looks good to me in principle.
- ๐ณ๐ฑNetherlands balintbrews Amsterdam, NL
I took a stab at writing a more descriptive title based on where the conversation went.
Also, I thought it might be helpful to be aware that the designs for code components ( ๐ฑ [Meta] Plan for code components Active ) introduce the term, group. See โจ Component groups for code components Postponed . Those are what we previously named category in ๐ Define built-in components and categorization for components Postponed . We may want to resolve that mismatch first before we choose the property name here. I would vote for renaming groups to categories in the code components world.
- ๐ง๐ชBelgium wim leers Ghent ๐ง๐ช๐ช๐บ
#6++ โ nice work, @larowlan!
I find both and fairly confusing. I tried to think out of the box. Thoughts on https://git.drupalcode.org/project/experience_builder/-/merge_requests/5... ?
- ๐บ๐ธUnited States effulgentsia
During a recent retrospective, the XB team identified that in addition to having a "sprint" tag, it would be helpful to have a short list of other issues that would be the most valuable to work on if/when the ones in the current sprint are all blocked or being worked on by someone else or are outside of someone's area of expertise. I'm going with "sprint candidate" as the tag for that. Often, this will be issues that are likely to be part of the next sprint, so getting them done (or at least started) early would be fantastic.
- ๐ง๐ชBelgium wim leers Ghent ๐ง๐ช๐ช๐บ
Thoughts on name proposals at https://git.drupalcode.org/project/experience_builder/-/merge_requests/5...? ๐
- ๐ง๐ชBelgium wim leers Ghent ๐ง๐ช๐ช๐บ
By the way, it's not clear to what the different UI locations would be?
Is it
components: label: Components position: library icon: Component1 weight: 1 global_components: label: Dynamic Components position: header icon: File weight: 2
as in the current MR? i.e. "Components" or "Dynamic Components", nothing else?
@larowlan says that @effulgentsia pointed out we also need "Extensions", but โฆ extensions don't come from
Component
config entities norComponentSource
plugins, so how does that connect? - ๐ง๐ชBelgium wim leers Ghent ๐ง๐ช๐ช๐บ
๐ Create extendibility proof of concept that also serves as documentation-by-example Active landed yesterday, but it doesn't yet expose that demo extension through the top bar: that still contains a hardcoded list of extensions.
The title of this issue is about component sources, but perhaps it's really about populating the entire XB UI top bar menu from the server side? ๐ค
- ๐ซ๐ฎFinland lauriii Finland
@larowlan says that @effulgentsia pointed out we also need "Extensions", but โฆ extensions don't come from Component config entities nor ComponentSource plugins, so how does that connect?
I believe this would be referring to the fact that extensions panel will show module provided components in future:
- ๐ซ๐ฎFinland lauriii Finland
I know I've written this somewhere but I can't find it anywhere so I'm writing this again here for context. The different places where components will appear in the UI are the following:
- Elements: Provided by Experience Builder
- Extensions: Provided by Modules
- Dynamic Components: Blocks
- Library: SDCs from the Active Theme + JavaScript Code Components
Each of these UIs have categorization within that category for its components. Here are few screenshots of how these might look like:
- ๐บ๐ธUnited States effulgentsia
For terminology, I propose
library
instead oflist
. In other words, per #19, we'll have 4 libraries:- ID=elements, label=Elements
- ID=extension_components, label=Components
- ID=dynamic_components, label="Dynamic Components"
- ID=primary_components, label=Components
Note that per above two different libraries can have the same label. #1 in the above list won't be in XB 1.0: that will come later when a visual component builder gets worked on.
If we follow the metaphor of Library, as in buildings with books, then libraries don't have positions, they have locations, so I also propose renaming what this MR calls
position
tolocation
. This would then allowweight
to be renamed toposition
.Now here's where things get tricky...
On a superficial level, there are two locations: the left and the top. Continuing the metaphor with brick-and-mortar libraries, we can think of this as the main library (on the left) and satellite libraries (on the top). The area in the top bar for these satellite libraries is called tools ๐ Define the 3 areas the Top Bar will provide Active . So the above could be conceptualized as:
- ID=elements, label=Elements, location=tools, position=0
- ID=extension_components, label=Components, location=tools, position=1
- ID=dynamic_components, label="Dynamic Components", location=tools, position=2
- ID=primary_components, label=Components, location=main
On the surface, the above seems really good in terms of meeting the goals of comment #4: it would allow PHP code to add more libraries to the Tools area and have them show up without needing any change to the React code.
However, the are two problem with this approach:
- The UX will need to intersperse other things that aren't component libraries in the Tools area. For example, we'll want a menu for managing Text styles, and we'll want this menu to be to the right of the Elements library and to the left of the Extensions library. Perhaps we could solve this by assigning documented
position
values for these non-library tools? So, for example, if we assign Text Styles as position=100, then #2 and #3 in the above list could be changed to position=101 and position=102. - Within the Extensions menu, there are other things besides the extension_components library. For example, there's also plugins. This probably makes
extensions
an entirely separate location fromtools
, since we don't want to place the extension_components library directly in the tools area, but rather inside the Extensions menu that's within the Tools area.
So that then leaves us with:
- ID=elements, label=Elements, location=tools, position=0
- ID=extension_components, label=Components, location=extensions
- ID=dynamic_components, label="Dynamic Components", location=tools, position=201
- ID=primary_components, label=Components, location=main
With the above, how much value are we even gaining from #1 and #3 being in the same location, if we need out-of-band knowledge about the
position
values? Would it be more robust to do:- ID=elements, label=Elements, location=elements
- ID=extension_components, label=Components, location=extensions
- ID=dynamic_components, label="Dynamic Components", location=dynamic_components
- ID=primary_components, label=Components, location=main
But if we do the above, then we're down to a 1:1 relationship between library and location, which means we don't need location at all. We could go back to:
- ID=elements, label=Elements
- ID=extension_components, label=Components
- ID=dynamic_components, label="Dynamic Components"
- ID=primary_components, label=Components
and have the React UI hard-code where each library ID goes. Which I think is what makes the most sense given the UX we want, but it would remove the flexibility desired in comment #4.
@larowlan, @longwave: Since you were the two most wanting greater flexibility, what are your thoughts on this?
- ๐ซ๐ฎFinland lauriii Finland
I feel pretty strongly that it would be better to be opinionated on the libraries and not allow individual sites to meddle with these. From users perspective, there's a lot of value in having consistency how these are presented to them. For example, this allows us to provide documentation and video materials that are actually meaningful to the end user. If we identify other common needs, we could easily add backend / UI support for additional libraries even if XB doesn't add anything to those libraries by default.
- ๐ฆ๐บAustralia larowlan ๐ฆ๐บ๐.au GMT+10
I think #20 is ok, somewhere I saw @lauriii say having it consistent means we can record generic training videos, so that makes sense.
I think the original goal was to allow modules to have a say in all of this. But I think so long as they can put things in the extensions drawer, that need is met.
- ๐ฌ๐งUnited Kingdom longwave UK
If we're going to hardcode the locations would we also be hardcoding the labels? I'm not sure I see the benefit of adding flexibility for the four labels, we might as well just send only the library ID for each component then we need no metadata at all about the libraries themselves. Users could still relabel them through translations if they really wanted to.
I still think contrib or custom implementations of XB might want to add additional icons in the top bar, or regroup things in their own way, but perhaps for 1.0 we just disallow that until we have a good use case for it.
- ๐ฌ๐งUnited Kingdom f.mazeikis Brighton
f.mazeikis โ made their first commit to this issueโs fork.
- ๐ง๐ชBelgium wim leers Ghent ๐ง๐ช๐ช๐บ
I just asked @lauriii whether module-provided SDCs belong in the bucket he mentioned in #19 (or @effulgentsia's
extension_components
equivalent in #20). The answer is .So that means this is AFAICT the decision tree:
1. Is the component dynamic (consumes implicit inputs/context or has logic)? YES โ dynamic_components NO: Go to 2. 2. Is the component provided by a module? YES โ Go to 2.B NO โ Go to 3. 2.B I the providing module XB? YES โ elements NOโ extension_components Fallback: โ primary_components
- ๐ซ๐ฎFinland lauriii Finland
This is almost correct. The library should show components only from the active theme. This is different from the current functionality where itโs showing components from all themes. Based on this, the decision tree would be:
1. Is the component dynamic (consumes implicit inputs/context or has logic)? YES โ dynamic_components NO: Go to 2. 2. Is the component provided by a module? YES โ Go to 2.B NO โ Go to 3. 2.B I the providing module XB? YES โ elements NOโ extension_components 3. Is the component provided by the active theme (or its base theme)? YES โ primary_components Fallback: โ Component not listed in XB.
- ๐ง๐ชBelgium wim leers Ghent ๐ง๐ช๐ช๐บ
#27 doesn't account for "code components" ( ๐ฑ [Meta] Plan for code components Active ). For those, it's not provided by an extension (module/theme), but by config.
1. Is the component dynamic (consumes implicit inputs/context or has logic)? YES โ dynamic_components NO: Go to 2. 2. Is the component provided by a module? YES โ Go to 2.B NO โ Go to 3. 2.B I the providing module XB? YES โ elements NOโ extension_components 3. Is the component provided by the default theme (or its base theme)? YES โ primary_components NO โ Go to 4. 4. Is the component provided by neither a theme nor a module? YES โ primary_components Fallback: โ Component not listed in XB.
Question 4 accounts for that now. ๐
- ๐ง๐ชBelgium wim leers Ghent ๐ง๐ช๐ช๐บ
Given the decision tree in #27, I think we've got some serious changes to make:
-
I keep forgetting that the
ComponentSource
plugin is instantiated perComponent
config entity! ๐ฌThat's why @f.mazeikis'
SingleDirectoryComponent::getLibraryId()
implements this correctly ๐.But still, the fundamental problem remains: we want all future component sources to also respect this, and we know this is likely to evolve over time. That'd require all those plugins to be updated; leaving XB product owners less in control over the cohesiveness of the UX.
- is not a thing we currently do: neither in HEAD, nor in this MR. I'm fine with it not yet happening here to keep scope tight, but we need to think through the consequences of the current implementation to make it possible.
Over at ๐ Library includes components/blocks that have been disabled Active earlier today, we made it so that the server-side list of
Component
s is the complete set of everything discovered on the site (including ones that are either automatically or manually disabled aka get theirstatus
set tofalse
), but the client only receives the relevant subset: the enabled ones.This seems different-but-similar:
/xb/api/config/component
should now only return thoseComponent
s which belong in one of the 4 libraries, according to the decision tree. (And still only the enabled ones, of course.)Loading all
Component
config entities and instantiating their correspondingComponentSource
plugin is very expensive. Although โฆ right now it doesn't seem to be making a significant difference in my local dev env (HEAD vs current MR). But it definitely eventually will. - โ ๏ธ Changing the default theme (
system.theme
config'sdefault
key-value pair) should then immediately result in the set of components available in the XB UI changing! (Which again is the controller for/xb/api/config/component
).
-
- ๐ง๐ชBelgium wim leers Ghent ๐ง๐ช๐ช๐บ
BTW, nice, OpenAPI validation has been catching the fact that not all responses contain the necessary
library
info:Body does not match schema for content-type "application/json" for Response [get /xb/api/config/component 200]. [Keyword validation failed: Value must be present in the enum in sdc.olivero.teaser->library]
๐
- ๐ง๐ชBelgium wim leers Ghent ๐ง๐ช๐ช๐บ
To fully address #29, we would need:
- to query across all
Component
config entities to find only the relevant ones to return to the client WITHOUT having to instantiate them (both the config entity and the associated source). - upon changing the default theme, all affected
Component
config entities must have their library re-assessed - ideally, we'd apply the decision tree in #27 automatically. So then we need to automatically and efficiently be able to answer each of the 5 questions (1, 2, 2.B, 3 and 4 in #28). Let's try:
- โ Impossible today: we lack this metadata.
โ Easily added though: add a boolean key-value pair to\Drupal\experience_builder\Attribute\ComponentSource
, which then every source defines. EveryComponent
config entity already stores itssource
. From there, it's trivial to map it to the appropriate boolean value.
โ https://git.drupalcode.org/project/experience_builder/-/merge_requests/5... - โ Impossible today: we lack this metadata.
โ Easily added though: a new requiredprovider
property on theComponent
config entity, that all component sources must populate.
โ https://git.drupalcode.org/project/experience_builder/-/merge_requests/5...
- โ Impossible today: we lack this metadata.
Then we can use this metadata in the config entity query โฆ and bam, future performance disaster averted!
โ https://git.drupalcode.org/project/experience_builder/-/merge_requests/5...Still remaining to be done: move the computing of the library ID elsewhere.
- to query across all
- ๐ง๐ชBelgium wim leers Ghent ๐ง๐ช๐ช๐บ
I'll tackle
Still remaining to be done: move the computing of the library ID elsewhere.
because my head is still in this space from last night. Will assign to @f.mazeikis for review afterwards.
- ๐ง๐ชBelgium wim leers Ghent ๐ง๐ช๐ช๐บ
Green! ๐ฅณ That means my proposal in #31 turned out to be viable ๐
Overhauled the issue summary based on @lauriii's #19, @effulgentsia's #20 and my decision tree in #28, which @lauriii +1'd.
I also already updated the docs.And for the last nice bit: query cacheability.
Back to @f.mazeikis for reviewing what I changed โ note that @f.mazeikis' original
SingleDirectoryComponent::getLibraryId()
is still present, but now is fully generalized, and fully implements #28's decision tree. - ๐ง๐ชBelgium wim leers Ghent ๐ง๐ช๐ช๐บ
-
wim leers โ
committed defaa88e on 0.x authored by
larowlan โ
Issue #3498419 by f.mazeikis, wim leers, larowlan, lauriii, longwave,...
-
wim leers โ
committed defaa88e on 0.x authored by
larowlan โ
- Status changed to Fixed
15 days ago 10:44am 18 March 2025 Automatically closed - issue fixed for 2 weeks with no activity.