Skip to content

Improve WordPress UX With Custom Gutenberg Blocks

custom-gutenberg

Last year, on December 6th, WordPress 5.0 released a huge upgrade to the content editor UI, the Gutenberg Block Editor came to enhance the WordPress experience with an extensible drag & drop content designer interface based on React.

However this kind of editors are not new to WordPress, popular plugins like the Page Builder by Site Origin, Elementor or Beaver Builder have been around for many years. And It’s understandable why they became so popular, you can create beautiful pages quick and easy without knowing anything about programming. But of course, if you do know how to code, you can customize the interface to align even better to your project-specific needs.

Gutenberg comes with lots of different content types or Blocks, like headings, sliders, columns and many more. But also, the Block API allows us to insert new blocks, so, let’s see how to do it.

Register the block

In most builders, to register a Block you only need PHP, for instance, read here how to insert new blocks in the Beaver Builder. However in Gutenberg, it’s a different story, besides the PHP setup, a Javascript setup has to be done as well. Remember, Blocks are React components.

The fastest way I have found to register new Blocks is by using the toolkit create-guten-block. Please note that Node >= 8 and npm >= 5.3 are required on your local development machine. So, the script works like this:

In wp-content/plugins folder run:

$ npx create-guten-block my-block   

This will generate the codebase for the plugin that contains the new block, It also configures React, Webpack, ES6/7/8/Next, ESLint, Babel and other features. Now, navigate to the new plugin folder “my-block” and compile/watch the source with npm start:

$ cd my-block
$ npm start

At this point a new plugin called “my-block — CGB Gutenberg Block Plugin” should be visible in the WordPress Plugins, go ahead and activate it.

Now, go to the editor and If you see the new block in the editor, congratulations, you have created your first block!

It looks like this on the Editor:

And like this in front-end:

Customizing the Block

Now, this is where the fun begins, the files that you need to modify are:

  • src/block/block.js – Block configuration.
  • src/block/style.scss – Block style.
  • src/block/editor.scss – Editor-only styles.

The file block.js contains a React component that defines the methods edit() and save(). These are required.

Edit(): This method defines what is shown in the editor.
Save(): This method defines what is shown at the front-end.

Let’s say we want our block to have the option to add text, for this purpose we can use the RichText component, which is a minimal text editor similar to the old Classic Editor. In block.js make these 4 changes:

  1. Import RichText component in our Block by adding
    const { RichText } = wp.editor;
  2. Define the attribute where RichText data will be stored, I named it “content”.
  3. Inside edit() define the constant “updateContent” to handle user input, It invokes the Block API method setAttributes() to set the value for the attribute “content” on save.
  4. And finally, use the RickText component in both returns in edit() and save().

All comments were removed for better readability. The block.js should look like this now:

 
import "./editor.scss";
import "./style.scss";
 
const { __ } = wp.i18n;
const { registerBlockType } = wp.blocks;
const { RichText } = wp.editor;
 
registerBlockType("cgb/block-my-block", {
 title: __("my-block - CGB Block"),
 icon: "shield",
 category: "common",
 keywords: [
   __("my-block — CGB Block"),
   __("CGB Example"),
   __("create-guten-block")
 ],
 attributes: {
   content: {
     type: "array",
     source: "children",
     selector: ".block-content"
   }
 },
 edit: props => {
   const updateContent = value => {
     props.setAttributes({ content: value });
   };
   return (
     <div className={props.className}>
       <p>— Hello from the backend.</p>
       <RichText
         tagName="div"
         className={"block-content"}
         onChange={updateContent}
         value={props.content}
       />
     </div>
   );
 },
 save: props => {
   return (
     <div className={props.className}>
       <p>— Hello from the frontend.</p>
       <RichText.Content
         tagName="div"
         value={ props.attributes.content }
         className="block-content"
       />
     </div>
   );
 }
});

If all went well you should see this Block in the Editor (Notice the format options above):

And in the front:

Publish compiled Block

When you’re finished testing deploy your production code with the cmd:

$ npm run build 

It runs once and produces 3 files inside dist/:

  • blocks.build.js
  • blocks.editor.build.css
  • blocks.style.build.css

Conclusion

Understanding how to extend the Gutenberg Blocks API was a bit hard for me at the beginning because I wasn’t familiar with React and its JSX syntax. I’ve noticed other developers are having the same struggle, so, besides Javascript / PHP / WordPress API that WordPress developers are used to, it’s also critical to have a good React expertise if you want to do more complex customization to the Block Editor.

Happy coding!