Custom Block Development Part-4: Advance Custom Block with ESNext

This is the fourth article of our custom block development series, in this article we are taking things to next level and going to get introduced to more advanced JavaScript which we will use to code our custom block. If you haven’t read our previous article yet click on this link to read it or you can check our index article to get the list of all published articles on this series.

In previous articles, we have created a beautiful-looking custom block that we can customize and save. We have done that using plain old JavaScript version ES5 and that’s ok if you wanna build something simple and for personal use, you can continue that way if you want. But most developers these days are moving towards ESNext because it makes code more easily readable and it is the future of JavaScript.

What are ES5 and ESNext?

So first let’s start with the basics and take a brief look at what ES5 and ESNext are. So both ES5 and ESNext are scripting language standards defined by ECMA(European Computer Manufacture Association) International. ES5, full name ECMAScript 5 was released back in 2009 and was used widely after that and most of us developers are familiar with it.

Later in 2019 ECMAScript 6 or ES6 was released and consider a massive upgrade over ES5. ESNext is used to refer whatever the upcoming latest version of ECMAScript.

Now you might be thinking if ESNext is newer and better then why we have not started this series with it and why even consider ES5? The answer is because even now most browsers currently still don’t support ESNext fully and you need to set up extra tools to convert your ES6 or ESNext code to ES5 and then feed that to the browser. That’s why I want you to know both and make the decision based on that what you wanna use.

Also since Gutenberg is based on React and React wants you to use JSX– a syntax extension to Javascript then you also find yourself using JSX which is also not supported by most browsers without transforming it.

The benefit of Using ESNext and JSX

If you are still not convinced about using ESNext then let’s take a look at the benefits of using ESNext over ES5. Below I have shared two pieces of code outputting the same thing but one is written in ESNext and another is written in ES5. In the code, I am trying to return an object to render simple HTML on the page.

ESNext:

return <p className="example"> Hello World! </p>;

ES5:

return wp.element.createElement(
    'p',
    { className: 'example' },
    'Hello World!'
);

The difference between both is night and day, and surely the ESNext is many times more easily readable and feels like almost writing HTML. Now try to imagine you want to create a very complex design with a lot of components then which do you prefer? obviously the ESNext.

ES5 to ESNext Transpiler

Since most of the browser still doesn’t fully support ES6/ESNext, we need to use a transpiler to transpile the ESNext code into ES5 to make it browser compatible and in React and WordPress that transpiler is Babel. Simply put we will configure babel and webpack in our project to convert our ESNext code into ES5 code.

We will also use Webpack which is another JavaScript library used to bundle and minified our JavaScript file. Babel and Webpack both run on the node so we’ll gonna use node and npm as well for configuring things.

Create Custom Block with ESNext

Enough talk! Now let’s see in action how we are going to use ESNext for our custom block development. Since we are using ESNext we need some extra steps and tools to run it smoothly we can go start writing things as we did in previous articles using ES5. So let’s see the configuration first. Don’t worry it will require just a couple of manual steps and the rest of the things will be handle by npm and we have to do this only once.

Step 1: Set up the project

So to set up the project first go to your plugins directory and create a new folder with whatever name you prefer. Now open that folder inside the terminal, if you are using vs code you can use the command Ctrl+Shift+` to open the terminal or right click on the folder and select “open in integrated terminal”.

To set up the project you need to create a package.json file for webpack where you store all the configuration and dependencies for your project. You can use two methods one is to create the file manually and fill the JSON or you can use the npm command to create. Just run the following command and it will walk you through the process of creating a package.json file.

npm init

After running this command terminal will ask you the following things:

package name: (advance-custom block) advance-custom-block
version: (1.0.0) 1.0.0
description: Advance custom gutenberg block by WebProTime
entry point: (index.js)
test command:
git repository:
keywords:
author: lazydevpro
license: (ISC)

After that, it will show you the output and ask you to confirm it.

About to write to C:\xampp\htdocs\wordpress\wp-content\plugins\advance custom block\package.json:

{
  "name": "advance-custom-block",
  "version": "1.0.0",
  "description": "Advance custom gutenberg block by WebProTime",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "lazydevpro",
  "license": "ISC"
}


Is this OK? (yes)

Just press Enter to confirm and your package.json file will be created.

Step 2: Install @wordpress/script package

Now the next thing is to install the WordPress script package. This package will help us a lot with our configuration for custom block development. To install this package we will run a command npm install. We can pass --save-devparameter so it will be written in the package.json as a dev dependency. The --save-exactparameter will save the exact version of a dependency so it will not write a range of valid versions. If you wanna learn more about this step you can check npm install documentation.

Just run the following line in the same terminal:

npm install --save-dev --save-exact @wordpress/scripts

After running this command npm will install the WordPress scripts package and create node_modules directory which contains hundreds of subfolders that contain modules and dependencies. It will also create a package-lock.json file. You don’t need to do anything in this directory or file.

Note: Make sure you don’t include this node_modules directory in your actual production plugin because it is not required. The directory is also very huge and not needed.

It will also add the @wordpress/scripts as a dev dependency in the package.json file as shown below.

"devDependencies": {
    "@wordpress/scripts": "18.0.1"
  }

Step 3: Add scripts property

Now the next step is to add scripts property so webpack can compile our code with our command and also look for the changes and recompile when we make changes and save our script file. To do that just open the package.json file and find the “scripts” property and remove the previous commands and add the following text to it.

"scripts": {
  "start": "wp-scripts start",
  "build": "wp-scripts build"
},

After adding the following text our setup is done and now we can run the command npm run buildornpm run start. The buildcommand will run in “production” mode and shrinks the code so it can be downloaded faster but it will make code difficult to read.

While we are developing we can use startthis command will not shrink the code and also keeps checking for the changes and whenever we save the changes it will rebuild the code again. But wait we don’t need to run this yet first now let’s create the files for our custom block.

When you compile your code with startor buildcommand will create transpiled ES5 the actual script file in build/index.js file. And that file is your actual block file and you need to reference that file while registering custom block in PHP.

Step 4: Create the block file

The scripts package expects the source file to be in the src/index.js file, so we will create a folder named src and create an index.js file into that folder. Now in that file, we will write the code for our custom block in ESNext format. For now, I am just converting the code of our previous article in ESNext for the sake of simplicity and so you can compare the changes.

Here is our src/index.js file:

const { registerBlockType } = wp.blocks;
const { RichText } = wp.blockEditor;


// Registering A Block
registerBlockType('wpt/wpt-block', {
    title: 'WPT Custom Block',
    category: 'common',
    icon: 'superhero',
    description: 'First Hello World Block',
    keyword: ['test', 'searchme'],
    attributes: {
        textHeading: {
            type: 'string',
            default: 'Heading'
        },
        textPara:{
            type: 'string',
            default: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.'
        },
        textButton: {
            type: 'string',
            default: 'Click Me'
        },
    
    },

    // Block Edit Function
    edit: props => {
        return( 
            <div className="wpt-back">
                <h2 className="wpt-heading">
                    <RichText 
                    value={props.attributes.textHeading}
                    onChange={content =>  {
                                props.setAttributes( { textHeading: content } );
                            }}
                    />
                </h2>
                <p className="wpt-para">
                    <RichText 
                    value={props.attributes.textPara}
                    onChange={content =>  {
                                props.setAttributes( { textPara: content } );
                            }}
                    />
                </p>
                <a className="wpt-button">
                    <RichText 
                    tagName="a"
                    value={props.attributes.textButton}
                    onChange={content =>  {
                                props.setAttributes( { textButton: content } );
                            }}
                    />
                </a>
            </div>
        )
    },

    //Block Save Function 
    save: props => {
        return( 
            <div className="wpt-back">
                <h2 className="wpt-heading">
                    <RichText.Content value={props.attributes.textHeading} />
                </h2>
                <p className="wpt-para">
                    <RichText.Content value={props.attributes.textPara} />
                </p>
                <a className="wpt-button">
                    <RichText.Content  tagName="a" value={props.attributes.textButton} />
                </a>
            </div>
        )
    },
});

Now in the above code, you can see a big part of it different from our previous article because it was in ES5 and this one is ESNext. So let’s just take a quick look at the difference between both files.

The first thing you may have noticed is instead of using the self-invoking function and passing the wp.blockEditor and wp.blocks as variables. We have declared them as variables at top of our file.

The second big change you can see in our editandsavefunctions, they are no longer using function keyword instead they are now an arrow function.

The third change is in our return statement in editandsavefunctions. The complete structure of the return statement is changed and now it is according to ESNext standards.

To better understand the difference between both compare them side-by-side, you should be able to understand them more easily.

Step 5: Create PHP Plugin File

Now the next step is to create a plugin file so it will add our custom block to the WordPress website. The PHP file here will be the exact same file that we have created in the last article since we will replicate the same custom block in this article with ESNext as well. So you can copy and paste it in the plugin folder one thing you need to change is the path of the script and CSS file.

Also as I have told you earlier the actual script file will be in build/index.js so we will be changing that in our wp_register_scriptfunction. Also, we will add our CSS file to the build folder as well and rename the path accordingly too.

I am changing the plugin name for avoiding any confusion and the code of our plugin.php file will be like the one given below:

<?php
/** 
 *  Plugin Name: Advance Custom Blocks
 *  Plugin URI: https://github.com/ 
 *  Description: A Custom block created for learnirng by WebProTime team. 
 *  Version: 1.0.0 
 *  Author: WebProTime 
 * 
 */

function wpt_register_blocks() {

    // Check if Gutenberg is active.
    if ( ! function_exists( 'register_block_type' ) ) {
        return;
    }

    // Add block script.
    wp_register_script(
        'wpt-block', 
        plugins_url( 'build/index.js', __FILE__ ), //replaced path
        ['wp-blocks', 'wp-editor'] //dependencies
    );

    // Add block style.
    wp_register_style(
        'style',
        plugins_url( 'build/style.css', __FILE__ ),//replaced path
        []
    );


    // Register block script and style.
    register_block_type( 'wpt/wpt-block', [
        'style' => 'style',
        'editor_script' => 'wpt-block',
    ] );
}

add_action( 'init', 'wpt_register_blocks' );

Step 6: Run the code

After that, we need to run our code so it will transpile and create the required file. To run our code we will run the following command in the terminal:

npm run start

After running this command webpack and babel will transpile our ESNext code and create ES5 code in the build folder.

Step 7: Activate the plugin

After that, we need to activate our plugin if you have copied the plugin.php from our previous article then you need to deactivate the previous plugin and activate the new one else it will conflict with it and you’ll see an error. After activating the plugin our custom block will be added to our website.

Step 8: Test the block

custom block

Finally, create a new post or page and add our custom block. You’ll see the exact same custom block as the previous one. And that’s it you have created a block using ESNext. This custom block will work exactly the same as the previous one you should be able to edit the text and on the published website, you’ll see your edited content.

How to continue using ES5

From now on upcoming articles in the tutorial will be in ESNext standard and I will recommend you to continue with ESNext. But in case if you still wanna continue with ES5 then I wanna share a couple of things that will help you do that. On most of the internet, you’ll find codes written for blocks in ESNext you can identify them with edit and save return statements.

Also if you wanna convert any ESNext code into ES5 you can do that on this link. One more thing Gutenberg is adding the documentation in both ESNext and ES5 standards so reference documentation as well when are stuck.

Conclusion

Now you should be able to create your own custom block with editing capabilities using advance ESNext as well as ES5. I hope now you’re able to make a decision on which coding standard you’ll be following. If you have any questions, doubts, or suggestions regarding this article make sure to comment them down below. Also if you are having trouble with following this article comment on the issue as well we will respond ASAP.

You can get the complete source code used in this article and in the complete series on my Github repo.

Have questions or confused about something WordPress Related? Join Our Discord Server & ask a Question

Leave a Comment

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

Scroll to Top
Scroll to Top