Defining Content–Block Areas

One of the major projects from this year’s focuses is to expand the block editor beyond the content area and into other parts of the site. This included, so far, explorations to bring blocks into other screens within the dashboard as well as converting existing widgets into blocks. One of the remaining things to figure out is the specification of content areas themselves. In this post I’d like to start discussing what content areas are and present an example of how it can tie several concepts of phase two of Gutenberg together.

What Are Content Areas?

In its simplest form, content areas represent parts of a site where blocks can be added and manipulated. Since content has a very specific meaning in WordPress already, we can also refer to these as block areas more generally to avoid opaqueness. Block areas would include headers, footers, sidebars, and any other meaningful template part outside of the post content that contains blocks.

The concept of block areas helps provide a way to meaningfully organize blocks within a full page, but is also a way to differentiate between global elements (navigation, site title, and so on) and local elements (the main content of a post, page, or custom post type).

This proposition groups the general Gutenberg roadmap into the following three ideas — how blocks are organized within the main content area, how block areas are organized within the page, and how pages are organized within the site.

Phase one focused, for the most part, on the first idea. The following video tries to illustrate aspects of the second formulation.

Showing how block areas can be organized within the page, with some blocks from the Kioken library making an appearance.

Let’s dissect what is going on a bit more in detail — this will be a fairly technical overview.

Block Areas

Displaying a "header" block area as a single editor view.

Technically, block areas are defined as individual entries in a wp_template custom post type. These structural units can hold any number of blocks and have loose semantics. Also within wp_template are special root templates that can aggregate various block areas. Areas are equivalent to the general use of template parts in themes for this scenario.

wp:area { id: "header" }
    wp:site-title
    wp:navigation
    wp:paragraph { content: "Hello, world!" }
wp:area { id: "post" }
    wp:post-title
    wp:post-date
    wp:post-content

They exist as their own retrievable entries (from `wp_template`) and can be combined within larger template units, providing both conceptual separation and a potentially unified editing flow at the same time. The editor application is capable of saving the different elements to the right places.

Areas can contain general blocks or context-specific blocks (like “post title”, “post date”, and “post content”), making it possible to have more complex theme layouts and designs. In this context, any block offered by WordPress can be a widget in that it could be added to global areas of a site.

Block areas can only be used directly within templates and are not accessible in regular editing sessions. (These are equivalent to theme-editor responsibilities.) The content of block areas, however, becomes easy to edit in a familiar block-editing environment. It is important, then, to distinguish the ability to modify what block areas contain and the ability to insert and define block areas themselves.

It is worth noting that block areas are initially indifferent to where data is sourced and have a non-dependant relationship with editor providers. That means they can define the structure of a theme or layout but don’t deal with granular data allocation; only the blocks used within determine where specific data is allocated. (For example, a Site Title block would be saving its content to the relevant site option regardless of whether it is inserted in a header block area or a footer block area.)

The block navigator can identify different template parts and their contents.

An editor view that understands block areas would be able to display a site design either entirely or in parts. While being able to display areas together is crucial for a faithful representation of the design, the system is still able to separate and orchestrate how data is saved, keeping clear boundaries between local and global content, and allowing flexibility in representing dynamic content. Since block areas are internally blocks defining an inner blocks group they can be exposed through the regular block navigator and identified by display name.

It’s not the most important right at this time to dwell on the implementation details of how a template is defined by a theme declaration, as this could be established through a PHP structure or JSON objects (internationalization is a good subject to keep in mind here) while the anatomy of block areas remains equivalent.

// Example of a root template using various block areas.
{
  "slug": "single",
  "content": [
     [ 'theme/header' ],
     [ 'core/paragraph', { content: "Some content..." } ],
     [ 'core/post' , {}, [
         [ 'core/post-title' ],
         [ 'core/post-content' ],
     ] ]
     [ 'theme/footer' ],
  ]
}

In the example above the `theme/footer` is not a real block but something that gets swapped with a `core/template-part` referencing the corresponding block area.

With this specification, the full layout and design of a given page can be represented through blocks and block areas.

Open questions:

  • Looking further into the future, should wp_templates reflect the current template hierarchy? Example: an entry with an archive slug would map to how archive.php operates today and so on. What would this unlock for users that was harder to do before? (Easy customizations for specific category pages, for example.)
  • How should declaration work from a theme perspective? What would be the most idiomatic in the current paradigm? What would offer most convenience for the future?
  • How can we incorporate more granular add_theme_support into the areas so that color palettes, content widths, etc, are more refined and contextual?
  • Is it worth establishing common semantic areas for added portability? Current templates can be validated and there could also be transformation tools (same as block to block, block area to block area).

Relevant Issues:

Full-Page Editing

The “selector” presentation in the header of the demo is merely a convenient prototype tool and not an implementation proposal.

While block areas provide the structure to handle global elements, the editor also needs to understand how to work with them. There are largely two possibilities: a single editor that could handle all block areas together —providing a comprehensive full view of the site— or multiple editor views for each specific area.

Since each block area is effectively a post-entry, it is already easy to edit them in a regular Gutenberg session. However, as shown in the video, we can also augment the editor so that it can combine all the block area definitions from a template together in a single editing session, providing a comprehensive view of the full page.

Modes allow to explore various configurations and aspects of the editing session, such as focusing on certain areas (the post and its content, the header, sidebar, or footer in this example) and tailor tools to each task at hand. They can also control what is editable and what is locked down, providing the most convenient tools and interactions for each context. We could imagine a site-building mode that exposes more advanced theme tools, or a design mode that helps with alignment issues, balance, and document semantics.

Editing modes can also take into account the currently available block areas to expose specific modes centered around each of these template parts. These views can potentially take over many of the dedicated appearance menus.

While in “writing” mode, only the post properties are saved, whereas full-site editing orchestrates saving not just the content but also each individual template part plus the container template together.

Modes could also be extended by plugins to cover other editorial needs, like toggling between member / non-member states, ads / no-ads, and could also help as a presentational foundation for multi-language in the near future.

Open questions:

  • How should saving work from a UX perspective when there are multiple blocks with global data?
  • Should modes be toggleable within an editing session or should they be isolated to full page views (like the customizer)? (Full-site editing, design mode, etc, could all be part of a specific admin section like the customizer is now.)
  • Implicit relationships between modes and user roles.

Relevant Issues:

  • Selection Tools –17088.
  • Expanding editor beyond post_content –16281.
  • [Explore] Template mode and declarative post blocks: –17263.

Entities & Sources

With block areas handling global elements there is a need to access and manipulate site-wide data from individual blocks and for the editor application to centrally orchestrate its saving mechanisms. The goal is to eliminate the need for block authors to have to handle update mechanisms for non-HTML data.

For this purpose, the current data entities system would absorb more responsibilities and allow blocks to have bindings with data sourced from multiple places in WordPress including sourcing and updating. The block can then consume it as any regular attribute and doesn’t have to handle requests or saving operations. This stays true to the fact that blocks define primarily an interaction model, not a data model.

The architecture of entities has been iterated multiple times already and is meant to be low level so we can do all these optimizations and streamline block declaration.

This mechanism is used in the demo to create a “Site Title” block which operates like any other block in the page, yet doesn’t save to the document HTML source but to the proper site option. These attributes are synchronized from the entity value, so if the block appears multiple times (like showing the title both in the header and the footer of the site) they are kept in sync and reflect all edits within the session. The goal is arriving at a declarative API for custom entity blocks that allows the editor to handle saving the block harmoniously in the same saving flow as everything else.

Relevant Issues:

  • Updating the store to use Core Data entities –16932.
  • Implementing EntityProvider and using it to refactor custom sources –17153. (This work also provides a considerable performance boost.)
  • Add a Site Title block and required functionality –17207.

If you’d like to help with any of these three efforts, join the conversations on GitHub or in Slack at #core-editor!

#gutenberg