How to create a (multiple) block plugin for WordPress
Tags: wordpress, tutorial, programming, webdev
Published: 2021-08-08 09:56:44

*Photo by <a href="https://unsplash.com/@elodieoudot?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Elodie Oudot</a> on <a href="https://unsplash.com/s/photos/lego-blocks?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Unsplash</a>*
  
**Want the files?**
If you're impatient like me, you can go straight for [the code on GitHub](https://github.com/rmorse/multiple-blocks-plugin).

## 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](https://developer.wordpress.org/block-editor/reference-guides/packages/packages-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:
```shell
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**:
![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/41tcahli846qqbyph1i4.png)
 
## 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](https://developer.wordpress.org/block-editor/reference-guides/block-api/block-metadata/) - 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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fykpqxkh7bdo21zmrrxb.png)

###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:
```json
"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):
```javascript
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:
```scss
.wp-block-create-block-multiple-blocks-plugin
```
However the class name is based on our block name and **should be changed to**:
```scss
.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:
```php
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:

```json
"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):
```shell
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:
```shell
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.

[Download from GitHub](https://github.com/rmorse/multiple-blocks-plugin)


-----

Questions + feedback are most welcome.

If you liked this post, come and say hi over [on Twitter](https://twitter.com/rmors_) - my plan is to create more WordPress developer related content in the near future.