Overview: Custom Entity Sources #17368
Labels
Framework
Issues related to broader framework topics, especially as it relates to javascript
[Type] Overview
Comprehensive, high level view of an area of focus often with multiple tracking issues
Milestone
This issue is to serve as a live recap of the work being done to support editing beyond the post content.
The merged and pending final PRs are all here: https://github.com/WordPress/gutenberg/pulls?q=is%3Apr+author%3Aepiqueras+project%3AWordPress%2Fgutenberg%2F13
Keep reading to understand how everything fits together.
Context 📔
Phase 2 (#13113) of Gutenberg paves the way for an expansion of the block editor beyond post content (#16281). Over the last few months, efforts have been undertaken to integrate the block editor in the Widgets screen and in the Customizer, while block areas seek to expand template editing (#13489).
It becomes apparent that therein lie two challenges: supporting a multitude of use cases and data sources — as blocks are no longer assumed to always make up
post_content
— and providing a clear and robust API that can accommodate said multitude.The Solution ✅
Handling Entities 👐
In stepping around our code and discussing lots of different potential implementations, we realized that a lot of the complexity in prototypes came from trying to switch between editing one set of posts, e.g. some template parts and an actual post, to another set of posts. It was hard to keep things like edits, change detection, and undo levels, in sync. But we already had an abstraction built for that: the core data store's entities. Having grown with a focus on single posts, most of the code in the editor wasn’t using that abstraction, and instead directly interfaced with the API for regular posts. We needed to refactor this before we could move forward.
The following PRs took care of abstracting away and replacing all of the manual post handling in the editor into core data entities:
saveEntityRecord
. #17030: Core Data: Return updated record in saveEntityRecord.A Declarative API for Custom Entity Blocks 🗒
With the foundation ready, we needed to decide on an API for creating blocks that sync with different entities. So that for example, a block layout like the following could be achieved:
This will be super useful even beyond the context of block areas. It expands the scope of use cases in which blocks can remain purely interaction models, agnostic to sourcing and updating of any non-HTML data.
Trials 💡
There were quite a few ways to go about it. There was the possibility of extending the custom sources implementation (#16402) to also operate on inner blocks. But that only led us to discuss how unnecessarily complex custom sources were and mark them for refactoring (which the final version of the new API easily did). Among other notable approaches were:
EntityHandlers
component and basic template blocks. #17020: An algebraic-effects-inspired API for blocks to throw persistence effects that were handled by the nearest parent with a registered handler. This was nice, but unnecessarily complex, like custom sources.EntityProvider
, controlledInnerBlocks
and basic template blocks. #17135: The best of the two previous approaches, a simple entity provider and controlled inner blocks instead of a block list split.Final API 🏁
The final API ended up looking a lot like #17135.
It introduces a declarative and composable entity provider with dynamic entity type-kind-specific context creation:
A few nice hooks for leveraging entities:
And controlled inner blocks:
These APIs were implemented and leveraged in the following PRs:
EntityProvider
and use it to refactor custom sources with a backwards compatibility hook for meta sources. #17153: Starts implementing the API and uses it to refactor custom sources away for a 20% typing performance speed up.Known Issues ❗️
A few issues that were previously mitigated by some of the editor store’s functionality have now surfaced and we need to fix them ASAP. At this point of maturity in the project, and with WordPress 5.3 in sight, we can’t afford any regressions.
The text was updated successfully, but these errors were encountered: