WordPress 5.0 was released at last year’s WordCamp US and introduces the new block-based “Gutenberg” editor. We’ve been super-excited about Gutenberg since then.
— Caldera WP 🌋 (@CalderaWP) December 10, 2017
Now that WordPress 5.0 is out, everyone is excited about blocks, but one question I keep hearing is “what about my shortcodes?” That’s a good question. We wrote an article last year about how shortcodes work with Gutenberg.
We’ve been excited about Gutenberg for a long time. We were the first major plugin to add a block. One cool thing about our shortcode was it loaded a preview of our form in the post editor. I wanted to make sure our block did the same. Because we were so early, I had to write my own solution. For Caldera Forms 1.8, we’re using WordPress’ built-in solution for previewing blocks that are server-side rendered — blocks like our Caldera Forms block.
When I went to do this conversion for Caldera Forms, I could not find a great example outside of the official documentation. So, I decided to write a quick post about how to convert a WordPress shortcode to a Gutenberg block. It’s something I enjoy doing, and I hope it helps you. If you want to look at the pull request I wrote for Caldera Forms to implement the server-side rendering component for our block preview, you can see it here.
At last year’s php[world] Zac Gordon and I gave an all-day workshop on Gutenberg block development and the example code is on Github. To get started, I added a shortcode to that plugin, so I’d have something to improve.
My shortcode takes a post id and a heading level — h2, h3, h4 — and outputs the post’s title wrapped in the HTML for the heading. Very simple example, I wanted to keep this simple so it works for everyone. Here are the functions for the shortcode:
You can learn more about creating shortcodes in this post from Torque, but the important thing to see is that shortcodes are a way to send attributes to the shortcode handler function. This is what the post editor looks like when I use the classic editor block to insert my new shortcode:
Then in the front-end, when I view the post, I see the post title for post id 1, in the middle of this post, I see the post title:
Registering Your Block
Now we have enough to get started converting this shortcode to a block. You can download our example code at this point if you want to follow along, or you can use your own plugin that needs blockified.
Creating and registering a block is something that has been covered very well elsewhere. My slides from my WordCamp Pittsburgh 2018 talk include examples and links. You can also take a look at the official documentation on creating WordPress blocks. Igor Benic has a great post that shows how to create a Gutenberg block for displaying a post that I would recommend, strongly.
Here is how I registered the block. We’ll zoom into a few parts below:
When I used register_block_type() to register the block, I told it about two attributes. They have the same names as the attributes my shortcode expects. Not deviating from what already exists makes this easier. But, there is an opportunity to map block attributes to legacy shortcode attributes if needed.
Here is where I define my attributes:
Creating The Block
Now that we have the attributes planned out, let’s start setting up the new block. All WordPress blocks start with the function registerBlockType(), we give it a name, an edit callback — to create the UI for the block — and a save callback to change what gets saved from the default — and attributes.
Let’s start with the basic outline of a block that just shows some words in the block, where the preview should go.
This is a start point, but this block should show up in the editor and display the static text from the edit() callback function.
Now, let’s make the block editable. The example code plugin has two complete examples of blocks with editable attributes that you can see.
Let’s start making our edit callback do what we want, in small steps. First, let’s add InspectorControls to scope –
Now in our edit callback, let’s use createElement — WordPress’ function to create HTML elements inside of blocks using all of the React magic that powers Gutenberg makes things faster and cross-browser safe. In this case, we have one “div” element with two children, another “div” and the inspector controls:
Because I want the block to look identical in the editor to the front-end, I will put my controls on the right hand “Block Inspector” area. Before we can add form controls to update the values of the attributes, we need to know how to access the attribute values and how to update them.
The edit callback is passed an object “props” which contains the current values of our attributes and a function setAttributes() that we can use to update an attribute. I can use this to create two “change handler functions” — functions called when the value need to change. These will communicate to WordPress that the value has changed for these attributes:
Now I can use the WordPress component library to add a text control and select controls for the post ID and the heading level. I find that the wp-storify Storybook site is the best way to find the right WordPress UI components and see the README on how to use them.
With this, I can add my block and see this in the post editor when it is added:
Render Callback For PHP Blocks
Now that the UI for the attributes is done, we still need to be able to preview the block. What’s cool is it will update in real time. Because we already have a function — from the shortcode — to display this block, the PHP render callback argument was used with register_block_type() to call a PHP function to display the block in the front-end.
Here is a reminder of how that is wired up right now:
The render function just says hi from the server. I wanted to start as basic as possible. If you’re copying this code into your own plugin, you could put anything there. We’re going to use the same function the shortcode handler does. First, let’s get it working in the preview.
Creating this live updating preview is one of the simplest parts of this tutorial thanks to the ServerSideRender component. We can bring it into scope:
This component needs to know which block to use and the current attributes to render with, so we will replace the div with the text “Put preview here” with the ServerSideRender component:
Now in the post editor, my block shows “Hello From The Server” and it also shows that in the front-end when the post is displayed. That’s not what we want.
In the PHP render callback function, let’s call the same function the shortcode called:
As you can see, this is just passing the attributes to the function that creates the HTML. WordPress is taking care of the rest. It’s actually simpler than the shortcode function, which you can see here, which is the final PHP code:
With this in place, you should be able to skip through post/page IDs and see the titles load. And if you change the heading, it should update live in the browser right away.
You Can Go Further
That’s the basics of converting a WordPress shortcode plugin to a Gutenberg block for WordPress 5.0. In this post, you got a walkthrough of the process of creating a block, making it editable and adding a live preview that’s identical to the front-end view of the block and created with a PHP function shared with the legacy shortcode. You can see the completed example on Github. This is open-source, copy what you need, please.
If you wanted to take this further, and want a good challenge, I’d convert the simple text control for post ID to an autocomplete that searched for WordPress posts by post type. If this all sounds like fun, but you need an in-depth course before starting out with Gutenberg, Zac Gordon’s course is perfect for you. Zac starts at the basics and then walks through all of the new tools that are available to us to create really cool blocks. His course has a ton of great example code, which I reference all the time.