How to Adapt Your Plugin for Gutenberg: Part 1 (Block API)

The story is straightforward; Gutenberg is the new editor experience in WordPress, which is going to be merged into core in the next major release. A lot of plugins that do not keep up with this will become obsolete. This makes it essential that you adapt your plugin for Gutenberg before it’s too late.

Who’s affected?

Almost all the plugins that have anything to do with the post editor will be affected by Gutenberg. For example, if your plugin adds a button in TinyMCE to then place a shortcode in the editor, bad news; it will be the end of it.

“Do I need to adapt my plugins for Gutenberg?”

So which plugins need updating for Gutenberg? Any plugins that work with:

Custom metaboxes

Shortcodes

TinyMCE buttons

or any editor feature at all

While some plugins will still work with Gutenberg, like a plugin that adds a simple metabox, for instance, it will not be as smooth an experience for your users.

Even shortcodes will keep working as before, but it will just be plain text node in the editor, while all the shortcode plugins for Gutenberg will follow its block UI and will be easier for users to use.

So yes, users will prefer plugins that are crafted for the Gutenberg experience. And the ones to stay behind will be replaced by a competitor plugin.

Just to give you an idea, here’s an example of what the user’s standard old-editor experience looks like with a plugin of ours (a), and then what it looks like in Gutenberg (b) – with the plugin optimized for it.

(a)

(b)

Fear not! We are here to help you with making your plugins Gutenberg-ready. There are many ways to integrate your plugin towards Gutenberg, depending on how your plugin works, which we are going to be discussing in this article.

Things worth knowing beforehand

Gutenberg is written on React. And Gutenberg plugins are coded in JavaScript, which also can be a rough transition for developers who only code in PHP. While you don’t need to have knowledge of React to make plugins for Gutenberg, you will need some basic understanding of JavaScript. If you have previously worked on React and JSX then it will be similar grounds for you.

While there’s not enough official documentation for Gutenberg, its Github repository has a lot of valuable information for developers. If you want to learn Gutenberg development deeply, you must keep your eyes open on everything that is going on in Gutenberg’s GitHub repository because the project is moving really fast, and things are changing every single day.

How to adapt your plugin for Gutenberg

Gutenberg’s API provides us with many ways to extend the editor, like Block API, Shortcode API, and more. Which API to use depends on what type of plugin we are building.

If your plugin is a simple shortcode plugin, then Block API can be used to make a beautiful block for the editor. But if your plugin uses complex metaboxes where a block isn’t enough, we can use Sidebar API.

Also, we will be using a modern stack of JavaScript development tools, such as NodeJS, NPM, webpack, and ESNext. We will be providing you with example files, so you don’t need to worry about setting up your development environment.

In this post, we will be looking at how to make your plugin Gutenberg-compatible by using the Block API. We’ll get into the other methods (Sidebar API, Publish Panel, Status Bar & similar APIs) in part two if needed.

Block API

Blocks are the fundamental element of Gutenberg, it being a block-based editor. Block API allows you to make blocks for Gutenberg. You can make blocks that can render basic HTML, shortcodes, or even make dynamic blocks to display, for example, your latest posts.

The process based on an existing plugin

In our example, we will adopt a Click to Tweet shortcode to a Gutenberg block. This Click to Tweet shortcode renders a Tweet Box with your text, and a button to tweet that text. Like this:

Our shortcode looks something like this:

[clicktotweet tweet="Text to be displayed" tweetsent="Text to be tweeted" button="Tweet" theme="click-to-tweet"]

Our shortcode has four parameters:

tweet: Text that appears on your site.

tweetsent: Text that goes to Twitter.

button: Tweet button text.

theme: Either click-to-tweet or click-to-tweet-alt as box theme.

Adapting plugins for Gutenberg with Block API

There are two ways of going about it with Gutenberg, either we can render the HTML to the front-end, or we can use our Gutenberg block to render the shortcode to front-end. For this article, we will be doing the latter.

We have added four dependencies to our script that we will be using in our block. Let’s learn about these dependencies first:

wp-i18n is Gutenberg’s version of internationalization functions, such as __(). wp-blocks is used for the registerBlockType function which registers your block. We use wp-editor and wp-components scripts for various components in our block.

Now that we have enqueued your assets, we can start writing our block in /src/block.js file.

Importing dependencies

If you are using Gutenberg Boilerplate then your block.js file should have a basic block structure that you can use to build plugins for Gutenberg:

As you can see, all the attributes are same as our shortcode. All attributes have a type key, which tells Gutenberg its data type. You can use string, number, boolean & object as accepted types.

Some of the attributes also contain a default value. Attributes can also have other properties, such as source and selectors, which we won’t be using in our example, but you can learn more about them here.

Edit interface

Now we will be building the edit interface of our block, which will be the display – users will see it while editing the block in Gutenberg.

To get a basic idea, we can first hard-code our block and build upon it by replacing the following area in our code:

Our RichText component has five arguments. format is a string, as we are going to use our shortcode to display the elements in the front-end. If we wanted to use a selector in our attribute, then format would have been an array.

RichText has some formatting options by default, like bold and italic, which we have disabled by passing an empty array in formattingControls argument.

placeholder is the placeholder text when there is no text in the field, and onChange will trigger onChangeTweet function when a change event takes place.

Finally, value will be the value of our field, which will be taken from tweet attribute that we defined earlier.

Once that we have defined our RichText area, we need to build onChangeTweet function which will trigger when value changes in our text field.

We pass value of RichText field to onChangeTweet function, which uses props.setAttributes function to update the value of tweet attribute.

You will see the power of Gutenberg now when you use your block.

Isn’t it awesome?

Block Inspector

When building plugins for Gutenberg, you don’t need to reinvent the wheel every time to make option panels for your plugins. Gutenberg provides us with a simplified way to allow block customization and ensures that every user has a consistent experience with built-in UI patterns.

Similarly to RichText component, InspectorControls component adds a sidebar when the block is selected. Something like this:

We will also be using TextareaControl and TextControl to add a textarea and text input field to our Inspector area.

props.isSelected checks to make sure that the Inspector only appears when the block is selected.

TextareaControl and TextControl components, similarly to RichText, have a value and onChange method.

We also need to change the code of your block display to accommodate new changes. In our case, we only need to add Button Text to our block as Tweet Text will be added to the link, so we don’t need to show it in our backend.

You can replace hyperlink in our initial code with the following:

<a className="ctt-btn">
{ props.attributes.button }
</a>

As mentioned before, we are removing hyperlink from our code because we don’t need to show it in the backend. This will make our block look like so:

Block Inspector can be a potent tool for your block. If your plugin has advanced options that are too complicated for editor area, then you can put them in the Inspector area.

We will add one last option to our block to finish the JavaScript part in the next section.

Block Toolbar

Block Toolbar is another pre-built UI component that we can use to add more options to our block. It will appear above your block when you select it. Example:

Ideally, Block Toolbar should contain the primary controls of your block, with Inspector hosting the secondary controls. However, that is debatable and depends on your block.

We will be using the Block Toolbar area to host our alternative style control.

Similar to Block Inspector, we need to add the following code to our return statement to add Block Toolbar to our block:

We use BlockControls and Toolbar components to add a toolbar to our block. Similar to Block Inspector, props.isSelected makes sure our toolbar only appears when we put focus on our block.

We also use Tooltip and Button components for our control. Tooltip component is wrapped around Button component to make sure there’s a tooltip when you hover over the control to give you more context.

Button component is using classnames module that we imported earlier in the article. We used classnames function to give three classes to our control. The third class, is-active, only appears when our theme attribute value is true.

Its onChange function toggles the theme attribute to true/false. In the end, Dashicon components is used to display an icon for our control.

We will also have to change our block code for it to work with the changes. We need to replace the following line:

About The Author

Hardeep Asrani is a developer and Star Wars fan from Kanpur. He loves contributing to WordPress community in many ways, including support, themes, plugins and more. You can find him on Slack pretty much all the time exploring different parts of WordPress community.Hardeep works for ThemeIsle.com as a support ninja and developer. Hardeep is also one of the organisers of WordCamp Kanpur.

Featured on

CodeinWP stands for all-things-WordPress.
From web design to freelancing and from development to business, your questions are covered.