Discover Gutenberg: WordPress’ Latest Editor Guide

Gutenberg, an ambitious project that will arguably change WordPress in many ways and would affect both regular end-users and developers.

Gutenberg is a new editor for WordPress that will totally replace the current TinyMCE-powered editor. It is an ambitious project that will arguably change WordPress in many ways and would affect both regular end-users and developers, specifically, those who depend on the editor screen for working on WordPress. Here is how it looks.

Gutenberg Editor with sidebar on the right opened and a block option is displayed
It’s obvious that it’s inspired by the Medium editor UI.

Gutenberg also introduces a new paradigm in WordPress called “Block”.

“Block” is the abstract term used to describe units of markup that are composed form the content or layout of a webpage. The idea combines concepts of what in WordPress today we achieve with shortcodes, custom HTML, and embed discovery into a single consistent API and user experience.

Setting Up the Project

Knowing the fact that Gutenberg is built on top of React, some developers are worried that the barrier is too high for entry-level developers for developing Gutenberg.

Setting up React.js could be quite time-consuming and confusing if you’ve just getting started with it. You’ll need at least, JSX transformer, Babel, depending on your code you might need some Babel plugins, and a Bundler like Webpack, Rollup, or Parcel.

Fortunately, some people within WordPress community stepped-up and are trying to make developing Gutenberg as easy as possible for everyone to follow. Today, we have a tool that will generate a Gutenberg boilerplate so we can start writing code right away instead of befuddling with the tools and the configurations.

Create Guten Block

The create-guten-block is an initiate project by Ahmad Awais. It’s a zero-configuration tool kit (#0CJS) that will allow you to develop Gutenberg block with some modern stacks preset including React, Webpack, ESNext, Babel, ESLint, and Sass. Follow the instruction to get started with Create Guten Block.

Using ES5 (ECMAScript 5)

Using all these tools to create a simple “hello-world” block might seem just too much. If you like to keep your stacks lean, you can actually develop a Gutenberg block using a plain good ol’ ECMAScript 5 that you might already have familiarity with. If you have WP-CLI 1.5.0 installed on your computer, you can simply run…

wp scaffold block <slug> [--title=<title>] [--dashicon=<dashicon>] [--category=<category>] [--theme] [--plugin=<plugin>] [--force]

…to generate the Gutenberg block boilerplate to your plugin or theme. This approach is more sensible, particularly, for existing plugins and themes that you’ve developed before the Gutenberg era.

Instead of creating a new plugin to accommodate the Gutenberg blocks, you might want to integrate the blocks to your plugins or the themes. And to make this tutorial easy to follow for everyone, we’ll be using ECMAScript 5 with WP-CLI.

Registering a New Block

Gutenberg is currently developed as a plugin and will be merged to WordPress 5.0 whenever the team feels it’s ready. So, for the time being, you will need to install it from the Plugins page in wp-admin. Once you have installed and activated it, run the following command in the Terminal or the Command Prompt if you’re on a Windows machine.

wp scaffold block series --title="HTML5 Series" --theme

This command will generate a Block to the currently active theme. Our Block will consists of the following files:

.
├── series
│   ├── block.js
│   ├── editor.css
│   └── style.css
└── series.php

Let’s load the main file of our blocks in the functions.php of our theme:

if ( function_exists( 'register_block_type' ) ) {
	require get_template_directory() . '/blocks/series.php';
}

Notice that we enclose the file loading with a conditional. This ensures compatibility with previous WordPress version that our block is only loaded when Gutenberg is present. Our Block should now be available within the Gutenberg interface.

This how it looks when we insert the block.

Gutenberg APIs

Gutenberg introduces two sets of APIs to register a new Block. If we look at the series.php, we will find the following code that registers our new Block. It also loads the stylesheet and JavaScripts on the front-end and the editor.

register_block_type( 'twentyseventeen/series', array(
    'editor_script' => 'series-block-editor',
    'editor_style' => 'series-block-editor',
    'style' => 'series-block',
) );

As we can see above, our Block is named twentyseventeen/series, the Block name must be unique and namespaced to avoid collision with the other Blocks brought by the other plugins.

Furthermore, Gutenberg provides a set of new JavaScript APIs to interact with the “Block” interface in the editor. Since the API is quite abundant, we’ll be focusing on some specifics that I think you should know to get a simple yet functioning Gutenberg Block.

wp.blocks.registerBlockType

First, we will be looking into wp.blocks.registerBlockType. This function is used to register a new “Block” to the Gutenberg editor. It requires two arguments. The first argument is the Block name which should follow name registered in the register_block_type function in the PHP side. The second argument is an Object defining the Block properties like title, category, and a couple of functions to render the Block interface.

var registerBlockType = wp.blocks.registerBlockType;

registerBlockType( 'twentyseventeen/series', {
    title: __( 'HTML5 Series' ),
    category: 'widgets',
    keywords: [ 'html' ],
    edit: function( props ) { },
    save: function( props ) { }
} );

wp.element.createElement

This function allows you to create the element within the “Block” in the post editor. The wp.element.createElement function is basically an abstraction of the React createElement() function thus it accepts the same set of arguments. The first argument takes the type of the element for example a paragraph, a span, or a div as shown below:

wp.element.createElement('div');

We can alias the function into a variable so it’s shorter to write. For example:

var el = wp.element.createElement;
el('div');

If you prefer using the new ES6 syntax, you can also do it this way:

const { createElement: el } = wp.element;
el('div');

We can also add the element attributes such as the class name or id on the second parameter as follows:

var el = wp.element.createElement;
el('div', {
    'class': 'series-html5',
    'id': 'series-html-post-id-001'
});

The div that we created would not make sense without the content. We can add the content on the argument of the third parameter:

var el = wp.element.createElement;
el('p', {
    'class': 'series-html5',
    'id': 'series-html-post-id-001'
}, 'This article is part of our "HTML5/CSS3 Tutorials series" - dedicated to help make you a better designer and/or developer. Click here to see more articles from the same series' );

wp.components

The wp.components contain a collection of, as the name implies, the Gutenberg components. These components technically are React custom components which include the Button, Popover, Spinner, Tooltip, and a bunch of others. We can reuse these components into our own Block. In the following example, we add a button component.

var Button = wp.components.Button;
el( Button, {
    'class': 'download-button',
}, 'Download' );

Attributes

The Attributes is the way to store the data in our Block, this data could be like the content, the colors, the alignments, the URL, etc. We can get the attributes from the Properties passed on the edit() function, as follows:

edit: function( props ) {
    var content = props.attributes.seriesContent;

    return el( 'div', {
        'class': 'series-html5',
        'id': 'series-html-post-id-001'
    }, content );
}

To update the Attributes, we use the setAttributes() function. Typically we would change the content on certain action such as when a button is clicked, an input is filled, an option is selected, etc. In the following example, we use it to add a fallback content of our Block in case something unexpected happened to our seriesContent Attribute.

edit: function( props ) {

    if ( typeof props.attributes.seriesContent === 'undefined' || ! props.attributes.seriesContent ) {
        props.setAttribute({
            seriesContent: 'Hello World! Here is the fallback content.'
        })
    }

    var content = props.attributes.seriesContent;

    return [
        el( 'div', {
            'class': 'series-html5',
            'id': 'series-html-post-id-001'
        }, content ),
    ];
}

Saving the Block

The save() function works similarly to the edit(), except it defines the content of our Block to save to the post database. Saving the Block content is quite straightforward, as we can see below:

save: function( props ) {

    if ( ! props || ! props.attributes.seriesContent ) {
        return;
    }

    var content = props.attributes.seriesContent;

    return [
        el( 'div', {
            'class': 'series-html5',
            'id': 'series-html-post-id-001'
        }, content ),
    ];
}

What’s Next?

Gutenberg will change WordPress ecosystem for the better (or possibly the worse). It enables developers to adopt a new way of developing WordPress plugins and themes. Gutenberg is just a start. Soon the “Block” paradigm will be expanded to other areas of WordPress such as the Settings APIs and the Widgets.

Learn JavaScript Deeply; it’s the only way to get into Gutenberg and stay relevant to the future in WordPress industry. If you’re already familiar with the JavaScript basics, the quirks, the functions, the tools, the goods and the bads, I’m really sure you will get up to speed with Gutenberg.

As mentioned, Gutenberg exposes an abundance of APIs, enough to do almost anything to your Block. You can choose whether to code your Block with a plain old JavaScript, JavaScript with ES6 syntax, React, or even Vue.

Ideas and Inspirations

I’ve created a very (very) simple Gutenberg Block that you can find in the repository of our Github account. Furthermore, I’ve also put together a number of repositories from where you can drive inspiration on building a more complex Block.

Further Reference

WebsiteFacebookTwitterInstagramPinterestLinkedInGoogle+YoutubeRedditDribbbleBehanceGithubCodePenWhatsappEmail