Build a Block Series – Part 2: WordPress Plugin

The second part of my series walking through building a Gutenberg block for the WordPress editor.

See Part 1: Development Environment.

Part two covers creating a WordPress plugin and setting up the JavaScript build for block development. After this part, all the pieces are in place to start creating a block.

WordPress Plugin

A WordPress plugin is a set of files in a directory within the sites wp-content/plugins directory. For this example, I’m going to create a QRCode Block, so I created a new directory at: wp-content/plugins/qrcode-block

All of the plugin files we develop will be within this directory.

I created a new PHP file qrcode-block.php that is the main plugin file. At the top of this file, I included the appropriate Plugin Header comment block which defines our plugin.

 /**
   * Plugin Name: QRCode Block
   * Plugin URI:  https://github.com/mkaz/qrcode-block
   * Description: A block to insert a QRCode
   * Version:     0.1.0
   * Author:      Marcus Kazmierczak
   * Author URI:  https://mkaz.blog
   * Text Domain: qrcode-block
   * License:     GPL v2 or later
   * License URI: http://www.gnu.org/licenses/gpl-2.0.txt
   */

This is all that is needed to stub out a plugin, it won’t do anything. However, it is good to get the basics in place and build up from there. The plugin should be listed on the Plugins admin page and can be activated.

For more on creating a WordPress plugin see Plugin Basics, and Plugin Header requirements for explanation and additional fields you can include in your plugin header.

package.json

The package.json file defines the JavaScript properties for your project. This is a standard file used by NPM for defining properties and scripts it can run, the file and process is not specific to WordPress.

From the plugin directory, you can run npm init and it will walk you through a short set of prompts to create the fields for your package.json file.

After your package.json file is created, you can install dependencies. The only dependency we will need here is the @wordpress/scripts package which bundles the tools and configurations we need to build Gutenberg blocks.

Install: npm install --save-dev @wordpress/scripts

The --save-dev parameter will automatically update the package.json file with the dependency under the property devDependencies

This installs the necessary packages, dependencies and binaries we will use under the node_modules directory.

To use the scripts package, setup two commands using the scripts property of package.json.

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

These are run using: npm run build or npm run start which will call the appropriate binary and command we need.

Use npm run build for running once to create a production build.

Use npm run start for creating a development build and starts a watch process that waits and watches for changes to the file and will rebuild each time it is saved.

First, you need to create the file it is looking for. The default configuration for the scripts package expects the source file to be at: src/index.js

Create the above file, you can add the simple debug statement to it.

console.log("Hello");

Run: npm run build to create the built file, the scripts package will save the built file to build/index.js

Plugin to Load Script

To load the script, so it is run within the editor, you need to tell WordPress about the script. You do this by adding the following action, which will run during the init cycle when WordPress loads the page.

add_action( 'init', function() {

    $asset_file = include( plugin_dir_path( __FILE__ ) . 'build/index.asset.php' );

    wp_register_script( 'mkaz-qrcode-block-script',
        plugins_url( 'build/index.js', __FILE__ ),
        $asset_file['dependencies'],
        $asset_file['version']
    );

    register_block_type( 'mkaz/qrcode-block', array(
        'editor_script' => 'mkaz-qrcode-block-script',
    ));

 });

The build process creates a secondary asset file that contains the list of dependencies and a file version based on the timestamp.

The wp_register_script function registers a name, called the handle, and relates that name to the script file. The dependencies are used to specify if the script requires including other libraries. The version is specified so the browser will reload if the file changed.

The register_block_type function registers the block we are going to create and specifies the editor_script file handle registered. So now when the editor loads it will load this script.

With the above in place, create a new post to load the editor and check the developer tools show “Hello” in the console.

To open the developer tools in Firefox, use the menu selecting Web Developer -> Toggle Tools, or the keyboard shortcuts on Windows is Ctrl+Shift+I, or on Mac Cmd+Shift+I. For me on Linux, the F12 key also works. You can then click Console to view logs.

It is a good skill to learn and get comfortable using the web console. This is where JavaScript errors are shown and a nice way to test out snippets of JavaScript. See Firefox Developer Tools documentation.

Try running npm run start that will start the watch process for automatic rebuilds. If you then make an update to src/index.js file, you will see the build run, and if you reload the WordPress editor you’ll see the change.

For more info, see the build section of the Getting Started with JavaScript tutorial in the WordPress Handbook.

Summary

Hopefully, at this point, you have your plugin created and activate. You have created the package.json with the @wordpress/scripts dependency, and build and start scripts defined. You can create a source JavaScript that gets built and the plugin loads. With this, all our pieces are in place to start building a block.