Gutenberg: Expanding the Editor outside of post_content

Created on 25 Jun 2019  路  8Comments  路  Source: WordPress/gutenberg

One of the main important requirements to build a full site editing experience is the ability, for the block editor to edit both the post/page object and its associated block template at the same time.

The current implementation of the EditorProvider component makes an important assumption that need to be reconsidered:

  • Parsing and hydrating changes are highly coupled with the post_content post object's property.

For full site editing, the list of blocks to be edited is extracted from the template object instead and "augmented" using the blocks stored in post_content if needed (if a core/post-content block is used in the template).

The initial step to achieve the required flexibility here is to consider the editor screen as it exists today as an editor built around a frozen block template composed of two blocks: A post title block and a post content block.

const template = [ 
  { name: 'core/post-title' }, { name: 'core/post-content' } 
];

const post = { title, content, ... };

const Editor = <EditorProvider template={template} post={post}><BlockList /></EditorProvider>

Related #16075 #13489

Framework [Feature] Full Site Editing [Type] Task

Most helpful comment

I think this issue can be closed now. For the FSE work refer to #20791 now.

All 8 comments

I'd love to see this extended to the "post header" area. The screenshot below is from one of my blog posts. What I've been doing is faking a post header block by creating a custom page template that doesn't show the post header. Then, I re-add a h1 Heading block in the post content.

The problem with this method is my entry byline/meta disappears unless I manually add that too.

What we need is an opt-in for themes to have post header support. And, the entire post header area needs to be considered, not just the post title.

gb-post-title-block-002

@justintadlock indeed, that's next to come. We'd need to figure out the best way to store these template parts and the best way to handle editing while saving to different sources (global and local). Starting with the title only helps constrain the context to just the post, so we don't yet need to solve global content.

It'd be good to start formalizing how the template parts should be represented (block areas / theme areas) separately, though.

I think I have a pretty clear idea of how we can move forward with this. What does everyone think of the following changes:

Persistence

Change this to save to a template CPT:

https://github.com/WordPress/gutenberg/blob/a8e96920032ab4f9ccb38c29de34f90c296ed7a7/packages/editor/src/store/actions.js#L258

Fetch and pass down the template CPT here:

https://github.com/WordPress/gutenberg/blob/0a3c5c094bea378c48d8b57fc46bb4dbcd4379d1/packages/edit-post/src/editor.js#L124

Editor Setup

Pass the template down to here:

https://github.com/WordPress/gutenberg/blob/a8e96920032ab4f9ccb38c29de34f90c296ed7a7/packages/editor/src/store/actions.js#L44

Defaulting to

[ { name: 'core/post-title', attributes: { ... } }, { name: 'core/post-content', attributes: { ... } } ]

if none is available.

It will setup the block list so that template parts become the top level blocks.

E.g.:

The default template would produce a block list with two top level blocks. Both of these would need to leverage custom attribute sources (#16282).

core/post-title would produce no markup, but it would sync its single title string attribute with the post title attribute source.

core/post-content would produce no markup, but it would sync its single content string attribute with the post content attribute source. This would contain the serialization of its innerBlocks, which will be what is currently the top level block list.

Note that the fact that these two top level blocks produce no markup is because templates are shared between posts. They will store where the post content is rendered, but not the post content itself:

<!-- wp:post-title /-->
<!-- wp:post-content /-->

Templates could also have arbitrary blocks, like for sidebars for example:

<!-- wp:post-title /-->
<!-- wp:post-content /-->
<!-- wp:group -->
    <div class="sidebar">
        <!-- wp:paragraph -->
            <p>About </p>
        <!-- /wp:paragraph -->
        <!-- wp:latest-post /-->
    </div>
<!-- /wp:group -->

They could also use reusable blocks to share content across different templates.

Next Steps

This is still kind of abstract, but I wanted to get the ball rolling on how this would be best implemented. It looks like most of the work here is in solving #16282. I will start syncing with @aduth on how this can be done. I have not started to think about that too much yet, but I'm guessing something like action hooks that can be registered for savePost would work and would not break backwards compatibility.

I'm super excited for this feature and can't wait to see it land!

This sounds like a great plan @epiqueras I'd suggest to avoid thinking about persistence at first. We could build the JS bits relying on a static template and memory updates only. This would allow us to think about how to support a "locked" template (the current UI).

@youknowriad Yeah, that was the plan. Here's what we discussed with @aduth today: https://github.com/WordPress/gutenberg/issues/16282#issuecomment-507423808.

17190

In reference to my feature request. I think that's related to this issue.

I think this issue can be closed now. For the FSE work refer to #20791 now.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

davidsword picture davidsword  路  3Comments

jasmussen picture jasmussen  路  3Comments

franz-josef-kaiser picture franz-josef-kaiser  路  3Comments

jasmussen picture jasmussen  路  3Comments

nylen picture nylen  路  3Comments