Even if you already know the libraries used by Gutenberg, it can still feel daunting to get started. We share a number of tips to help make it easier.
PHP developers can find it daunting to code for Gutenberg, the new WordPress editor, since it requires deep knowledge of React and JavaScript.
That was my own experience when I starting building my first block several months ago. Even though I’m still a ways away from mastering the languages, I’ve been able to somewhat adapt to the new paradigm and have succeeded in producing several blocks.
In this article, I will share several tips to understand what to pay attention to when coding for Gutenberg.
My main way for learning how to do something in Gutenberg is by checking how the Gutenberg team is doing it, mostly by checking the code in the repo.
Even if we already know React, JavaScript, Redux, webpack, or any of the libraries used by Gutenberg, it is highly advisable to check the code in the repo. Gutenberg provides a layer of abstraction on top of the libraries it depends on, and several of its functionalities only work in a way specific to Gutenberg.
That is the case, for instance, for interacting with the data store, done through package @wordpress/data
. Even though this package is implemented on top of Redux, it incorporates several important differences with it, so having experience using Redux from a prior project may still not be enough to know how to use it within Gutenberg.
Any functionality implemented for Gutenberg is also available for our own use. It is a good idea to be a heavy user of the WordPress editor, exploring all of its screens and user interactions, to discover and experiment with these functionalities and decide whether to port them to our own plugins.
For instance, I noticed the welcome screen shown the first time the user interacts with the WordPress editor:
WordPress editor welcome screen.
I thought this user interaction was very practical to display user documentation, so I decided to port it over to my own plugin.
To find the code, I searched for string "In the WordPress editor, each paragraph, image, or video"
(which appears on the editor’s welcome guide), which produces file packages/edit-post/src/components/welcome-guide/index.js
with this code:
// imports...
// ...
export default function WelcomeGuide() {
// ...
return (
<Guide
className="edit-post-welcome-guide"
contentLabel={ __( 'Welcome to the block editor' ) }
finishButtonText={ __( 'Get started' ) }
onFinish={ () => toggleFeature( 'welcomeGuide' ) }
>
<GuidePage className="edit-post-welcome-guide__page">
<h1 className="edit-post-welcome-guide__heading">
{ __( 'Welcome to the block editor' ) }
</h1>
<CanvasImage className="edit-post-welcome-guide__image" />
<p className="edit-post-welcome-guide__text">
{ __(
'In the WordPress editor, each paragraph, image, or video is presented as a distinct “block” of content.'
) }
</p>
</GuidePage>
/* More <GuidePage> components */
/* ... */
</Guide>
);
}
I copy/pasted the code from the repository to my plugin and edited it to suit my needs. The result ended up being very satisfactory:
Reusing the welcome guide for my own plugin.
Gutenberg’s documentation is found in the Block Editor Handbook. It is not yet thorough, which makes it difficult for beginners to start coding for Gutenberg.
For instance, I got the following impressions when learning from it:
Even though it has plenty of room to improve, the existing documentation can still be very helpful. So do browse all of the documentation, reading it a few times until things start clicking. And whenever it is not good enough concerning some topic, try to fill the blanks by learning from the code in the repository, as much as possible.
@wordpress/create-block
package to scaffold a new block@wordpress/create-block
is a tool for scaffolding new blocks, maintained by the Gutenberg team. I described how to use this package in my previous article, Setting up your first Gutenberg project.
Gutenberg is based on React, a JavaScript library for building user interfaces described through components. A component is a JavaScript class or function intended to render some specific interface and customize it through properties. It is also composable, i.e., a component can contain another component, thus reusing its code.
Gutenberg is based on blocks, where a block is a high-level React component with certain features (for instance, its attributes are saved to the database). Thus, it follows that blocks can be composed of components (and blocks can also contain nested blocks, but this is a different matter).
Even though Gutenberg is seemingly all about blocks, there are certain situations where we interact with Gutenberg not through blocks, but through components.
For instance, the welcome guide shown earlier displays user documentation in a modal window and is triggered via a link placed in the Document TabPanel:
Sidebar panel.
Creating this panel is accomplished through <PluginDocumentSettingPanel>
, which is a component, not a block:
import { registerPlugin } from '@wordpress/plugins';
import { PluginDocumentSettingPanel } from '@wordpress/edit-post';
const WelcomeGuidePluginDocumentSettingPanel = () => (
<PluginDocumentSettingPanel
name="welcome-guide"
title="Welcome Guide"
className="welcome-guide"
>
/* Link to open the modal window */
/* ... */
/* Modal window */
/* ... */
</PluginDocumentSettingPanel>
);
registerPlugin( 'welcome-guide-plugin-document-setting-panel', {
render: WelcomeGuidePluginDocumentSettingPanel,
icon: 'welcome-view-site',
} );
Would it be possible to satisfy the same use case — i.e., showing documentation to the user right in the editor — using a block? Let’s check this out.
We could have a block with an accordion element right at the top of the editor, initially closed:
Accordion with user documentation, initially closed.
When clicking on it, it would open and display the user documentation, in this case via a video embedded from Vimeo:
Accordion with user documentation, now open.
However, this scheme wouldn’t work out because a reference to the block (and its data, unless it’s a reusable block) is stored in the database entry for that post. Then, at least one of the following issues would take place:
core/html
block and initialize it with its inner HTML through a template, but this doesn’t work because the template only allows us to define attributes, not content. Even if it did work, passing the HTML to implement an accordion (which requires CSS and maybe some JavaScript, too) through the template would be a hack#php #wordpress #javascript #react #developer