This is the second part of an article in a series on creating WordPress Gutenberg blocks. Here is part 1.  If you want to pick up where we are, here is the repository.

We left off last time with a Gutenberg hero image block that had centered text over an image.  We added the ability to edit that text and change the text color.  It started to get a little long, so the homework I left off with was to set up the overlay so that it would also be able to be changed with a color palette option in InspectorControls.  We still have yet to use the wonderful MediaUpload component.

The repo for this in all its finished glory is here if you would desire it.

Let’s do this.

How I hooked up the ColorPalette to our transparent overlay

There are many ways to skin a cat. Here is the route I chose: I will apply an opacity to our to our overlay through the css, but since the color of the background will be determined by the content editor I’ll apply that color inline.

.wp-block-firstgutyblocks-hero-image .overlay {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    /* background: rgba(150,0,0,.3); <- old*/
    opacity: .3;
}

In our index.js, I will be adding an overlayColor attribute and add that as an inline style on my overlay div:

...
attributes: {
    textString: {
        type: 'array',
        source: 'children',
        selector: 'h2',
    },
    fontColor: {
        type: 'string',
        default: 'black'
    },
    overlayColor: { // new!
        type: 'string',
        default: 'orange'
    }
},

...

edit(props) {

    const { 
        setAttributes, 
        attributes,
        className,
        focus
    } = props;
    const { fontColor, overlayColor } = props.attributes;

...
<div 
    className={className}
    style={{
        backgroundImage: `url('http://placehold.it/1440x700')`,
        backgroundSize: 'cover',
        backgroundPosition: 'center'
    }}>
    <div 
        className="overlay"
        style={{ background: overlayColor }} {/*NEW!*/}
        ></div>
    <RichText
        tagName="h2"
        className="content"
        value={attributes.textString}
        onChange={onTextChange}
        placeholder="Enter your text here!"
        style={{color: fontColor}}
        />
</div>

Orange is a temporary choice just to make sure it’s working.  And tada!  Here we have it if we reload the editor!

Hero image block now displaying a semi-transparent orange overlay.

Okay, so now let’s add another ColorPalette component in the InspectorControls and hook it up so the user could change the color:

...
// Adding an attribute handler
function onOverlayColorChange(changes) {
    setAttributes({
        overlayColor: changes
    })
}

...

//Adding another control to the InspectorControls
<InspectorControls>
    <div>
        <strong>Select a font color:</strong>
        <ColorPalette
            value={fontColor}
            onChange={onTextColorChange}
            />
    </div>
    <div>
        <strong>Select an overlay color:</strong>
        <ColorPalette
            value={overlayColor}
            onChange={onOverlayColorChange}
            />
    </div>
</InspectorControls>,

An we now can edit text, edit the text color, AND change the overlay color.

Spiffy

Uploading a background image using MediaUpload

It’s super nice that the gutenberg editor gives us a bunch of components through wp.block that we can use.  Another component that is super nice is MediaUpload that does a lot of work for us.

MediaUpload is a component that uses what’s called render props.  You don’t have to go into detail about what those are, just realize they’re a thing and they’re very similar to Higher Order Components.  (And If you want to see a really great talk about why these things exist and how React has evolved with these sorts of things, here’s a really great talk on it.)

ANYWAY!  Let’s pull in the Media Upload, and create a new attribute that will hold our picture’s url.

const { 
    registerBlockType,
} = wp.blocks;

{
    RichText,
    InspectorControls,
    ColorPalette,
    MediaUpload  // Thanks wp.editor!
} = wp.editor;

...

attributes: {
    textString: {
        type: 'array',
        source: 'children',
        selector: 'h2',
    },
    fontColor: {
        type: 'string',
        default: 'black'
    },
    overlayColor: {
        type: 'string',
        default: null // let's get rid of the annoying orange
    },
    backgroundImage: {
        type: 'string',
        default: null, // no image by default!
    }
},

Now, let’s place our MediaUpload component:

<InspectorControls>
    <div>
        <strong>Select a font color:</strong>
        <ColorPalette
            value={fontColor}
            onChange={onTextColorChange}
        />
    </div>
    <div>
        <strong>Select an overlay color:</strong>
        <ColorPalette
            value={overlayColor}
            onChange={onOverlayColorChange}
        />
    </div>
    <div>
        <strong>Select a background image:</strong>
        <MediaUpload
            onSelect={(imageObject) => console.log(imageObject)}
            type="image"
            value={backgroundImage} // make sure you destructured backgroundImage from props.attributes!
            render={({ open }) => (
                <button onClick={open}>
                    Upload Image!
                </button>
            )}
        />
    </div>
</InspectorControls>,

A few things to note here:

  • The “onSelect” attribute is where we will eventually handle the new picture and save it’s url to “backgroundImage”.  For now, we will console.log this thing to see what MediaUpload gives us after we select an image
  • The most confusing part is the render attribute.  Basically whatever is returned inside the parentheses (in this case the <button> markup) will be shown in the editor.  MediaUpload doesn’t add anything more, but it does let you have that “open” function.  Whatever element is bound to that with onClick will be hooked up to open the MediaUpload library.

So if all goes well you can load the block, click the button, upload and select and image, and then check the console…

Editor showing our gutenberg block and a console showing the image object we console logged

MediaUpload wraps our button and allows us to make a button that opens up our media library.  Once we select an image, MediaUpload returns that image object.  For now, we set that to simply console.log the object.

MediaUpload and the object it returns

If you look closely, you notice that there’s a “sizes” property on this object?  inside of that we have lots of things that are served up by WordPress…

WordPress does it’s thing and resizes your image with different dimensions it would ordinarily use with srcset.  In this case, my picture was very large so I get a full, large, medium, and thumbnail.  In our case, I’m going to use “full” since these images are supposed to be large, detailed, full resolution things.  There’s room for optimizing and file size later!

So here’s the point, we need to create a function that will handle this object and setAttributes:

function onImageSelect(imageObject) {
    setAttributes({
        backgroundImage: imageObject.sizes.full.url
    })
}

...

<div>
    <strong>Select a background image:</strong>
    <MediaUpload
        onSelect={onImageSelect}
        type="image"
        value={backgroundImage}
        render={({ open }) => (
            <button onClick={open}>
                Upload Image!
            </button>
        )}
    />
</div>

...
//We need to make sure our div styles use this image!
<div
    className={className}
    style={{
        backgroundImage: `url(${backgroundImage})`,
        backgroundSize: 'cover',
        backgroundPosition: 'center'
    }}
>

Now, instead of logging the image when you select it, onImageSelect will set the attribute with the url of our image.  You should see the image automatically change when you select it.

Editor showing a hero image block with image showing in background of the block.

Edit: One thing I forgot to mention

I forgot to make this explicit when I first posted this.  We need to make sure that this background image shows up when we hit update! Here is what my save() method looks like now.

save(props) {

    const { attributes, className } = props;
    const { fontColor, backgroundImage } = props.attributes;

    return (
        <div
            className={className}
            style={{
                backgroundImage: `url(${backgroundImage})`,
                backgroundSize: 'cover',
                backgroundPosition: 'center'
            }}>
            <div className="overlay"></div>
            <h2 class="content" style={{ color: fontColor }}>{attributes.textString}</h2>
        </div>
    );
}

Summary

That was a a lot, but I hope that through this process this gives you ideas how to wire up your own custom block.  In these past two posts we

  • Structured the markup of a block to create an image hero
  • Learned how to use InspectorControl, ColorPalette, and MediaUpload
  • Used both css and inline styles

Thoughts? Comments?  Please post below or hit me up on twitter: @jschof

This is the 4th article in a series on creating WordPress Gutenberg blocks.  You may want to check out there other articles here, here, and here.  

Our goal here is to create a full width, customizable hero image Gutenberg block.  We aim to learn how to use the InspectorControls, ColorPalette, and MediaUpload components and use those to create a configurable block.

We’ll start off with the work from the previous article.  The completed repo for the last article is located here in the article3/styles branch.  You can pull that down to pick up right where we are now.  I have also pushed a finished hero block branch here in case you want to see it in all its glory- article4/hero-block.

Editing some of the details about our Gutenberg block first…

Let’s start by editing some of the meta information about our block.  This isn’t strictly necessary, but I’d like the title of the block to now be “Image Hero Block” so I know what it is.  I’m also changing the icon because I want it to look more like an image.

...

registerBlockType('firstgutyblocks/hero-image', {
    title: "Hero Image Block",
    icon: 'format-image',
    category: 'common',

...

Now keep in mind that since I’ve updated the string to ‘firstgutyblocks/hero-image’ I need to make sure that the php functions for our plugins are also updated.  They will be paying attention to that namespace/blockname that we have here.  So I’ve updated my firstgutyblocks.php to this:

function firstgutyblocks_hero_image_editor_assets() {
    wp_enqueue_script(
        'firstgutyblocks/hero-image',
        plugins_url( 'build/index.build.js', __FILE__ ),
        array( 'wp-blocks', 'wp-element' )
    );
    wp_enqueue_style(
		'firstgutyblocks/hero-image-editor-style',
        plugins_url( 'src/editor.css', __FILE__ ),
        array( 'wp-edit-blocks' )
	);
};

add_action( 'enqueue_block_editor_assets', 'firstgutyblocks_hero_image_editor_assets');

function firstgutyblocks_hero_image_assets() {
    wp_enqueue_style(
		'firstgutyblocks/hero-image',
        plugins_url( 'src/view.css', __FILE__ ),
        array( 'wp-blocks' )
	);
}
add_action( 'enqueue_block_assets', 'firstgutyblocks_hero_image_assets');

Now, if you have ‘npm run watch’ running in the background, you should be able to load up the editor and see a newly-named block with that image icon in the block options list.

WordPress Gutenberg editor menu open and displaying "Hero Image Block" as an option

Now let’s make markup for our hero image block

We are going to make a block in which the user can upload an image as a background.  We’ll also let them select colors for text and for the transparent overlay.  We’ll also let them select a padding height to determine the hero height.

First, let’s clear out our editor.css and view.css files so they are empty.

Second, we’re going to update the block by doing the following in the edit method:

edit(props) {

    const { 
        setAttributes, 
        attributes,
        className
    } = props;

    function onTextChange(changes) {
        setAttributes({
            textString: changes
        });
    }

    return (
        <div className={className}>
            {/* Adding an overlay element */}
            <div className="overlay"></div>
            <RichText
                tagName="h2"
                className="content" // adding a class we can target
                value={attributes.textString}
                onChange={onTextChange}
                placeholder="Enter your text here!"
                />
        </div>
    );
},

save(props) {

    const { attributes, className } = props;

    return (
        <div className={className}>
            <div className="overlay"></div>
            {/* the class also needs to be added to the h2 for RichText */}
            <h2 class="content">{attributes.textString}</h2>
        </div>
    );
}

We already had an editable rich text field.  Now we have a div that will act as our transparent overlay, and we’ve added classes to target with our css.  Also, remember to make these changes in your save method!

If you save and refresh your editor you can see that our markup is in place.  I went to the preview just to check the markup is the way I want it.

Markup for our gutenberg block is showing in the correct spots
Beautiful

Styling the hero image block

Let’s add a background image to our ‘wp-block-firstgutyblocks-hero-image’ div.  You have choices here- you can do styles through css, or you can place styles inline in the jsx.  There are many, many fights raging over whether we should ever place styles inline.  There are some really cool projects that allow you to basically keep all styles in our javascript.  I basically ask myself “Is this a style that the user will want to edit themselves?  Or is it static?”  If it is user-changeable then I go for inline.

Hence, we will make our background image inline.  To make sure it’s working, I’m going to place an inline style.  Here is the code for my edit method:

return (
    <div 
        className={className}
        style={{
            backgroundImage: `url('http://placehold.it/1440x700')`,
            backgroundSize: 'cover',
            backgroundPosition: 'center'
        }}>
        <div className="overlay"></div> {/* Adding an overlay element */}
        <RichText
            tagName="h2"
            className="content" // adding a class we can target
            value={attributes.textString}
            onChange={onTextChange}
            placeholder="Enter your text here!"
            />
    </div>
);

!!!Make sure you do this in your save method container div as well!!! I would load the block in the editor to make sure that the background image is showing up in both the editing block and the saved block.

If you aren’t familiar with how those inline styles are happening, here’s a pretty good overview.  Basically, you create an object that looks a bit like markup, but some of the property names have to be camel-cased.  We will be using this a lot in our blocks because many things the user wants control over are styles.

But the point here is that we now have a place that javascript determines the background image.

Let’s do a few more styles to make things look a little prettier…

/* view.css */
.wp-block-firstgutyblocks-hero-image {
    padding: 4em 0;
    text-align: center;
}

Now we’re starting to see a hero block emerge:

A Gutenberg block in the editor showing the hero block styling

Just one more thing: let’s create the styles we need to get that overlay div working.

/* view.css */
.wp-block-firstgutyblocks-hero-image {
    position: relative;
    padding: 4em 0;
    text-align: center;
}

.wp-block-firstgutyblocks-hero-image .overlay {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: rgba(150,0,0,.3);
}

.wp-block-firstgutyblocks-hero-image .content {
    position: relative;
    z-index: 1;
}

So we made the container div the position relative element for our block.  We then position the overlay absolutely on the parent and make sure it covers the entire parent.  This will give that overlay look- and for now we’re adding a random rgba color to show it’s working.

We also need to position relative the content string so that we can z-index it and lift it above the overlay.

So far so good!

The hero image block has a transparent overlay and properly positioned text.

Adding a settings panel for our block using InspectorControls

Alright, so now we’re going to let the user choose two things: the overlay color and the text color.  First, let us import a block called InspectorControls.  We’re going to add this as part of our edit method only.  The idea is that when the block is selected, these options will show on the right side in the block settings.  So let’s add the following…

const { 
    registerBlockType,
} = wp.blocks;

const {
    RichText,
    InspectorControls // New component!
} = wp.editor;

...

edit(props) {
    const { 
        setAttributes, 
        attributes,
        className,
        focus // this is "true" when the user clicks on the block
    } = props;

...

return ([
    <InspectorControls>
        This text will show when the box is selected
    </InspectorControls>,
    <div 
        className={className}
        style={{
            backgroundImage: `url('http://placehold.it/1440x700')`,
            backgroundSize: 'cover',
            backgroundPosition: 'center'
        }}>
        <div className="overlay"></div> {/* Adding an overlay element */}
        <RichText
            tagName="h2"
            className="content" // adding a class we can target
            value={attributes.textString}
            onChange={onTextChange}
            placeholder="Enter your text here!"
            />
    </div>
]);

There’s a lot going on in the return part of the code above.

  1. React can render an array of things.  It’s easiest to return an array that has the InspectorControls separate from the actual block
  2. Anything inside of the InspectorControls elements will show in the sidebar in the editor.

If you refresh the block in the editor and click on the block, in the sidebar you should see your text.

Adding actual settings to the settings panel

Whew… this is getting long.

Anyway- we have our settings panel set up.  Let’s import another pre-made color tool so we don’t have to work too much.  Let’s import ColorPalette and use it just to show what it is.

const { 
    registerBlockType,
} = wp.blocks;

const {
    RichText,
    InspectorControls,
    ColorPalette
} = wp.editor;

...

<InspectorControls>
    <div>
        <strong>Select a font color:</strong>
        <ColorPalette />
    </div>
</InspectorControls>,

We should see when we reload the editor and click on the block:

So no we actually need to wire this color palette to the block and make it change the font color.  We will first: make a fontColor attribute, second: hook up an onChange function to the colorPalette to make it change the color, and third: create an inline style for the text that is based on the fontColor attribute.

attributes: {
    textString: {
        type: 'array',
        source: 'children',
        selector: 'h2',
    },
    fontColor: { // NEW attribute!
        type: 'string',
        default: 'black'
    }
},

...

// in the edit method, we are peeling off this attribute from props
const { 
    setAttributes, 
    attributes,
    className,
    focus
} = props;
const { fontColor } = props.attributes; {/* new! */}

...

//create a handler that will set the color when you click on the ColorPalette
function onTextColorChange(changes) {
    setAttributes({
        fontColor: changes
    })
}

...

return ([
    <InspectorControls>
        <div>
            <strong>Select a font color:</strong>
            <ColorPalette
                value={fontColor} {/* new! */}
                onChange={onTextColorChange} {/* new! */}
                />
        </div>
    </InspectorControls>,
    <div 
        className={className}
        style={{
            backgroundImage: `url('http://placehold.it/1440x700')`,
            backgroundSize: 'cover',
            backgroundPosition: 'center'
        }}>
        <div className="overlay"></div>
        <RichText
            tagName="h2"
            className="content"
            value={attributes.textString}
            onChange={onTextChange}
            placeholder="Enter your text here!"
            style={{color: fontColor}}  {/* new! */}
            />
    </div>
]);

...

//Make sure to update the save method text styles:
save(props) {

    const { attributes, className } = props;
    const { fontColor } = props.attributes;

    return (
        <div 
            className={className}
            style={{
                backgroundImage: `url('http://placehold.it/1440x700')`,
                backgroundSize: 'cover',
                backgroundPosition: 'center'
            }}>
            <div className="overlay"></div>
            <h2 class="content" style={{ color:fontColor }}>{attributes.textString}</h2>
        </div>
    );
}

To be continued…

This is getting too long to keep to one post.  I will be writing a part 2 where we allow editors to pick not only the text color, but also the gradient color.  We’ll also go over how to implement a MediaUpload and display custom images.

Here’s your homework: See if you can implement a second ColorPalette that changes the transparent overlay. (You will need to create another attribute.)  This will be a good test to see if you have absorbed all that went into the hero block so far.

Edit: Part 2 is now up

Prerequisites:

Gutenberg Blocks may seem overwhelming, but I’m hoping to clear away just enough details so that we can see what’s going on at the heart of this new editor.  I’m assuming that:

  • You’re familiar with some build processes with babel
  • You’ve done enough React to be familiar with JSX
  • You’re primarily Javascript/html/css focused.

Outline:

Here are the steps we’ll take to get a block loaded in the Gutenberg editor.  We plan on making a single block with pre-rendered text.  (No interactivity, CSS, fancy stuff yet)

  1. Set up WordPress and a folder structure
  2. Create a build process with webpack
  3. Call the block’s javascript into the editor with php
  4. Register a block with javascript

To see the finished product, you can see the repo here

WordPress Gutenberg and folder structure:

Make sure that you have installed and activated the Gutenberg plugin.

I use local by flywheel to quickly spin up instances of WordPress. Whichever way you choose to set up your WordPress, you’ll need a folder inside of your plugins folder with your plugin title.

Inside this firstgutyblocks folder we will have a php file that I’ve named “firstgutyblocks.php”.  This will contain the plugin information.  You’ll need to include these comments so WordPress knows what to do with this file:

<?php
/**
 * Plugin Name: First Guty Blocks
 * Description: Our first Gutenberg Blocks!
 * Version: 1.0.0
 * Author: Jim Schofield
 *
 * @package firstgutyblocks
 */

// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

Before moving on, go into wp-admin and activate our plugin!

Set up the Gutenberg build process

Time to set up Webpack

Webpack’s role is to transpile our JSX into friendly javascript.  If this is unfamiliar to you, take a look here and check out babel.  There are ways to write code in vanilla javascript instead, but I don’t recommend it.  JSX is the bread and butter of React applications, and if you look at the source code of Gutenberg, that’s about all you’ll see.  So it’s best to get comfy with it 🙂  It’ll save you time in the long run.

In the terminal, go to your firstgutyblocks folder and init npm.

npm init

It will ask you to fill in information like project names, etc., but you can just go with defaults (just keep pressing enter).  Then, install some dependencies:

npm install --save-dev webpack webpack-cli babel-core babel-loader babel-preset-env babel-preset-react

That’s a lot… so here’s the what and why for all of those things:

  • webpack – our asset bundler/task runner of choice today
  • webpack-cli – allows us to use some commands in the command line that are useful
  • babel-core – the thing that will transform our bleeding edge javascript into plain ol javascript
  • babel-loader –  allows us to use babel inside of webpack
  • babel-preset-env and babel-preset-react – basically the rules babel follows to transform our javascript

So now that we have all of those dependencies, let’s start making webpack work…

We’ll need to create a webpack.config.js file in the firstgutyblocks folder and configure it to build what we want, where we want, how we want:

// node module that let's us do file system stuffs...
const path = require('path');

// Webpack expects an exported object with all the configurations, so we export an object here
module.exports = {
    entry: './src/index.js', // Where to find our main js
    output: {
        // where we want our built file to go to and be named
        // I name it index.build.js so I keep index files separate
        filename: 'index.build.js',
        // we're going to put our built file in a './build/' folder
        path: path.resolve(__dirname, 'build')
    }, 
    module: {
        rules: [
            { 
                // basically tells webpack to use babel with the correct presets
                test: /\.js$/,
                loader: 'babel-loader',
                query: {
                    presets: ['babel-preset-env', 'babel-preset-react']
                }
            }
        ]
    },
    // Webpack yells at you if you don't choose a mode...
    mode: 'development'
}

Now… we’re about to actually run webpack.

First, let’s go to our package.json and add the following to our “scripts” key:

...
"scripts": {
    "build": "webpack"
    "test": "echo \"Error: no test specified\" && exit 1"
}
...

This is a convenience thing- to run a build we type “npm run build”.  If you do it right now, you will see an error because we don’t have a javascript file yet…

So let’s make a “src” folder and create an “index.js” in that.  I’m going to add this code to said index file:

const message = <h1>Test JSX!</h1>;
console.log("Hello World!");

And now if you do “npm run build” again you should have a nice, pleasant, build message!

So what’s with the javascript that I added?  Well, first, I want a console log that’s run when the script is loaded letting me know when the javascript is loaded and working correctly in the editor.  Second, I want to make sure that the transpiling is taking place when I run webpack.  So if I try to use jsx as I am on the first line, it will fail when I try to run webpack if something’s not configured or installed.

So far, we have webpack building our javascript into a file in the build folder, and our plugin folder should look like this:

Calling the javascript in php

Now, we actually want WordPress to take that javascript and load it when we open up the shiny new Gutenberg editor.  So we go back to the plugin file and add a function that’s called in a new shiny WordPress hook ‘enqueue_block_editor_assets’.  Basically, we want WordPress to know about our new Gutenberg block and where the javascript file is located.  Let’s add to our ‘firstgutyblocks.php’ file…

/* this function name I believe is arbitrary, but I 
* generally see  people follow 
* {namespace}_{blockname}_editor_assets as a 
* naming convention
*/
function firstgutyblocks_hello_world_editor_assets() {
    wp_enqueue_script(
        // the name - also generally {namespace/blockname}
        'firstgutyblocks/hello-world',
        // where the javscript is located
        plugins_url( 'build/index.build.js', __FILE__ ),
        // and dependencies WordPress needs to serve up for us
        // you must have these two for the most basic block
        array( 'wp-blocks', 'wp-element' )
    );
};

// and then, we actually have the function run when the editor loads...
add_action( 'enqueue_block_editor_assets', 'firstgutyblocks_hello_world_editor_assets' );

OKAY.  NOW we can actually log in to WordPress and open a page or a post.  If all goes well, you will now be rewarded with a “A Guty Block is Present!” console log when the editor starts up.  You’ll need to reload the editor if it’s already open.

So we haven’t actually made a block or added it to the editor yet.  Most of the battle has been fought, we’re almost there…

Register our block in javascript

We have a process to get Javascript building.  We have our one javascript file loading when the editor loads.  Now it’s actually time to create the block in javascript!

Let’s go back to the index.js file and remove the work before.  First, let’s get what we need to register a block:

const { registerBlockType} = wp.blocks;
// using destructuring to basically do:
// const registerBlockType = wp.blocks.registerBlockType

wp.blocks is provided for us on the window already.  We need to retrieve this function to register our block:

const { registerBlockType} = wp.blocks;

registerBlockType('firstgutyblocks/hello-world', { 
        // We put the Guty config stuff here
    }
);

The method registerBlockType takes two arguments.  The first is the block is the block’s unique name.  The second a config object.  This config object is where the React part takes over.  Let’s fill in that object now.

const { registerBlockType} = wp.blocks;

registerBlockType('firstgutyblocks/hello-world',{ 
        // We put the Guty config stuff here
        title: 'My First Guty Block!', //Title seen in the editor for the block
        icon: 'smiley', //using WordPress' dashboard icons
        category: 'common',

        // edit is basically the 'render' function for your block.  
        // It can be a live react app inside the editor.
        edit() {
            return <h1>Hello Editor!</h1>;
        },

        // save is the 'render' function, but it's used to generate a static html 
        // string, and it is not a live react app.
        save() {
            return <h1>Hello World!</h1>;
        }
    }
);`

When you load the editor, you should be able to select “My First Guty Block!”  You should then see a static h1 element saying “Hello Editor!”  If you publish, you would see a static h1 element on the page saying “Hello World!”

Review

We’ve set up a WordPress plugin to register a Gutenberg block and load this block in the editor.  We’ve set up a webpack build process to build all the files we need.

Although this static example is not so impressive to look at, I promise that there are some exciting things possible in this new editor.  I plan to write some more articles on how to make make interactive and truly WYSIWYG blocks, adding CSS, and doing advanced things like API calls and rendering react applications on the front end.

In the meantime, I have a repo of some general blocks I’ve been playing around with if you’re interested.

Check out part 2: Creating an editable field