Technical overview of Gutenberg integration

To better understand how we can integrate Gutenberg into WordPress, it’s crucial to know how the Gutenberg plugin is organized.

JavaScript Packages

The Gutenberg plugin is mostly a JavaScript application composed of several packages. Each one of these packages is:

  • Generic and available as an npm package.
  • The Gutenberg Plugin registers each package as a WordPress script.
  • The Gutenberg Plugin makes the public API of each package available in the wp global variable.
  • If a package is dependent on another one, it consumes it as a global variable and adds it as a dependency of the WordPress registered script.
  • A package can have one or multiple CSS stylesheets.

For example:

A @wordpress/components npm package is registered in the plugin as a wp-components WordPress script; its API is available in the wp.components global variable; and depends on @wordpress/element.

In turn, @wordpress/element‘s script is wp-element and is consumed by @wordpress/components in the bundled script as wp.element.

Bootstraping the editor’s page

To display the editor’s page we call wp.editPost.initializeEditor from the higher-level wp-edit-post package. This function takes as arguments the post to be edited and some editor settings.

This call is made when loading the edit.php page localizing the required arguments and enqueuing the wp-edit-post script.

REST API endpoints

Once the editor’s page rendered, all the communication with WordPress happens using REST API calls. In addition to the regular REST API endpoints to fetch, update and delete taxonomies, posts, etc., Gutenberg adds new REST API endpoints that include:

  • Autosaving endpoint.
  • Reusable Blocks endpoint.
  • Root endpoint for site settings.

Many other tweaks have been necessary in existing endpoints (taxonomies, embeds, permalinks, post search, etc) and most of these have been merged in the previous 4.9.* releases.

MetaBoxes

To support MetaBoxes, Gutenberg hooks initially render the content of the MetaBoxes in a hidden DOM node rendered using a PHP script. We also hook into the post.php call to persist the MetaBoxes save call.

Summary

So, as a high-level picture, the Gutenberg plugin is composed of:

  • JavaScript scripts and styles.
  • A PHP file to bootstrap the editor in edit.php.
  • REST API endpoints.
  • PHP utilities to parse, register and render blocks on the front-end.
  • PHP script to inject the MetaBoxes into the page and hooks to save the MetaBoxes.

Integration Process

In previous JavaScript meetings, we discussed the packages integration approach:

Since the JavaScript scripts are built as reusable npm packages, we’ll consume them in WordPress like any other npm package:

  • Adding a dependency in Core’s package.json.
  • Exporting the wp.* globals in enqueue scripts inside WordPress Core.
    • Example: wp.components = require( '@wordpress/components' );
  • Moving the script registration corresponding to each package into wp-includes/script-loader.php.

Scripts like wp.shortcodewp.a11y.speakwp.utils.WordCount can be replaced by their corresponding npm packages. This has already been proposed for the shortcode package and should continue for other packages.

The work being done in #core-js meetings to align the JavaScript guidelines (code style) between Gutenberg and Core would result in a formal @wordpress/eslint-preset package that should be used as a replacement for the current JSHint config.

The REST endpoints should be moved to the regular REST endpoints location in WordPress Core wp-includes/rest-api/endpoints.

The PHP utilities and classes should be moved to wp-includes.

Some minor tasks are also left to do in the Gutenberg repository:

  • Drop the Gutenberg name from all the PHP APIs still using it.
  • Finalize the block-library and edit-post packages:
    • HTML Block and Freeform block to be moved to the npm packages.
    • The creation of the edit-post package.

Test Suite

The e2e tests are crucial to avoid regression when making updates to WP-Admin. The e2e test infrastructure and the tests themselves should be moved to WordPress Core and their stability can be considered a metric for the success of the integration process.

Unit tests, in general, live next the code being tested. For packages, these will stay in the Gutenberg repository and, for the files moved to Core, the tests will follow.

What about the Gutenberg Plugin?

After WordPress 5.0 is released, the Gutenberg plugin will continue to exist. Its purpose will be changed to the development and the maintenance of the WordPress npm packages, including the editor itself, and will also serve to develop the second phase (site customization) of the Gutenberg project. Plugin updates will continue to be released during the 5.0 cycle.

The PHP part of the plugin won’t be needed anymore, as the plugin will just register new versions of the scripts of the packages to replace the ones already registered by Core.