Problem/Motivation
When you create a Custom Block entity, a Block Plugin definition is derived and is available anywhere Block Plugin definitions are listed. This makes a lot of sense when Custom Blocks are meant to be re-used, for example you may want a "Logo" Custom Block on many pages in different regions.
However when using Custom Blocks within the Layout Builder the current functionality has many problems:
UX
Currently to add a custom block to a Layout the user would have to
- Navigate to the custom block page
- Create the block
- Navigate back to the layout builder
- Click Add block
- Find the block they just created.
Access Control
If we allow inline block creation a user who creates a custom block on the Layout Builder for an access controlled entity probably expects only those that can view the entity that has the Layout to be able to view the custom block.
Currently blocks have no connection on an access level to where they are placed so this block would be able to placed via the block admin page, if you listed the block in a View or it was referenced in an Entity Reference value anyone would be able to see it.
Performance
When using something like Panels or Layout Builder, Custom Blocks are often only meant to be used once. If you're building out hundreds of pages you could end up with thousands of Custom Blocks and lead to performance issues. These blocks would be shown every place you are able to pick a block including the layout builder and the current block place listing.
Revision
Currently if you placed a block via the Layout Builder there is no connection between the revision of the block and revision of the entity with the Layout. If you updated a custom block all previous revisions of the entity with the layout would display the update version.
Deletion
If a custom block is deleted then it would be removed from all placements via the Layout Builder across all revisions.
Proposed resolution
Add the ability for users to create custom non-reusable blocks from within the Layout Builder. These blocks will be the same entity type as Custom Block provide by the block_content
module therefore all the site's current block types will be available from within the Layout Builder.
The non-reusable blocks will only be viewable within the context of the layout that they were placed in. For layout entities where the bundle is set to create a new revision for each update the changes to custom inline blocks will be tracked with the parent entities revision.
The new custom inline blocks should be "owned" by the layout that they are placed in in that they should *not* be editable or deleted from outside of the layout builder.
Implementation
In #2976334: Allow Custom blocks to be set as non-reusable adding access restriction based on where it was used. but included here in combined patch, review the do-not-test.patch for this issue.
See that issue Custom Block related implementation.
For integration with Layout Builder, we should create a new Block Plugin that stores Custom Block revision IDs and implement an inline form for creating and editing these Custom Blocks. All inline blocks created with this plugin will be non-reusable.
A simple database backed usage tracking service will be created to track usage of the inline custom blocks. These inline custom blocks will only ever 1 parent so it was determined that it does not need generic usage tracking
@see #2976366: Create generic entity usage tracking service
Remaining tasks
Write a patch to explore the feasibility of this approach.
Write tests
Review
User interface changes
Users would be able to create Custom Blocks inline from the Layout Builder. These blocks would not be available in the Custom Block library.
API changes
API changes needed for this change are being made in #2976334: Allow Custom blocks to be set as non-reusable adding access restriction based on where it was used.
Data model changes
Data model changes needed for this change are being made in #2976334: Allow Custom blocks to be set as non-reusable adding access restriction based on where it was used.