Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Overview: Custom Entity Sources #17368

Closed
epiqueras opened this issue Sep 7, 2019 · 1 comment
Closed

Overview: Custom Entity Sources #17368

epiqueras opened this issue Sep 7, 2019 · 1 comment
Assignees
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

Comments

@epiqueras
Copy link
Contributor

epiqueras commented Sep 7, 2019

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:

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:

Screen Shot 2019-09-07 at 1 52 41 PM

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:

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:

<EntityProvider kind="site" type="root">
  <EntityProvider kind="postType" type={ post.type } id={ post.id }>
    { children }
    <InnerBlocks />
  </EntityProvider>
</EntityProvider>

A few nice hooks for leveraging entities:

const id = useEntityId( 'postType', 'post' );
const [ content, setContent ] = useEntityProp( 'postType', 'post', 'content' );
const [ isDirty, isSaving, save ] = useEntitySaving(
  'postType',
  'post',
  'content'
);

And controlled inner blocks:

<InnerBlocks
  value={ blocks }
  onChange={ setBlocks }
  onInput={ setContent }
/>

These APIs were implemented and leveraged in the following PRs:

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.

  • Undo (Fix: Block Editor: Fix undo level inconsistencies. #17259): There are some inconsistencies in how the block editor marks edits as persistent that need to be corrected. The first character in a typing sequence is being marked as persistent, and there is an extra undo level between sequences. These issues were somehow not surfacing before or maybe we just never noticed them because the tests don’t cover them. The editor did have extra logic surrounding undo levels. Now it just does what the block editor tells it to do. We should also expand the undo e2e tests to catch issues like these.
@youknowriad
Copy link
Contributor

Closing this as most of this is already merged and working.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
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
Projects
None yet
Development

No branches or pull requests

2 participants