• Skip to primary navigation
  • Skip to main content
Sal Ferrarello
  • About Sal Ferrarello
  • Speaking
  • Connect
    Mastodon GitHub Twitter (inactive)
You are here: Home / Programming / WordPress Custom Editor Block
Assortment of letters from a printing press.

WordPress Custom Editor Block

Last updated on May 29, 2018 by Sal Ferrarello

With WordPress 5.0 a new block-based editing experience will be introduced (a.k.a. Gutenberg). This new editing experience is available via the Gutenberg plugin. By adding this plugin to your (development) WordPress website, you can preview the new editing experience.

At the time of this writing, Gutenberg is still under-development so I recommend only installing it on development websites (not a live site).

Building Your Own Blocks

The new block-based editor (Gutenberg) is built to be extensible, allowing developers to create their own custom blocks.

Do You Need a Custom Block?

Before building your own block, I suggest exploring what you can do with the built-in features of the new block-based editor. Mika Epstein has a great post, You Don’t Need a Block, where she looks at the Shared Block functionality and how it can be used to create your own custom block without any coding.

Clearly, shared blocks won’t be a solution for every need but it is one more tool in your arsenal when bending WordPress to your will.

Custom Block Requirements

In learning about creating WordPress custom Gutenberg blocks, I’ve found most instructions and examples take advantage of features in the newer versions of JavaScript. To support older browsers, a build process is used to to convert this new JavaScript code to the equivalent older, more universal JavaScript (this process is called transpiling and uses a tool like Babel).

While I can see this is a great way to build WordPress custom Gutenberg blocks, I found it wasn’t a great way for me to learn to build custom blocks. There are two factors I don’t like in this setup:

  1. It requires I learn newer JavaScript syntax and how to build custom blocks at the same time. I prefer to learn one thing at a time.
  2. It requires a build process using something like npm. I think build processes can be great but I prefer to eliminate them when I’m learning and iterating quickly.

I fully expect I will reach a point where I say, “Wow, I really need to use these newer features of JavaScript. I guess it is time to start using a build process for creating my blocks,” however until that time, I’ll continue working without one.

Example Blocks

The following are blocks I’ve built specifically for learning. In addition to the final product, I’ve done my best to arrange the history so that each commit is informative.

I start each block using the WP CLI scaffold command. e.g. I run something like the following on the command line.

Create the Plugin

$ wp scaffold plugin my-plugin 

Create the Block within the Plugin

$ wp scaffold block my-block --plugin=my-plugin

Add code to the plugin file to load the block code

In the root plugin file (e.g. my-plugin.php), I add

include( plugin_dir_path( __FILE__ ) . 'blocks/my-block.php' );

Resulting Plugin

This results in a plugin like my My Plugin Starter Block. This creates a custom block you can add and remove, however the content in this block can not be modified – it is hardcoded. The following blocks are all built starting from a base like this one.

Blocks I’ve Built

You’ll notice I prefix all of my blocks with “Iron Code” in order to differentiate them from other blocks (and as part of my own branding).

Update: I’m now defining my WordPress block attributes in PHP rather than JavaScript for the reasons I outline in the linked blog post.

Iron Code Basic

Goal: to create an editable block with minimal code changes.

The block has one input field and uses this to render a single paragraph on output. If you view the commits, you can see the steps I took this make this block.

This block will be stored in the post content (along with the other blocks) as the following:

<!-- wp:learn-iron-code-block-basic/iron-code-basic -->
<p class="wp-block-learn-iron-code-block-basic-iron-code-basic">The user typed this in.</p>
<!-- /wp:learn-iron-code-block-basic/iron-code-basic -->

Note: Since this uses an input field only a single line is supported.

Iron Code Basic Block

Iron Code Two Elements

Goal: create a minimal block with two editable fields

Viewing the commits, you can see I first make it editable with one field (like the Iron Code Basic block) and then add the second field.

This block will be stored in the post content (along with the other blocks) as the following:

<!-- wp:learn-iron-code-block-two-elements/iron-code-two-elements -->
<div class="wp-block-learn-iron-code-block-two-elements-iron-code-two-elements">
    <h2 class="learn-iron-code-block-two-elements--heading">User entered heading.</h2>
    <p class="learn-iron-code-block-two-elements--content">Body content provided by the user in the Gutenberg editor.</p>
</div>
<!-- /wp:learn-iron-code-block-two-elements/iron-code-two-elements -->

Note: Since we are generating multiple elements for editing, we use nested calls to el() (i.e. wp.element.createElement()).

Iron Code Two Elements Block

Iron Code Rich Text

Goal: use the Gutenberg RichText component to create a field with a rich contenteditable input area, providing users the option to add emphasis to content or links to content – the RichText component handles multiple line of input

This block will be stored in the post content (along with the other blocks) as the following:

<!-- wp:learn-iron-code-block-rich-text/iron-code-rich-text -->
<p class="wp-block-learn-iron-code-block-rich-text-iron-code-rich-text">My first line<br/>My second line, which has a <strong>bold</strong> word.<br/>My third line</p>
<!-- /wp:learn-iron-code-block-rich-text/iron-code-rich-text -->

Note: By default, the RichText component will generate an html paragraph (<p>) with line breaks (<br>) between line.

Iron Code RichText Block

Iron Code Rich Text List

Goal: create a block using the RichText component to create a ul/li list

This block will be stored in the post content (along with the other blocks) as the following:

<!-- wp:learn-iron-code-block-rich-text-list/iron-code-rich-text-list -->
<ul multiline="li" class="wp-block-learn-iron-code-block-rich-text-list-iron-code-rich-text-list">
    <li>One</li>
    <li>two</li>
    <li>3</li>
    <li>rouf</li>
    <li>FIVE</li>
</ul>
<!-- /wp:learn-iron-code-block-rich-text-list/iron-code-rich-text-list -->

Note: By default, the RichText component will render the value as a paragraph (<p>) with line breaks (<br>). In the final commit, you can see we modify the RichText component to render the value as an unordered list (<ul>/<li>).

Iron Code RichText List Block

Iron Code Shortcode

Goal: create a block that renders front-end output on page load using PHP (similar to a shortcode)

This block will be stored as a placeholder only in the post content (along with where the other blocks are stored) as the following:

<!-- wp:learn-iron-code-block-shortcode/iron-code-shortcode /-->

Note: Even if the JavaScript for the block stores actual markup in the post content, that markup will be overridden by the PHP rendering when displayed on the front-end.

Iron Code Shortcode Block

Iron Code Basic Focus

Goal: to create an editable block that displays differently in the backend editor depending on whether or not it is in focus

This block is similar to the Iron Code Basic block (found above), in that it has a single input field that renders a paragraph on output. This block goes one step further, using props.isSelected in the edit function to display this block differently depending on whether or not the block is selected (i.e. in focus).

  • When selected, the block displays a single input field (just like the Iron Code Basic block)
  • When not selected, the block displays a paragraph (in the same way, it displays on the front-end)

Using this technique we can allow the user to complete a number of fields when the block is selected and once it is no longer selected, we can render the block the way it will appear on the front-end.

Iron Code Basic Focus Block

Other Notes and Resources

createElement

In my blocks, you’ll notice I create a variable called el and assign it the wp.element.createElement. I do this because calling el() is more tidy than calling wp.element.createElement(). This raises the question, what is this function? The new WordPress editor is built with React. Calling wp.element.createElement() (or el()) is the same as calling React.createElement().

Check out this helpful introduction to React.createElement.

Photo Credit

pxhere

Sal Ferrarello
Sal Ferrarello (@salcode)
Sal is a PHP developer with a focus on the WordPress platform. He is a conference speaker with a background including Piano Player, Radio DJ, Magician/Juggler, Beach Photographer, and High School Math Teacher. Sal can be found professionally at WebDevStudios, where he works as a senior backend engineer.

Share this post:

Share on TwitterShare on FacebookShare on LinkedInShare on EmailShare on Reddit

Filed Under: Computing, Dev Tips, Programming Tagged With: Gutenberg, WordPress

Reader Interactions

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Copyright © 2023 · Bootstrap4 Genesis on Genesis Framework · WordPress · Log in