A first simple block with some ES6 code – it’s not as scary as it sounds

I’m currently on vacation and had some tech free days, so my blog post comes a bit later this week. In the previous post, I’ve shown you, how you can write a block without any ES6/React code. This week I want to show you the minimum you have to know to get the full potential of modern JavaScript while still keeping it simple.

Create a block with the “create-block” script

As I’ve also mentioned, that I would highly recommend using the create-block package to create your first little plugin. This will create a lot of files for you, and you are ready to go. We create the example from the last post by running this command in the wp-content/plugins folder:

npx @wordpress/create-block random-posts-server-side-render-block-es6

This will give you the following files in the newly created plugin directory:

$ tree
.
├── node_modules
├── package.json
├── random-posts-server-side-render-block-es6.php
├── readme.txt
└── src
    ├── block.json
    ├── edit.js
    ├── editor.scss
    ├── index.js
    ├── save.js
    └── style.scss

In the node_modules folder we will have all the files we would need for compiling the ES6 code so browsers can use them. The package.json defines all the dependecies that are installed as well the scripts that would run.

The block definition

The most important file in a “block plugin” is the src/block.json file. It defines the name, title, icon and other details:

{
    "$schema": "https://schemas.wp.org/trunk/block.json",
    "apiVersion": 2,
    "name": "rpssrb/random-posts",
    "version": "0.1.0",
    "title": "Random Posts",
    "category": "widgets",
    "icon": "smiley",
    "description": "An example for a ServerSideRender block using minimal ES6 code.",
    "supports": {
        "html": false
    },
    "textdomain": "random-posts-server-side-render-block-es6",
    "editorScript": "file:./index.js",
    "editorStyle": "file:./index.css",
    "style": "file:./style-index.css"
}

At the end of the file you will find three really useful lines. They define where the asset files are located. So while we had to use wp_enqueue_scripts in the last blog post, we get this all for free. No need to do that in PHP and handling the check for this file, it’s dependecies and the timestamp for caching ourselves. Just this one feature make it worth using a bit more of modern block development.

Now you could still write only ES5 code into the JavaScript files, but let’s take a look on how our simple example look like with modern JavaScript.

Registering a server side rendered block with ES6

As you have seen in the file system output above, you usually get three JS files. The index.js file will register the block. The edit.js file is used for rendering the block in the editor including controls for it’s options. The save.js will finally hold the functions to save the block content into the post content. Those two extra files can be used, but for a simple block you can also just use the index.js file. And for really complex blocks you would even split up the edit.js into smaller (reusable) parts. To keep it simple again, we will just use the index.js file:

import ServerSideRender from '@wordpress/server-side-render';
import { registerBlockType } from '@wordpress/blocks';
import './editor.scss';
import './style.scss';
import metadata from './block.json';

registerBlockType(
    metadata.name,
    {
        edit() {
            return (
                <ServerSideRender
                    block="rpssrb/random-posts"
                />
            );
        }
    }
);

In order to use components and functions in ES6, we have to import them. We are going to use the ServerSideRender component as well as the registerBlockType function. When you compare this code snippet with the ES5 one from the last blog post, you will recognize that it does not look all that different. This “weirdly looking HTML tag” is JSX, an extension to HTML that React is using to build its components. When passing parameters to those components, you are using attributes similar to HTML (instead of using a JSON object, as in the ES5 variant) and in those attributes you can even use JavaScript. For our ServerSideRender component, we only need to pass the static block name.

As you might have recognized, we are getting the name for the block in the registerBlockType function from our metadata we also import. This will give us the opportunity to get any of the declared values from this file. In this very simple example, we only need the name. We could also use this in the block attribute of the ServerSideRender component, but here we just use a static string.

The two lines I have not yet covered are the imports for the SCSS files. When you use the @wordpress/scripts package that being installed with the npx command above, you will get Sass compilation for free. You just name the two files editor.scss and style.scss and they will be compiled for either just the block editor or for the front end as well.

Now, after you have written this beautiful code, you finally have to compile it. If you only want to do it once (in a minified way, suitable for production use), you run npm run build or while actively developing you use npm run start so you always have a (verbose version, which is better for debugging) of the code you just write.

Registering the PHP callback function for the server side rendered block

As we are still writing a block that would get its content from the PHP backend, we also still have to register the callback function. It looks quite similar to our previous code. But instead of using static string, we can also use the index.js file to register the block in PHP and adding the callback function parameter:

function create_block_rpssrb_block_init() {
	register_block_type(
		__DIR__ . '/build',
		[
			'render_callback' => 'rpssrb_render_callback',
		]
	);
}
add_action( 'init', 'create_block_rpssrb_block_init' );

Instead of using the blocks name, we use the path to our build directory that is being created using the build scripts. In this folder, the PHP function will look for an index.js file and use the block name from this file.

We also use the same implementation for our callback function you can find in the previous blog post. And again you can also use the “bonus” of having a shortcode for the callback as well.

Conclusion

It’s really not that hard to create a block using ES6 syntax, and using the create-block package (or using the @wordpress/script package) make the hard part of getting the compilation running a lot easier. The only thing you have to do – and what might be a bit though – is installing node and then installing npm on your machine. Even then, you have to keep these two up to date and working with the packages you are using. This can really be annoying from time to time.

The reason why it’s worth to do all that, I will cover in my next blog post, when we add some simple controls to our block to make it more usable.

Posted by

Bernhard is a full time web developer who likes to write WordPress plugins in his free time and is an active member of the WP Meetups in Berlin and Potsdam.

Leave a Reply

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