Gutenberg is a brand-new editing interface that will change the way people use WordPress. Are you ready for that change? If you’re a plugin developer, you need to prepare your own plugins for Gutenberg.
In case you haven’t yet heard about Gutenberg, it is a new WordPress editor that will change how you write content. Under Gutenberg, set to become part of WordPress core in version 5, each element in your content will be a block (of type paragraph, image, blockquote, heading, and so on).
Even metaboxes won’t be the same.
Simple metaboxes should work with Gutenberg out of the box, although they will be displayed differently. However, if you have complex metaboxes such as the one in the Yoast SEO plugin, then you’ll have to test it against Gutenberg and maybe create a new one just for Gutenberg.
So which plugins need updating for Gutenberg? Plugins with:
- custom post types
- complex metaboxes
- shortcodes
- or editor features
There are two approaches that we can take as plugin developers: support Gutenberg or disable Gutenberg. Supporting Gutenberg would mean that we will put extra effort into refactoring our code (maybe even duplicating some) so that our plugin users won’t have any difficulty using it.
How to Disable Gutenberg
If we decide to not support Gutenberg, then we need to disable Gutenberg. We can disable Gutenberg completely or only where our plugin is being used. In this section, I will take my own plugin “Simple Giveaways” that has a custom post type and also metaboxes.
Disabling Gutenberg Completely
This is something I would not recommend doing from your plugin. Instead, you might want to inform your plugin users with an admin notice that your plugin doesn’t work with Gutenberg so that they can revert back to the Classic Editor.
Reverting can be done by installing the plugin Classic Editor. Or you may create a new setting for your plugin and do this to disable it:
This filter can be found in the function
gutenberg_can_edit_post_type
which is used to check if Gutenberg can be loaded on that particular post type. If we always returnfalse
, then it means that we won't support Gutenberg at all.Disabling Gutenberg per Post Type
If your plugin has a custom post type, then you may want to disable Gutenberg for that particular post type. To disable Gutenberg for your custom post type, you can just change your post type configuration.
Editor Support
Gutenberg won't load if your post type does not support the editor. This is appropriate if your custom post type does not need the editor.
__( 'Simple Giveaways', 'giveasap' ), 'labels' => $labels, 'supports' => array( 'title', //'editor', Disabling Gutenberg 'thumbnail', ), 'hierarchical' => false, // ... ); register_post_type( 'giveasap', $args );REST API Support
Maybe you need the editor but you don't need it in the REST API? Gutenberg won't load if you don't support the REST API. Similarly to the above example, we will do that in the post type configuration.
__( 'Simple Giveaways', 'giveasap' ), // ... 'show_in_rest' => false, // Disable Gutenberg // ... ); register_post_type( 'giveasap', $args );By setting the parameter
show_in_rest
tofalse
, we will disable Gutenberg for that post type.Post Type Support
We can use the previously mentioned filter to disable Gutenberg only for our custom post type.
With this code, we are checking if we are on our custom post type. If we are, then just return false. This won't affect any other post types.
Disabling Gutenberg With Metaboxes
If you have complex metaboxes, maybe it would take too long for you to create a version of your plugin that could support Gutenberg. If that's the case, you can disable Gutenberg until you have something that works with Gutenberg.
To disable Gutenberg with your metaboxes, you need to define them as not compatible.
false, ) );If you want to learn how to support Gutenberg with complex metaboxes, you'll need to learn how to convert them to a block and also how to save them. Be sure to check the WordPress Gutenberg handbook for that.
How to Support Gutenberg
A better option than disabling Gutenberg is to support it!
Since metaboxes will probably work out of the box, you won't have much to do here (unless they're advanced, as we learned before). When supporting Gutenberg, you will mostly work on making new blocks for your shortcodes and even widgets.
Shortcodes will also work out of the box. But to provide a better user experience, you should probably make blocks for them.
You can create static and dynamic blocks. Static blocks will be completely written in JavaScript, and the outputted HTML will be saved in the content.
Dynamic blocks are a bit different. You will also have to create the JavaScript part so it works with the Gutenberg editor. But you will also define a PHP function that will be called to render it when displaying that content on the front of your site.
To understand static and dynamic blocks, let's look at a simple example—a simple alert block—and implement it both ways.
Registering a Block
To register a block, first we need to define it in PHP and then in JavaScript.
'guten-tuts', ) ); // Our Dynamic block. register_block_type( 'guten-tuts/alertdynamic', array( 'render_callback' => 'guten_tuts_dynamic_alert' ) ); } add_action( 'init', 'guten_tuts_block' );When registering a script, we need to define the dependencies here. The
wp-block
andwp-element
dependencies are the ones we need when creating blocks.I will not go into a detailed overview of blocks or the API as a whole. To understand this more, you should read the Gutenberg Handbook.
JavaScript Block File
The beginning of our JavaScript file block.js will have this:
var el = wp.element.createElement, __ = wp.i18n.__, registerBlockType = wp.blocks.registerBlockType, RichText = wp.blocks.RichText, blockStyle = { backgroundColor: '#900', color: '#fff', padding: '20px' };Static Block
Now let's define our static block. Since our alert will be just text, we need one attribute:
text
. In ouredit
function (used in the Editor), we will have aRichText
block. This block allows us to insert the text, add styles, and so on.The definition of our attribute
text
will tell the Gutenberg to strip the text inside thediv
. We are also telling Gutenberg that this will be an array of all child elements. Just for example, thisem text other text bold textwould convert into an array of three elements: "em text", "other text", and "bold text" along with their structure such as
em
andbold
.The conversion of these attributes happens in the output of the
save
method.registerBlockType( 'guten-tuts/alert', { title: __( 'Guten Tuts - Alert' ), icon: 'megaphone', category: 'layout', attributes: { text : { type: 'array', source: 'children', selector: 'div', } }, edit: function( props ) { var content = props.attributes.text; function onChangeText( newText ) { props.setAttributes( { text: newText } ); } return el( RichText, { tagName: 'div', className: props.className, onChange: onChangeText, value: content, isSelected: props.isSelected, style: blockStyle } ); }, save: function( props ) { var text = props.attributes.text; return el( 'div', { style: blockStyle, className: props.className }, text ); }, } );Dynamic Block
The Dynamic block will have the
edit
method, but thesave
method will returnnull
. We don't need thesave
method here because we will define a PHP callback function to render the dynamic block on the front.We have registered a callback
guten_tuts_dynamic_alert
before:'guten_tuts_dynamic_alert' ) ); // ...This callback will also receive a parameter
$attributes
. This will be an array of all the registered attributes. The behavior is very similar to registering a shortcode.The function
guten_tuts_dynamic_alert
will look like this:The output is just a
div
element with some text.As far as I can tell, we can't use the RichText for dynamic blocks because the attributes don't update. If I am wrong, let me know in the comments!
We will use a regular
input
to enter the alert's text. Since we don't have asave
method here, I've defined the attributetext
as a simple string.registerBlockType( 'guten-tuts/alertdynamic', { title: __( 'Guten Tuts - Dynamic Alert' ), icon: 'megaphone', category: 'layout', attributes: { text : { type: 'string', selector: 'div', }, }, edit: function( props ) { var content = props.attributes.text; blockStyle['width'] = '100%'; function onChangeText( e ) { var newText = e.target.value; props.setAttributes( { text: newText } ); } return el( 'input', { className: props.className + ' widefat', onChange: onChangeText, value: content, isSelected: props.isSelected, style: blockStyle } ); }, save: function( props ) { return null; }, } );You will see a regular
input
that has a background color and different styling than theRichText
block. Of course, you can change that and mimic the same styles.Since our PHP rendered alert has a different background color than the one defined inside our JavaScript code, we can also see the difference on the front side.
Conclusion
Preparing your plugin for Gutenberg can be a lot of work. But since Gutenberg is as extensible as the rest of WordPress, you have a lot of flexibility to support your plugin's features in Gutenberg.
Get started today by installing Gutenberg and testing it against your plugin.
Powered by WPeMatico