- Issue created by @larowlan
- 🇺🇸United States effulgentsia
I think the main drawback of one field per exposed slot is with respect to future Views integration. Suppose in the future we want to be able to support Views (or even just EntityQuer(ies)) for finding all instance of a Heading component whose
element
prop is equal toh2
(or likewise get lists of component instance matching whatever other condition). If we want such a View to be able to query across all exposed slots, I think that gets more complicated (maybe not impossible) when the data for each exposed slot is in a different field.The main benefit of one field per exposed slot is being able to leverage Drupal's existing infrastructure for deleting fields (and the corresponding batched purging, etc.) when exposed slots get deleted. Although that is a benefit, it would be limited to just the case of deleting exposed slots. It wouldn't, for example, solve deletion of non-exposed slots (e.g., a code update to an SDC that removes a slot), or deletion of components. However, @catch argues in #3519352-57: Content templates, part 3b: store exposed slot subtrees on individual entities → that the exposed slot is the more important use case for which to ensure robust data integrity, because those can get deleted through normal UI interaction, whereas the other cases are only triggered by code deployments, for which there's other options available for managing those (for example, the ability to run a longer running process to perform the update or simply choosing to not deploy code that breaks things you don't want to break).
If we decide against the field-per-exposed-slot idea, then another way to manage deletion/purging could be:
- Add an
orphaned_reasons
(or other name TBD) column. Increment it whenever the component instance is orphaned by a slot deletion (whether an exposed slot or a non-exposed slot) or a component deletion affecting itself or an ancestor. Decrement it whenever the slot or component that got deleted gets restored (if we decide to allow such restorations). - When
orphaned_reasons
goes from 0 to 1, set thedeleted
column to 1. Whenorphaned_reasons
goes from 1 to 0, set thedeleted
column to 0. - Leverage existing or add new logic for not loading and for purging field items whose
deleted=1
.
- Add an
- 🇬🇧United Kingdom catch
An
orphaned_reasons
column would have similar problems to file_usage in core (which we still haven't resolved. We had to disable automated file deletion because in-use files kept getting deleted and the only solution we have is completely replacing the entire subsystem with something that tracks actual references like entity_usage).If there's any kind of race condition, failed query, or similar error which can cause the increment/decrement to get out of sync, then either garbage collection will happen when it shouldn't, or it will never happen.
I think there are also information disclosure issues here too - e.g. how do we know that all consumers of the field, JSON:API, custom code etc will respect that only specific deltas are not available? This is much easier to do for an actual field where there is deletion, field access etc. to rely on.
- 🇫🇮Finland lauriii Finland
I think the main drawback of one field per exposed slot is with respect to future Views integration. Suppose in the future we want to be able to support Views (or even just EntityQuer(ies)) for finding all instance of a Heading component whose element prop is equal to h2 (or likewise get lists of component instances matching whatever other condition). If we want such a View to be able to query across all exposed slots, I think that gets more complicated (maybe not impossible) when the data for each exposed slot is in a different field.
There might be other use cases that prevent us from going with the field per slot approach but this tradeoff seems acceptable to me. I can't think of use cases where we'd need this.
The slot itself is supposed to convey something and we shouldn't have to be able to take components outside of that context. This is only relevant in the case of a single exposed slot, e.g.,
content
where the slot is less relevant. But when you have two slots, there's already meaning attached to it, e.g.,
content_top
andcontent_bottom
.To continue with the heading example, a module helping user to create a proper heading tree, may want to list all of the components inside all of the slots, and filter them based on whether that component is adding a heading. Even in this case, I'd imagine this would happen always in the context of the slot. It wouldn't be all that useful to show that there's a h2 somewhere, you'd want to show that there's a h2 in the
content_top
slot.Also, wouldn't Paragraphs have a similar limitation to this, when you use multiple entity reference fields (i.e. multiple slots)?
- 🇬🇧United Kingdom catch
@effulgentsia
Suppose in the future we want to be able to support Views (or even just EntityQuer(ies)) for finding all instance of a Heading component whose element prop is equal to h2 (or likewise get lists of component instances matching whatever other condition).
As well as @lauriii's answer, a single field would only make this easier at a per-entity-type or per-bundle level. As soon as you have differently named fields on different bundles, or even the 'same' named field on different entity types, then a single entity or views query on one field won't cut it. So from an auditing point of view, it doesn't make things any more complicated than they already are.
Also, wouldn't Paragraphs have a similar limitation to this, when you use multiple entity reference fields (i.e. multiple slots)?
I don't know how common this is, but yes. And similarly the use case where sites use layout builder for the top part of the content and paragraphs for the bottom.
- 🇧🇪Belgium wim leers Ghent 🇧🇪🇪🇺
#4: AFAICT that's been solved for XB in 📌 [PP-1] Evaluate storing XB field type's "deps_*" columns in separate table Active . The updating of that usage/dependency metadata DB table is atomic.
- 🇧🇪Belgium wim leers Ghent 🇧🇪🇪🇺
✨ Content templates, part 3b: store exposed slot subtrees on individual entities Active is in — crediting @nicxvan here for his comment about this issue's scope at #3519352-46: Content templates, part 3b: store exposed slot subtrees on individual entities → .
- 🇬🇧United Kingdom catch
@wim leers #3 is proposing an out-of-band update to a separate storage (column on the field table) with a counter though (e.g. a mass update triggered by config changes). It would require direct database queries against the field storage to implement that, they can happen in a transaction but they won't really be atomic IMO - e.g. it's possible for an entity to be loaded before the query runs, and saved after it runs.
- 🇺🇸United States effulgentsia
Yay about #5 that Views across exposed slots is not a necessary capability.
Another concern I thought of: if we do one-field-per-exposed-slot, would that prevent us from being able to use Workspaces and wse_config to stage changes to content templates if such a change involves adding or deleting exposed slots? XB doesn't yet integrate with Workspaces and wse_config, but it's something we'd like to add eventually, even if after 1.0.