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
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
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:
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:
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",
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', {
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
However the class name is based on our block name and should be changed to:
.wp-block-multiple-blocks-plugin-buy-button
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/' );
}
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/"
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
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
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.
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)
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 thesrc
folder to inside this has messed with both the registration of the blocks from theplugin.php
file as now it expects the block.json file to be inside thebuild
; to fix this I simply edited thewp-scripts run build
file from what you put to something like this to copy fileblock.json
file fromsrc
tobuild
:"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 thecp
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
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
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...
I'm at your 4th step, and you write:
But I think you meant:
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...