DEV Community

Cover image for How to create a (multiple) block plugin for WordPress
Ross Morsali
Ross Morsali

Posted on • Updated on

How to create a (multiple) block plugin for WordPress

Photo by Elodie Oudot on Unsplash

Want the files?
If you're impatient like me, you can go straight for the code on GitHub.

Creating a single block plugin

There's already a great package out there for creating a single block plugin, so we're going to use that as the foundation for creating our multiple block plugin.

Since the release of the @wordpress/create-block package, creating a block plugin with an an awesome development setup (scaffolding) has gotten a lot easier - it takes a lot of the hard work out of setting up webpack, a transpiler, scss + a whole lot more - although I'm sure some of you would still rather roll your own.

If you want to get going quickly I recommend getting familiar - and this post assumes you already know how to use @wordpress/create-block, but we'll still go through the steps from the beginning.

Anyway, I saw a question recently (I think on Twitter) - something like, "How can I create multiple blocks with this tool"?

So I've been digging into this and that's what I aim to share in this post.

Setting up @wordpress/create-block

I'll try to be brief on this, but you can follow the link above for a more in depth setup guide.

Lets start by creating a new plugin using @wordpress/create-block.

In a local development environment, locate your /wp-content/plugins/ directory and open a terminal from there, then enter:

npx @wordpress/create-block multiple-blocks-plugin
Enter fullscreen mode Exit fullscreen mode

It can take some time to setup, grab a drink...

This creates the main plugin directory with the name multiple-blocks-plugin and the default project structure. Enter this directory and start the dev script:

cd multiple-blocks-plugin
npm run start
Enter fullscreen mode Exit fullscreen mode

Now the plugin is ready to use and it can be enabled via the plugins page in your WordPress dashboard.

Once enabled, verify that setup has gone well by adding the block via the post editor - it will be called Multiple Blocks Plugin:
image

Existing structure

Assuming the above went well, we can now take a look at the project structure, and visualise how this needs to be re-arranged in order to support multiple blocks.

I won't be explaining all the files / folders, just the relevant ones.

multiple-blocks-plugin.php

This is the main plugin file, and it's incredibly simple - it calls register_block_type() with the current directory as an argument, which then tries to locate a block.json file (and registers it).

block.json

This is the main configuration file for your block, where you define basic settings - it also includes references to the other files that are used with your block (the editor script, editor style and shared style).

src

The src directory is where you'll be doing most of the work on your block. This is the place you'll usually add your block editor functionality as well as your styles.

build

We're using a modern development stack - which means we can write ESNext and JSX code in our project, but before it can be used on all browsers it must be converted (transpiled). This process is handled automatically and the result is placed in this directory.

package.json

Amongst other things, this file contains the npm run start script used to build your block, we'll be updating this and adding scripts for each block you want to create.

Convert into a multiple blocks plugin

So now let's begin the process of transforming the existing structure, into a structure that supports multiple blocks.

The main thing to note here is, block.json, src, and build all belong to the "block", whereas all the other files in the project are related to the plugin / development setup.

0. Create a directory to house all blocks

Let's name this something imaginative, like... blocks:
multiple-blocks-plugin/blocks/

The next steps can be repeated for every new block you want to create.

1. Create a directory for the block

In this case we'll use buy-button:
multiple-blocks-plugin/blocks/buy-button/

2. Identify & copy the block related files

We can move (if it's the first time doing this, otherwise copy) block.json, src and build in to the new block directory.

Your directory structure should look something like this:
image

3. Rename block settings in block.json

This step is important, we need to update the block name and title to something unique. These are the two properties to change:

"name": "multiple-blocks-plugin/buy-button",
"title": "Buy Button",
Enter fullscreen mode Exit fullscreen mode

Take a note of the new name - multiple-blocks-plugin/buy-button - we'll be needing it in the next step.

4. Update reference to the new block name

In your blocks src directory, edit index.js:
multiple-blocks-plugin/buy-button/src/index.js

and modify the line containing registerBlockType()

Lets update the name to use our new name (from the last step):

registerBlockType( 'multiple-blocks-plugin/buy-button', {
Enter fullscreen mode Exit fullscreen mode

5. Update CSS classes

There are two SCSS files to locate:

  • blocks/buy-button/src/style.scss
  • blocks/buy-button/src/editor.scss

They both contain the class:

.wp-block-create-block-multiple-blocks-plugin
Enter fullscreen mode Exit fullscreen mode

However the class name is based on our block name and should be changed to:

.wp-block-multiple-blocks-plugin-buy-button
Enter fullscreen mode Exit fullscreen mode

6. Update multiple-blocks-plugin.php to reference the new location

Here we simply want to change the directory used in register_block_type (if it's the first time doing this) or add an additional register_block_type to reference our new block directory.

We can update the main function like this:

function create_block_multiple_blocks_plugin_block_init() {
    register_block_type( plugin_dir_path( __FILE__ ) . 'blocks/buy-button/' );

    // Additional blocks would be registered here
    // register_block_type( plugin_dir_path( __FILE__ ) . 'blocks/another-block/' );
}
Enter fullscreen mode Exit fullscreen mode

7. Create scripts for your new block in package.json

When we use npm run start we're running a script defined in package.json, using some default settings.

Because we moved our block files, we'll need to create scripts to build them in their new locations. In the scripts section of package.json you'll need to add:

"start:buy-button": "wp-scripts start blocks/buy-button/src/index.js --output-path=blocks/buy-button/build/",
"build:buy-button": "wp-scripts build blocks/buy-button/src/index.js --output-path=blocks/buy-button/build/"
Enter fullscreen mode Exit fullscreen mode

Notice that we specified an input path pointing to the src directory of our block, and output path pointing the build directory of our block, and that we updated the scripts by adding our block name :buy-button to the script name.

With the above addition, this is the new way to start your dev build (from the command line):

npm run start:buy-button
Enter fullscreen mode Exit fullscreen mode

You'll need to use that instead of just npm run start for running in development mode and for production you can use:

npm run build:buy-button
Enter fullscreen mode Exit fullscreen mode

And that's it, you're good to go - what you do with these blocks is up to you!

Summary

So the first run through, we essentially moved the default generated block files, into a sub-directory and re-wired the project to use the new name + location.

For each new block you want to create, the process will be similar, just follow steps 1 - 7. All you need to do is copy the default block files over (from an existing project, or grab a fresh copy from @wordpress/create-block) -

Note: the build folder is in fact not necessary (although we moved it earlier) - it is automatically generated when you run the command line scripts.

Repo + files

The project is ready to be used and comes with 2 blocks - Buy Button and Hero Block (they don't do anything though) - but I do recommend learning the above process and creating additional blocks yourself.

Download from GitHub


Questions + feedback are most welcome.

If you liked this post, come and say hi over on Twitter - my plan is to create more WordPress developer related content in the near future.

Top comments (5)

Collapse
 
danielinv profile image
DanielINV

Hey Ross,

Thanks for your work on this real helpful!

I think since WP 5.9 there have been some changes with the block.json file as it has moved from outside of the src folder to inside this has messed with both the registration of the blocks from the plugin.php file as now it expects the block.json file to be inside the build; to fix this I simply edited the wp-scripts run build file from what you put to something like this to copy file block.json file from src to build:

"build:image-banner": "wp-scripts build blocks/image-banner/src/index.js --output-path=blocks/image-banner/build ; cp blocks/image-banner/src/block.json blocks/image-banner/build/block.json"

This works fine for the build and it is recognised by WordPress but the issue comes with the start script as it is watched it ignores/removes the cp command entirely.

For now to manage it, i will run build:image-banner": "wp-scripts start blocks/image-banner/src/index.js --output-path=blocks/image-banner/build" and physically copy the block.json file into the build folder.

Would love to know if you find any way to solve this!

Also for anyone else that is reading, your plugin file will now reference the block's build directory instead of just the block's root directory.

Thanks again Ross

Collapse
 
mrbjjackson profile image
Ben Jackson

Hi Dan,
I've been able to avoid this by removing the block.json file outside of the src directory (as it is in Ross' example) and then changing the lines in the file as follows:

from:
"editorScript": "file:./index.js",
"editorStyle": "file:./index.css",
"style": "file:./style-index.css"

to:

"editorScript": "file:.**/build/**index.js",
"editorStyle": "file:.**/build/**index.css",
"style": "file:.**/build/**style-index.css"

Ross: thanks for this very helpful tutorial

Collapse
 
rmorse profile image
Ross Morsali • Edited

Thanks for the headsup! I'm caught up in a couple of projects at the moment but it certainly looks like I need to revisit this to see what's changed.

I am aware there are some big changes coming which will natively allow you to create multiple block plugins - so you won't need to follow this tutorial at all! (or likely I'll update it with the new approach)

Check out this thread on it, I think we're close to a final solution all within wp-scripts - github.com/WordPress/gutenberg/iss...

Collapse
 
hardlynoticeable profile image
Stephen Akins

I'm at your 4th step, and you write:

In your blocks src directory, edit index.js:
multiple-blocks-plugin/buy-button/src/index.js

But I think you meant:

multiple-blocks-plugin/blocks/buy-button/src/index.js

Collapse
 
kevmarsden profile image
Kevin Marsden

Thanks for the tutorial!

For others running into errors because the location of the block.json file changed, I found this answer on the WordPress StackExchange to be helpful:

wordpress.stackexchange.com/a/4077...