Problem/Motivation
Being able to create custom inline content in the layout builder would be powerful feature that would replace Fieldable Panel Panes in contrib.
This issue is to discuss the best Way to do this
Proposed resolutions
#2957425: Allow the inline creation of non-reusable Custom Blocks in the layout builder
The basics
- Adds a new reusable base field to Custom block entity type.
- All existing blocks would be
reusable == TRUE - Changes
\Drupal\block_content\Plugin\Derivative\BlockContentto not pick up non-reusable blocks - Has to update existing Custom Block library View to filter out non-resuable blocks
- Would need entity usage tracking to which Custom Blocks are using in an entity. Could be hundreds in old revisions of an entity and need to have usage clean up on delete. The entity usage tracking would be generic and probably used elsewhere.
- Adds a new block plugin type that allows inline creation non-reusable blocks within the layout builder
- Add new derivative of the block plugin type would be made for each custom block type.
- This new block plugin type could also be used in the Block UI(unless we explicitly stopped it)
#2974860: Allow inline content creation in layout builder through a single purpose entity type
(patch just started so rough idea)
The basics
- Creates a new content entity type, inline block(name?), for inline content creation in layout builder
- No changes at all to
block_contentmodule. - Adds a new block plugin type that allows inline creation of inline block entities within the layout builder
- Add new derivative of the block plugin type would be made for each inline block type.
- Parent entity info would base fields on inline block
- May not need generic entity usage tracking if we can just remove parent info on parent delete and then delete all inline blocks without parents on cron
- Inline blocks would not need owner, or published fields
- Inline block entities would not need routes CRUD because this will would always view the block plugin form
#2948064: Layout Builder should support inline creation of Custom Blocks using entity serialization
This method seems not doable because entity serialization.
See comment 54
- Field UI prevents certain changes to fields like reducing cardinality on field that already has values. This will not work for our serialized block entity fields values.
- Certain field like the Options field may use EntityQuery in
hook_field_storage_config_update_forbidto determine if field config changes should be allow. If any option field value was in serialized block this would not show up. We could fix cores instances but contrib has been able to rely on querying available entities to determine field values. - Update hooks for schema in custom block types won't work for serialized field values.
- If a serialized block is used in default it would exported in to config. If the block has a entity reference value then that entity would have to available when the block was reimported on different environment. Apparently this is problem that Views also has with embedded entities in headers
- File usage is currently not tracked for serialized file field values.
It seems like 5) is the only 1 we could really address with the serialized blocks. 1-3 look to like there is really no good way to solve.
2 shows that entity queries will not select serialized entities. This probably has other side effects.
Any solutions the relies on serialized entities will have these problems.
UX differences
In #2957425: Allow the inline creation of non-reusable Custom Blocks in the layout builder the bundles/fields would be the same for the Custom library and Inline blocks.
In #2974860: Allow inline content creation in layout builder through a single purpose entity type unless we did some magic to sync the fields then they would have different bundles and fields.
When thinking of the new functionality as just new way to use blocks then having the same bundles/field might make sense.
If we expect users to use the new functionality in layout builder as Paragraphs is used today then completely different bundles/fields might make sense.
Comments
Comment #2
tedbowComment #3
tedbowIn regards to the UX differences of having different bundle types from existing block types...
I think if we were going to do this we might as well just use the existing Custom Block entity type because the extra complexity and potential bug of trying to sync these field configs is probably more complex that the changes we would have to make to Custom Block entity type to use it.
I am not sure it is actually a feature we want to have the same fields for both inline and "custom" blocks. both cases have pros/cons
Comment #4
johnwebdev commented#3
@samuel.mortenson added this option in the meeting yesterday
> An entity type that’s more like a facade on top of block_content, deriving its bundles and fields from block_content and using the same storage, but maybe a different base table.
That sounds like something in-between, right?
And I agree, if we go for an entirely new entity type, I think we make a clear separation between them and their use cases. A sync service could be created in contrib for easing the maintenance.
Comment #5
tedbowI would see this has more contrib use case personally. If we did #297486: Problem with jquery.innerfade.js in Internet Explorer then a contrib module could provide the syncing on all or some of the Custom Block types, it could an option on each 1.
We tried to sync in core we would to worry about:
hook_field_storage_config_update_forbidwould automatically fire this for the sync field config?hook_field_widget_form_alter, implementations can check the entity type by$context['items']->getEntity(). So if the intention of an implementation was alter a widget on block entity and it checked this check entity type would not be the same. So have the new entity type that was suppose to be synced the be same as the Custom Block entity all hook implementations like this would have to be updated.This kind of problem for me is why I would think syncing should be left to contrib.
We have to worry about the case where the site builder either creates view that exposes list of the inline blocks or sets up a entity reference to point to inline blocks.
Because determining view access will be tricky, based on view access the revision that inline block placed on.
Right now
\Drupal\block_content\BlockContentAccessControlHandler::checkAccessjust givesviewaccess if the block is published.If I was site builder I would filter new views to not show non-reusable blocks. Will people know to do this and to update there existing views. We could update views via an update hook to add the filter on reusable b/c all current views would be getting reusable blocks anyways.
But what about views that imported after the update hook. Would we assume they also should be updated? They could have been made before the update hook on another env which means they should get filter or they could have been made after so the filter was intentionally not added.
As far as entity reference field we can assume there are many existing entity reference fields that are set up to reference custom blocks. So in those you could now have the user be able start to select the non-reusable blocks unless we did something.
I just think if a user is placing a non-reusable block on layout page they probably have different idea about access vs adding in the custom block library. They would not expect that this block could be selected in an entity reference field on another entity and then render without view access to the entity where the non-reusable block was originally placed.
Of course there is also the case of placing the block on entity view display.
All this means that if we use the Custom block entity type we would have update
BlockContentAccessControlHandlerto have different logic based on if the entity is reusable or not.UPDATE: Added patch this #2957425-117: Allow the inline creation of non-reusable Custom Blocks in the layout builder.
Comment #6
tedbowWe are considering 2 ways of doing the same thing from the use perspective. Though they will have different side-effects the functionality of adding inline block(or block-like) content through Layout Builder will be the same in both cases.
For that reason I am going to create
\Drupal\Tests\layout_builder\FunctionalJavascript\InlineBlockTestBasethat will be the same in both cases. This way we can be sure we are comparing the same user functionality as it pertains to inline entity blocks:Both the issue have test coverage for these case but since they don't use the same base class we can't positive they will act the same way.
Comment #7
tedbowClosing this issue because after 3 weeks of discussions at Layout Initiative meetings and working on the 3 issues that are mentioned in summary #2957425: Allow the inline creation of non-reusable Custom Blocks in the layout builder was determined to be the best method.
Making another entity type behave like Custom Block types would be too complicated and require updates to current custom code.
Comment #8
tedbowMaybe I closed this to early
@larowlan the maintainer of the block_content has some reservations about #2976334-37: Allow Custom blocks to be set as non-reusable adding access restriction based on where it was used..
In general if it is general discussion about the best way to accomplish this in layout_builder then we can discuss it here.
For the actual patch in #2976334 we can discuss in that issue.
Site Building
I still think using existing block_content entity type would be the best site building experience.
People were very excited for field-able blocks in Drupal 8. I think part of this was the fragmentation in Drupal 7 contrib around this problem.
We had Fieldable Panel Panes, Beans and Boxes. It would be nice if in core we consolidate around 1 type so that site builders could manage the fields for this type of thing in 1 place.
Migrations
Fieldable Panels Panes already has on their project page:
Bean has:
Presumably that means there are already migrations built for this case. Probably the existing entities of these types would be reusable blocks but what would the migration paths migrate the bundles to? Both, if so then would it be the site-builders responsibility to keep them in sync?
Comment #9
tedbowClosing again.
Chatted with @larowlan and his now fine with using the Custom Block entity type for this(dependent on some changes I will add to #2976334: Allow Custom blocks to be set as non-reusable adding access restriction based on where it was used. that will simplify the access changes)
Comment #11
tim.plunkettRetroactively tagging