Hey WordPress Plugin Developers: Are Your Plugins Really Ready for Gutenberg?

#

WordPress 5.0 is right around the corner with the flagship feature, the new Gutenberg editor, set to change the WordPress landscape dramatically. Gutenberg not only impacts how you write content in WordPress, but how developers build plugins for WordPress.

Here at Delicious Brains we are working hard on the next version of our plugins, including making sure they are Gutenberg-compatible, but after chatting about Gutenberg the other day I thought it was high time I made sure my own plugins worked with the new editor as well.

In this post I’ll walk you through the process I took for making Intagrate, my Instagram WordPress plugin, Gutenberg-compatible, which will hopefully get you started on making your own plugins Gutenberg-ready.

Things to Consider

Although there is a way to completely disable Gutenberg on sites by using the Classic Editor plugin, if your own plugin is used on sites you don’t control (very likely if the plugins are sold or available on the WordPress plugin repository) then you will need to ensure it still functions a s expected with Gutenberg. There is also no guarantee that Classic Editor will be around in the future.

Plugins can widely differ in functionality and how they integrate with WordPress, and for a large number, I would expect Gutenberg to have little to no effect.

For example, through extensive testing we found that Gutenberg has no apparent impact on how WP Offload Media works because it primarily deals with media uploads behind the scenes. (Okay, maybe just one issue with admin notices.) However, as Gutenberg stores its data in the post_content column of the posts table, we had to make sure WP Migrate DB Pro still handles the find and replace of URLs and paths within Gutenberg block data – which it does without any trouble 💪.

However, there are a number of key areas of functionality that Gutenberg does have an impact on, so if your plugin has or uses them you should definitely read on. These areas include but aren’t limited to:

  • Custom Post Types
  • Custom Meta Boxes
  • TinyMCE buttons or integration

Testing Plugins with Gutenberg

I would recommend doing any testing on a local development environment or a staging site, with a WordPress site that you don’t mind trying things out/breaking things on.

To get the site running the new Gutenberg editor you’ve got two choices:

  1. Install the standalone Gutenberg plugin on a site running WordPress 4.9.x or earlier, or
  2. Get the site running the latest release candidate of WordPress 5.0.

Although the Core development team are keeping all Gutenberg changes up-to-date across the plugin and the release branch, I’m personally using the WordPress 5.0 release candidate (RC1 at the time of writing) for my test site. It can be downloaded as a zip, or installed using the Beta Testing plugin. The ‘bleeding edge nightlies’ is the option you need:

Beta Testing plugin settings page

Once WordPress has been updated you should see the brand-new-yet-to-be-released splash page:

WordPress 5.0 upgrade page

Which means our Gutenberg test site is ready to go.

Essential Plugin Maintenance for Gutenberg Compatibility

Now that our test site is running the new Gutenberg editor it’s time to check if your plugin plays nice with it. It’s worth making it clear that the majority of this post is about making your plugin continue to work with Gutenberg as is, with the bare minimum effort. I will touch on making enhancements and deeper integrations later on in the post.

Custom Post Types

If your plugin registers custom post types then, like me, you will be pleasantly surprised to see that when you go to edit one of the posts it might still load the classic editor. This is more by luck than design.

As it stands in WordPress currently, as Gary Pendergast explains, post types will only use the Gutenberg editor if:

  • When registered (or using add_post_type_support()) declare that they support the ‘editor’ feature.
  • When registered, set their show_in_rest setting to true (the default is false).

But wait, my custom post declares support for ‘editor’ because I want users to add content with the old editor – the classic editor. But now ‘editor’ means the new block editor Gutenberg. Confused? Me too.

The only reason the post type is using the classic editor still is because it was registered without the show_in_rest argument. The code was first written before the REST API existed and it has never needed to be exposed to the API. Therefore show_in_rest will default to false and Gutenberg won’t be loaded.

However, as this trac ticket highlights, this behavior might not be the case forever so it’s worthwhile implementing a longer-term fix. To ensure the post type always uses the classic editor (while that’s still a thing), we can use a new filter:

function igp_post_type_filter( $use_block_editor, $post_type ) {
    if ( 'instagrate_pro' === $post_type ) {
        return false;
    }

    return $use_block_editor;
}
add_filter( 'use_block_editor_for_post_type', 'igp_post_type_filter', 10, 2 );

Custom Meta Boxes

The handling of custom meta boxes in the Gutenberg editor has come under some criticism due to the assumption that all meta boxes are compatible with Gutenberg unless told otherwise.

This ‘opt-out not opt-in’ approach is problematic as it means when WordPress 5.0 drops, all custom meta boxes will be loaded on the block editor, ready or not. This will be fine for simple boxes, but anything really custom could break.

The best course of action is to ensure the meta box works with Gutenberg, or better still convert it to a block (I’ll come to that), but if you can’t then you need to disable it for the block editor.

The last parameter of the add_meta_box() function called $callback_args accepts an array of data which is sent to the meta box callback, and now accepts __block_editor_compatible_meta_box. When this is set to false the meta box will be turned off for the block editor:

add_meta_box( 'igp_links', __( 'Useful Links', 'instagrate-pro' ), array( $this, 'meta_box_links' ), 'instagrate_pro', 'normal', 'low', array( '__block_editor_compatible_meta_box' => false ) );

Incompatible custom meta box display

This is far from ideal, and you are relying on either the site owner using the Classic Editor plugin or the post type not supporting the block editor in general.

TinyMCE

The classic editor relies on TinyMCE, the WYSIWYG HTML Editor. TinyMCE can be customized to add buttons, dropdowns and lots more. As the Gutenberg Migration guide states, there isn’t the same type of button in the new Gutenberg UI:

While the Gutenberg Block API provides UI for inserting block-level elements, there are no Gutenberg equivalents for customizing the block toolbar or programmatically manipulating post content.

My custom post type has quite a few buttons added to the WYSIWYG editor to make it easy for users to insert Instagram data tags, which would be lost if I couldn’t turn off Gutenberg for the post type:

TinyMCE buttons

For now, the only course of action is to keep the post type using the classic editor so the TinyMCE buttons still work. It’s clear that the mass of buttons I’ve added is a hack that is unwieldy for users. At this point in my testing, I took a step back and started thinking how Gutenberg’s new UI and block-based experience is much slicker and easier to use than the classic editor.

Possible Enhancements

While testing the code to turn off Gutenberg for my custom post type I purposely loaded Gutenberg to see what would happen, expecting everything to break. Guess what? It didn’t. My metaboxes still loaded, and only my TinyMCE buttons were missing. It didn’t look half bad and I started to think about ways I could make my plugin interface work even better with Gutenberg.

Shortcodes in Gutenberg

Intagrate allows users to craft post content from Instagram media. If you want to show a video in your post content you need to add a shortcode to the post content in the custom post type.

Shortcodes have always been a great way to control where dynamic content will be displayed on the front end. However, they have never been user-friendly (even when inserted by a TinyMCE button), and are definitely not WYSIWYG. Although shortcodes will still work in WordPress 5.0, blocks are the new way of accomplishing the same thing.

[igp-video src="%%video%%" poster="%%image%%" size="large"]

You can create dynamic blocks to replace the shortcode for the block editor, so I could replace the shortcode with a block to display the Instagram video, where users can configure video settings in the block sidebar. If I was in control of the whole site I could use Advanced Custom Fields (ACF) to register my block with PHP and define the block settings as an ACF Field Group.

A block is so much more usable than a shortcode. Food for thought!

Converting Custom Meta Boxes

We already discussed dealing with custom meta boxes that aren’t compatible with the block editor, but there are many custom meta boxes that could be replaced by Gutenberg. For example, some meta boxes have been created to store data that will be rendered in some shape or form on the front end, where shortcodes wouldn’t have cut it for users to add the data. In these cases creating a custom block instead of a custom meta box makes much more sense.

If you do upgrade your meta box to a block, you would need to leave your legacy meta box code for sites that are using the Classic Editor plugin. In that case, you can use another $callback_arg when adding the meta box to tell WordPress to only load the meta box if the post type is using the classic editor:

add_meta_box( 'igp_links', __( 'Useful Links', 'instagrate-pro' ), array( $this, 'meta_box_links' ), 'instagrate_pro', 'normal', 'low', array( '__block_editor_compatible_meta_box' => false, '__back_compat_meta_box' => true ) );

Both the callback arguments for meta boxes are documented here, along with a note about extra notices being added for incompatible meta boxes when the WP_DEBUG constant is turned on.

Final Thoughts

Through the process of making my plugins compatible with Gutenberg, I’ve seen just what an improvement Gutenberg is over the existing editor.

Gutenberg is a powerful enhancement to the WordPress editing experience that plugin developers can leverage to make their plugins’ experience even better. If you develop a plugin that is used by others I recommend you take a look at not just making it continue to work with Gutenberg, but to start thinking about how you can improve it where possible by taking advantage of the new block-based editor.

Have you already made your plugins compatible? Have I missed any tips for a successful conversion? Are you making your plugin’s user experience even better because of Gutenberg? Let us know in the comments below.

About the Author

Iain Poulson

Iain is a WordPress and PHP developer from England. He builds free and premium plugins, as well as occasionally blogging about WordPress. Moonlights as a PhpStorm evangelist.