How to Build Custom Gutenberg Blocks

Congratulations, you’ve fully mastered using the Gutenberg editor and now are ready to create your own custom Gutenberg blocks!

In the following tutorial, we’ll show you how to create your first custom Gutenberg blocks that can be added to the standard suite of blocks that come pre-installed with the editor.

The three primary tools that you will need to create custom Gutenberg blocks are: PHP, CSS, and JavaScript.

We’ll start this whole process by registering scripts, styles, and block types in PHP, which provides WordPress with the bare minimum it needs to create the block in the editor. 

The actual block itself will be mostly written in JavaScript, but we have to first define it in PHP before we can proceed. 

PHP

Let’s start with the following lines to set up our PHP file:

<?php
/*
Plugin Name: Your Gutenberg Block
Plugin URI: http://ultrablocks.festplugins.com
Description: An example of a custom block. 
Author: UltraBlocks - FestPlugins
Author URI: http://ultrablocks.festplugins.com
Version: 1.0.0
License: GPL2
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: yourgutenberg 
Domain Path: /blocks
 */

In the area above, we’re just giving Gutenberg some context about our block so that it can generate the plugin name, author name, description, and other information. This is just a typical plugin declaration. 

We should also include this next line to prevent others from directly accessing our source code and stealing our work in the future. When someone tries to access this code directly, the file will be exited automatically.

defined('ABSPATH') || exit;

Now, we can start with the code that pertains to running Gutenberg Editor and our new, custom Gutenberg block:

If ( function_exists( ‘the_gutenberg_project’ ) ) { 
  If ( ! function_exists( ‘yourgutenberg_block’ ) ) { 
    function yourgutenberg_block() {

What does the code do? It tells WordPress to check to see if Gutenberg is installed and active. When it finds this, it asks if our custom block under a given name exists. Then, if our custom block exists, it will be run.

After we’ve done this, we’ll need to start defining the block, beginning with registering the script.

Registering Script

This line of PHP links our custom Gutenberg block to a script we wrote in JavaScript–the part that actually tells the block what to do.

wp_register_script(
  'name-ofyour-script',
  plugins_url( '/URL/of/your-script.js', _FILE_ ),
  array( 'wp-blocks', 'wp-element' )
);

As you can see, we’ll register the name of our script, write the URL of the JavaScript file, and include the dependencies needed for Gutenberg. The array section is absolutely necessary and must include ‘wp-blocks’ and ‘wp-element’. 

Register Global Block Style

Gutenberg allows us to change both the style of the block as it appears on a website and how it seen by users in the editor. For example, we might want our block to use a more stylized, artistic font on our website, but we want a simple, easy-to-read font for our users in the editor. 

If we decide that we want the style of the website and the editor to be exactly the same, we’ll just register the global block style and leave the editor style out of our code. 

First, we’ll need to register the global block style that is found in your CSS file.

wp_register_style(
  'nameof-mystyle',
  plugins_url( '/url/of/mystyle/style.css', _FILE_ ), 
  array( 'wp-edit-blocks' ),
  filemtime( plugin_dir_path( _FILE_ ) , '/url/of/mystyle/style.css' )
);

Here, we register the name of the style, add the plugin URL for the .css stylesheet and add ‘wp-edit-blocks’ to the array, which is a required dependency. The filemtime function lets you know when your custom Gutenberg block was last changed.

Register Editor Style (optional)

Second, you’ll need to register the editor-specific style in another, separate CSS file. 

wp_register_style(
  'nameof-mystyle-editor',
  plugins_url( '/url/of/mystyle/editor-style.css', _FILE_ ), 
  array( 'wp-edit-blocks' ),
  filemtime( plugin_dir_path( _FILE_ ) , '/url/of/mystyle/editor-style.css' )
);

You may have noticed that hardly anything changed between the two. The only difference is that the plugins_url will need to be different and the name of your file should probably include the word ‘editor’ to distinguish the two. You also want to register the name using the word ‘editor’ as well.  

Register Block Type

Finally, we’ll bring the two styles and our script together and define them as a block type.

register_block_type( 'pluginname/blockname', array(
  'editor_script' => 'name-ofyour-script', 
  'editor_style' => 'nameof-mystyle-editor', 
  'style' => 'nameof-mystyle',
) ); 

We simply plugged in the names that we defined earlier for the script, the global block style, and the editor style. This will then bring all three elements together into a “block type” that you will give a name as well.  However, you don’t have as much freedom when it comes to naming the block type.

You’ll have to use the format of  ‘pluginname/blockname’. Combining the name of the plugin and the block helps Gutenberg stay organized and not get mixed up. If you only used the block name, it could possibly grab a block from the wrong plugin, and vice versa. For example, our code might look like: ‘ultrablocksplugin/flipbox’. 

Finally, to finish everything up, we’ll add a hook into WordPress using the following line:

add_action( 'init', 'yourgutenberg_block' );

So, what does all of this code look like when put together?

<?php
/*
Plugin Name: Your Gutenberg Block
Plugin URI: http://ultrablocks.festplugins.com
Description: An example of a custom block. 
Author: UltraBlocks - FestPlugins
Author URI: http://ultrablocks.festplugins.com
Version: 1.0.0
License: GPL2
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: yourgutenberg 
Domain Path: /blocks
 */

defined('ABSPATH') || exit;

If ( function_exists( ‘the_gutenberg_project’ ) ) { 
  If ( ! function_exists( ‘yourgutenberg_block’ ) ) { 
    function yourgutenberg_block() {
  wp_register_script(
  'name-ofyour-script',
  plugins_url( '/URL/of/your-script.js', _FILE_ ),
  array( 'wp-blocks', 'wp-element' )
   );
   wp_register_style(
   'nameof-mystyle',
   plugins_url( '/url/of/mystyle/style.css', _FILE_ ), 
   array( 'wp-edit-blocks' ),
   filemtime( plugin_dir_path( _FILE_ ) , '/url/of/mystyle/style.css' )
    );
     wp_register_style(
     'nameof-mystyle-editor',
     plugins_url( '/url/of/mystyle/editor-style.css',                      _FILE_ ), 
     array( 'wp-edit-blocks' ),
     filemtime( plugin_dir_path( _FILE_ ) , '/url/of/mystyle/editor-style.css' )
     );
     register_block_type( 'pluginname/blockname', array(
      'editor_script' => 'name-ofyour-script', 
      'editor_style' => 'nameof-mystyle-editor', 
      'style' => 'nameof-mystyle',
     ) );
    }
    add_action( 'init', 'your_gutenberg_block' );
  }
}

There we have it, folks. That’s the basis of your custom Gutenberg block in PHP. Now, we’ll need to move on to JavaScript and CSS to actually create the script and the stylesheets that we defined in the PHP file.

JavaScript

The Gutenberg editor uses the React.js library and will require you to know a little bit about it. While React is designed to speed things up and save you time, it can do the opposite if you’ve never used it before. We encourage you to read some tutorials on React.js before you move on. 

To begin with our JavaScript file, we’ll have to define a few things and make sure that the file name matches up exactly with the name we used in the PHP file. 

Register Block Type

When we register the block type, we also give the block a name to display when it shows up in the editor. This is part of the title section.

In the icon section, we can either choose our own files to use or use the built-in icons that come with Gutenberg. Currently, Gutenberg allows us to simply add the name of the dash icon to make it appear. 

If we go onto WordPress.org we’ll be able to find the list of pre-installed icons. Just type the name of the file in the “icon:” section and it will show up in Gutenberg editor.

wp.blocks.registerBlockType( 'pluginname/blockname', {
  title: 'Block Name',
  icon: 'dash-icon',
  category: 'common',
  attributes: {
    content: {
      type: 'array',
      source: 'children',
      selector: 'p',
  },
}, 

You may have noticed that we have placed the block into the common blocks category. This helps us organize our blocks better and puts them in various sections of the editor, such as common, embeds, formatting, etc. 

The attributes section is one of the most interesting parts of Gutenberg blocks, as it helps convert all of your JavaScript information into HTML. As we learned in our previous tutorial, all of the additional code is stored in HTML comments. This allows Gutenberg to store JavaScript within the HTML, preserving the block’s editor style and script. 

This is a rather ingenious solution that allows Gutenberg posts to seamlessly transition back and forth between the editor and HTML.

The selector section tells Gutenberg where in the HTML to look for the “invisible” JavaScript code and defines the tag. In our code, we have ‘p’, meaning that Gutenberg will look for the attributes of our block in the <p> tags of the HTML.

Then, the source section lets Gutenberg know that the content information will be found in the children of the paragraph tag. The information type is also defined as an ‘array’, like it is defined in the PHP file. 

Edit Function

As we mentioned above, a post created in Gutenberg has the ability to go back and forth between the editor and HTML without losing any information. We’ll have to tell Gutenberg what to do when we edit a post and what to do when we save a post in the editor. 

In the area below, we can see that we have a tagName specified as ‘p’. This means that whenever we edit a post, Gutenberg will search the paragraph section of the HTML for information that pertains to the editor. 

The onChange function tells Gutenberg to update our block whenever we change it in the editor. The new content that we add in the editor will then change the information in that section and the corresponding attributes of the block.

edit: function( props ) {
  return wp.element.createElement( wp.blocks.RichText, {
    tagName: 'p',
    className: props.className,
    value: props.attributes.content,
    onChange: function( newContent ) {
      props.setAttributes( { content: newContent } );
    }
  } );
},

In addition, the RichText section allows our blocks to have the Bold, Italic, Strikethrough, and Hyperlink options that are baked into Gutenberg.

Save Function

Since we told Gutenberg what to do when we edit a document, we’ll need to tell it what to do when we save it. Remember that we told Gutenberg to look for information in the paragraph section, so we’ll have to make sure everything is saved in the same place. 

save: function( props ) {
  return wp.element.createElement( 'p', { 
    className: props.className,
  }, props.attributes.content );
}

In the lines above, we told Gutenberg to run the properties function when we save our work and to create a new element in the paragraph section of the HTML file. 

We also told it to save that element as props.attributes.content, which we referred to in the edit function above. 

This is an overly complex way of saying that your old information is replaced with new information. In simpler terms, the block is updated. 

Ok, let’s put everything together and see what our JavaScript file should look like:

wp.blocks.registerBlockType( 'pluginname/blockname', {
    title: 'Block Name',
    icon: 'dash-icon',
    category: 'common',
    attributes: {
      content: {
        type: 'array',
        source: 'children',
        selector: 'p',
       },
     }, 
  edit: function( props ) {
    return wp.element.createElement( wp.blocks.RichText, {
      tagName: 'p',
      className: props.className,
      value: props.attributes.content,
      onChange: function( newContent ) {
        props.setAttributes( { content: newContent }   );
      }
    } );
  },
  save: function( props ) {
    return wp.element.createElement( 'p', { 
      className: props.className,
  }, props.attributes.content );
  }
});

One of the most important things about your code is ensuring that it is consistent. Because we defined our attributes as content, we have to make sure that we continue to use the term ‘content’ in the rest of the code. 

Now, our final step will be creating our stylesheets in CSS.

CSS

After we have our scripts set up and we have everything compiled in PHP, we can move on to the fun part: adding styles. This is where things are a lot less strict and provide you with an opportunity to express yourself and be creative with the design–a refreshing departure from all that coding we did earlier. 

Define Global Block Style

Here we will be editing the global block style file that we defined earlier. We defined the file as .wp-block-nameof-mystyle in PHP, so we’ll have to use the exact same format here in CSS. 

.wp-block-nameof-mystyle {
  color: orange;
  font-family: Arial;
  border-width: 10px;
  border-style: solid;
  border-color: red;
  padding: 50px;
}

Now that we have .wp-block-nameof-mystyle set as our selector, we are able to adjust the color, border, and padding settings of every block. When we publish or preview our post, we should see these properties show up on the front-end as well as the back-end. 

Define Editor Style

Remember that we had two style sheets in our PHP file? While we defined both the front-end and back-end styles with the document above, .wp-block-nameof-mystyle-editor allows us to override the global block style document in the back-end and change the editor style separately. 

.wp-block-nameof-mystyle-editor {
  color: yellow;
  font-family: Helvetica; 
  border-color: green;
  padding: 10px;

Although the blocks will appear very differently on the website, you’ll see them in the editor with a yellow background, a 10-pixel wide green border, and Helvetica font.  

Summary

There are many more options for custom Gutenberg blocks. Today, we simply showed you the bare minimum requirements to create a block.

With this document, you’ll be able to create your very first custom Gutenberg block and start on your next project. If you don’t get it at first, go through the guide again and you’ll be sure to pick it up.

If you liked this guide and thought it was helpful, send it to a friend and let us know. We always love to hear from our readers!

Join us in our next article as we teach you how to create custom block controls, toolbars, and inspector sidebars.

https://ultrablocks.festplugins.com/wp-content/themes/fest_gutenbergtheme/assets/img/bg/bg1.png