Intro to Gutenberg Block Development

Please note that this tutorial was recorded in June/July of 2020. Much has changed with the tools discussed in this video, and it is therefore very out of date. For more up-to-date information, please visit the following tutorials:

With WordPress moving more and more into the world of blocks, knowing how to build your own blocks has become valuable knowledge. However, if you are a plugin or theme developer, you might not be sure where to start. This workshop will serve as a guide to building your first block.

Don’t forget to check out the create a block tutorial in the WordPress Developer handbook for more information on how to create a block.

Learning outcomes

  1. How to set up a block enabled plugin/enabled your existing plugin to be block enabled
  2. How to create a simple block, and the basic elements of a block
  3. How to create a custom block, using existing WordPress components
  4. How to create your own custom block, by creating your own custom component

Comprehension questions

  1. How do you register a new Gutenberg block in JavaScript?
  2. What property of a block is used to store information about the state of a block, and why is it useful?
  3. Briefly describe what a custom Component is, and how you would create one?


Hi there, and welcome to my Beginner’s Guide to block development. So the purpose of this workshop is going to be to take you through some of the core pieces of information that you might need to know if you want to build custom blocks for WordPress. For the purpose of this workshop, I’m going to be skipping over quite a bit of the block development handbook. With the Block Editor Handbook, shall I say, I highly recommend that you read through the entire handbook if you can. But I’m going to be highlighting certain sections as we go through. If you want to work along in this workshop, you’re going to need some preparation, you’re going to need a local development environment of some kind, either flywheel or vvv, or something along those lines. I run on Linux and Ubuntu. So I have a fairly standard lamp install setup, you’re also going to need a default WordPress install, which I do have running on WordPress dot test, then you’re going to need oops, I closed the window there, then you’re going to need to make sure you have Node.js installed. So Node.js is a JavaScript runtime that you install on your machine. And it includes something called NPM, which is the node package manager, which allows you to install all kinds of cool JavaScript packages. The recommended version is probably best for most people. If you want the most latest, the latest version, you can always install whatever the latest version is. And then finally, what you’re going to need is some kind of terminal access. If you are on Mac, or Linux like I am, you’ll have a built in Terminal. If you’re on Windows, I recommend checking out something like commander. Or you can try the windows subsystem for Linux, which I haven’t used in a while because I don’t have a Windows machine anymore. Okay, so once you’ve got all these things installed, we need to start building. So what I’ve done for the purpose of this workshop is I have a very basic standard plug in this is a standard PHP plugin for WordPress, it doesn’t matter what it does, it registers a table creates a table. It has a form shortcode, which outputs a form. It processes the form data. This is actually some code that I took from a plugin development workshop that I did at WordCamp. A while back. And the reason I’m doing this is because I want to show you how you can add a block to an existing plugin. It’s fairly easy to build a new block plugin from scratch because there’s some cool templating out there that we’re going to use as part of this workshop. But I want to sort of build this into an existing plugin, because many of you might already have plugins that you want to add blocks to. Or you’ve built plugins, and you kind of know how plugins work already. This is not going to be a course on or at least a workshop on how to build a plugin. This kind of assumes that you know how plugin works, and how to set up the plugin headers and that kind of thing. If you don’t know how all that works, there is information. In the tutorial section of the Block Editor Handbook, it talks about your development environment talks about getting started with setting up a plug in and loading JavaScript and all those kind of things, we’re going to kind of skip over that we’re going to assume that you know how a plugin works. Okay, so let’s get started. So the first thing I want to do is I want to set up the JavaScript ball tools. This open that up in a new window right there. So basically, in the tutorial section, there’s a section called getting getting started with JavaScript. And right down here, there’s a section called the JavaScript bold step. So let’s talk briefly about what this does. If you work through the various block tutorials that are further down here, you will see that they have these little switches. Let me find one I’m not going to find right now. Am I? Let’s try. Let’s go up a little bit. Let’s look at the attributes one. Not going to find right now my mate, let’s try two blocks. There we go. So they have this ESNext and s5 little toggle, and you can switch between the two. So as five is kind of the more sort of traditional way of writing JavaScript code, you could, you could maybe call this almost vanilla JavaScript, if you will.

And this I find to be often can be a lot more complex and a lot more complicated if you’re not used to sort of how JavaScript works. Yes, Next, you’ll see if you look at the source code is a lot simpler, a lot less code. It uses something called JSX, which is something in React that we’re going to dive into a little bit. So I tend to stick with using years next code. So to be able to run this ESNext code, we need to enable the bold step. Now what the bold step does is it takes your ES5 x code and transpose it down into es five code that your browsers and all of your browsers can under So in order to set this up, we make sure we have node installed. So here’s the setup, it talks about getting node installed. And then we need to run this npm install saved a part. So you’ll see I’ve got it over here, make sure NPM is installed, set up the project and run the installation setup. So in my project, we’re going to copy out this line of code. Here is my project file, I’m going to switch to my terminal. I’m going to find the right one got to running. So this is my WordPress web content. Let’s just get this out. WordPress WP content plugins block development workshops, I’m just going to write sorry, paste NPM in it. And it’s going to ask me a few questions about the workshop, or at least about the code that I’m working with. So package name, I’m happy to leave version, I’m happy to leave at any details commands. That is the Git repository. I don’t need any keywords right now. Licensed, I want to go GPL. And it actually says to me, hey, the license should be a valid reference, blah, blah, blah. So we’re going to copy out this GPL 3.0. Later, we’re going to change it to 2.0 or later, just because I want to stick to the WordPress standards. So that’s that it’s gonna say we’re about to write this file, yes, I want to write that file. I can obviously check all the information, that’s all great. And I’m going to say yes, go for it. So that’s created this package dot JSON file. Now what that’s done is it’s had a look at what I’m currently using. So it notices that I’m using grunt, which comes from, you don’t know why grunt file is there, it comes from the WPC Li, plugin, skaffold. But way too much about that we’re going to change all that in a second. But it has my author name, and the block name and various other things that I need dependencies and that kind of thing. So this kind of sets up the package files so that I can start installing things. The next thing I need to do is I need to install some things, I need to install the WordPress scripts package. So I’m just going to copy this command off, it’s going to run a whole bunch of JavaScript stuff. I’m going to paste that in there. And you’ll see it’ll now say, right, it’s going to start installing some things. And basically creating this node modules directory. Now, if you’re used to using composer in PHP, node modules is kind of similar to the way composer works with a vendor with a vendor folder. It’s basically installing a bunch of JavaScript packages that will allow me to do a whole bunch of things. One of the things that it does is it installs the bolt commands, so that I can build my files. And we’ll talk about how the build process works in a second, takes the source code and converts it into the transpiled code and all that kind of thing. So this is basically just fetching all this data, it takes a few seconds, so we’re just gonna let it run. And while we’re doing that, we’re gonna have a look over here, that is basically step one. So let’s go back to the command line. And I think maybe what I’ll do is I’ll stop this for now. And we’ll come back once this is all done. Okay, so the install process is completed, it’s installed the WordPress scripts package. If we pop back into the package, JSON, you’ll see it’s added this dev dependency. So by doing the installation process, similar to the way composer works, it adds the dependency for me. And that’s kind of all that is done except for adding all of these node modules, which we will use for the build process. Okay, so now we’re set up and really start building some blocks, what I like to do is I like to use existing sample code to kind of get an idea of what’s going on.

So what I’m going to do is I’m going to use this command to create the starter block. And you’ll see in the block tutorial on the handbook, that it actually references, how to get started with creating a block. So this is a nice way to see what the code looks like if you’ve never seen this code before. And it’ll give you an idea of what we’re kind of working towards. So back in my command line, I’m going to go up one directory, because I want to be in the plugins directory, I’m going to run the Create stratup block, come on, it’s then going to create a folder called startup block in my plugins directory, it’s going to fetch all the JavaScript stuff that I need, it’s going to create various files that I might need, install some packages, which does take a while. And when this is done, I’m going to have in my plugins directory in my project, I’m going to have a starter block plugin. With some code that I can start looking at, you’ll see it’s already created the starter block dot PHP file, which we can look at. So let’s close down our workshop plugin. So in the starter block dot PHP, you’ll see here it’s got a basic plugin. So if you’ve never created a plugin before, this is a great way to get started with building your first plugin. It’s got the header file, it’s got the function which initializes everything and it’s got the action which creates, which hooks into the unit action and then calls this function. Okay, let’s have a look and see how far this is going. This is all happening. So let’s take a look. So while that’s all going on today, the node modules are coming through. Okay, cool. That’s awesome. You’ll see it’s also created this source directory. And if we ever look in the source directory, you’ll see that there is an index.js file. And this is where all the JavaScript, block registration and things happen. Okay, so that’s going to be an important file for us. There’s also other things, isn’t it a j. s is a saved j s, I’m not going to dive too much into these, I’m just going to work in the index js file today. It also creates the ball directory for us for the first time, and then it creates these files over here, index asset, CSS, js, and stuff. Okay, so let’s dive into those. Let’s see if there’s going Yes, this is finished. Excellent. So it’s created the starter block, it’s bootstrapped all the code for us. And it’s saying you can run these commands, you can run NPM start, you can run NPM build, which we’ll use quite a bit. And you can start doing all kinds of fun things. So the way a block works is in PHP, you register the block code, so you register the JavaScript file, and any style sheets that you might need. And it’s using this register block type PHP method. It has a name for the block. And then it has an array of scripts. So the editor script is the JavaScript file that manages the editor, the editor style is the CSS file that just makes any kind of design changes in the editor. And the style is any front end styling that you want to register. For any kind of different things on the front end, normally, you wouldn’t have two different styles, because you typically want your blog to look the same in the editor as on the front end, but there might be some things you want to do over there. Then what it does is it says right, look for this asset path. So the asset part gets generates generated in the bold step. And it basically is just a bunch of dependencies. So we need blocks, and we need elements, we need internationalization, then we need polyfil. And it gives you a version number. And this gets regenerated every time you run the build step. So if we go back here, you’ll see it gives us a nice little error, which says you may need to run these for this to work, which is a nice cool way of throwing that you haven’t run that. It then uses that asset file. And it uses the bold index.js. And it registers that script. So this is very similar. If you’ve seen registering scripts for themes or plugins, you give it a handle, you give it a path. And then we give it these dependencies and the version, this is exactly the same as you may have done in the plugin or anything the same for the CSS files, register the style, give it a handle path, any dependencies at a time. And this is basically a version number. And then the same for the style CSS, okay, so this is this is kind of, I would say, the most amount of code, you would need to register a block, you can go less than this.

And that’s what we’re going to do in this workshop, we’re not going to dive into a lot of this stuff. But this is kind of as much as you might need. in PHP for your block to work, everything then else happens in your JavaScript. So you register your block type, and you give it things like a title and the description and various other things. And you give it an ID method function, and it’s a function. And we’ll get into that in a second. But that’s kind of where all the block JavaScript denas happens. So that’s what we’re going to use in our plugin file as well. So what I’m going to do now is I’m going to go back to the start over here, and I want to just do a very simple registering an asset, I’m going to use the code, they open in a new tab. So anyway, I’m going to use the code they provide in the handbook, which is very much simplified version of what we have in the Stata block. Okay, so I’m going to close that down. I’m going to close that down, close that down. And I’m just going to take this code here, because I find this to be nice and simple. Little bit easier to work with the first time but I’m going to use that starter block if I ever need to get back to it. So in our block development workshop, I am now going to register this code right at the bottom here of my main plugin file. Okay, I like to have my action hooks at the top before my functions, that’s just something that I preferred makes it more readable. And then I’m going to just call this I think I was using the btw prefix. Yes I was. I’m going to go btw workshop block Connect. I’m going to call my function, my callback function the same thing. Here’s my asset file. So find the ball asset adnexa. PHP, we’ve seen that in the starter block. I’m not going to do the check if the file exists. Right now I’m just keeping it super simple. And then I’m going to reach to the script so I want to call the script btw workshop lock script. This is the handle of all the good registered on the front end. The Bold index does. The j stays the same the dependencies I get from the asset that all stays the same. Then I need to register my block talk now when you’re registering a block type you need to make sure that it has a unique prefix similar to when you do plugin functions. You You’ll see in the JavaScript section they talk about scoping your code. So I recommend reading about that and figuring out how that works. So in this instance, I’m just going to go here, and I’m going to say, btw workshop. And then I’m going to do this. And then I’m going to go here, and I’m going to say, No, that’s not what I want. Let’s go btw workshop block, I could just call a workshop block, if I wanted to even where it doesn’t really matter, let’s actually do that. We’re just calling it a workshop block, you’ll notice that I’m using hyphens and underscores, if you use underscores, you will get an error. So your block type naming must be using hyphens. And then my editor script is going to be the workshop block script that I have here. So I’m just going to pop that in there. Okay. So now I’ve set up, literally, this is the minimal amount of code you need. To create a new block, I need to not create my index js. Now, I’m not going to create it in the bold folder, because my bold step will create the bold folder. For me, if you have a look at my starter block, I have a source and I have a board. So I need to create the source folder and put on my source called source code in that source folder, so let’s create the source folder. I already exists, I think I had it earlier when I was testing this out. So I’ve got the folder, and then I need to put in, that’s my phone going off, I need to put in a JavaScript file, we’re going to call it index. And that’s going to be not going to add it to get right now, this is going to be where my block code is going to reside. Now going back to the writing your first block tutorial, they’ve got a very simple block here, which is nice for us, for example. So we’re going to use that I’m going to copy this code out over here. And I’m just going to pop it in over there. And let’s have a look at what this is doing. So what this is doing is it’s saying import the register block type function, which you’re going to need, it’s setting up a block style, which has got some styling in it, it’s then registering the block type. And you’ll see this was similar to the code we copied. So we need to change that to our code over here. There we go.

Okay, I want to give it my own titles, I’m just going to say, workshop block, which is great, I can stay as it is, I’m going to not gonna worry about changing that this is gonna stay the same. But now I’ve registered my blog type in PHP. So it knows to expect a block with that name. Using the script tied to this handle. That script isn’t this one, it’ll be the one that gets built in the bold step. But this is the source that creates that bold file, and then contains this code, which we will dive into in a second. That’s all well and good. But now I need to run the book. So if we go back here, you’ll see that I’ve registered the block assets, and I’ve reached the block in JavaScript. And before I can run the boldly install, update the package JSON, what am I talking about there? Well, if you have a look at the package, JSON for our workshop block, you’ll see that under the scripts area, I don’t have I only have this test script that will run. But if you go back to our starter block, which is over here, somewhere, you’ll see that here, I have these scripts, and I have the bold script step and I have formatting and those kinds of things. So this I need to make sure it gets updated. I also need to update and say, my main file is this ball dot index, I’m going to take this code may not build index, I’m going to update my my plugins package JSON with that get author name could stay the same. David have any dependencies is already WordPress scripts. So that’s great. And then I want to copy these scripts out over here. And property and over there. Okay, now I’ve got the bold step set up. That’s excellent. So now what I do is I just run npm install to make sure everything is installed as necessary. So I’m going to go into my blocked development workshop. And I’m going to make sure everything that I might need is installed, it should all be installed. But I might need to add some new things because now I’ve told that I need build scripts, and I need steps and I need all kinds of other fun things. So it’s going to run through and add some more packages. It’s telling me about vulnerabilities, I’m not going to worry about fixing those right now.

Once I’ve done that, then I can run NPM run bold. Now watch what’ll happen. If you have a look. I’m going to close the starter block package JSON. If you have a look in my build folder. I’m going to take this file out and just delete that. Okay, there’s my source index, nothing currently in my build directory, I’m then going to run the build step. And it will then take my index dot j s and any kind of any sort of pop up there and any kind of CSS or whatever that I’m using, and transpile it into this very like simple one line simple and if this is simple, but anyway, one line no spaces, JavaScript that any browser can handle, it also creates the asset file. So it creates this every time. Okay, now, what you can do if you don’t want to run run build every time is you can run something called NPM, run start. And what this does is this runs in the background and it watches any changes to your files, and it just automatically builds them. So what I’m going to do quickly here is I’m just going to pop this over to the side, I’m going to pop this over to the side, and I want you to watch this window, I’m going to go into my index file, no, that’s not the one I want. I want the source one, there we go. And I’m going to call it WordPress block two. And as soon as I save this, you’ll see that my assets shouldn’t be running here don’t know why they aren’t running. There we go, bird ran there, and it updated it, and it created the new index. So that’s when I call this something else. And I save it, and then it runs it again. So this will just continually keep building my bold files, which are the ones that I’m using in my plugin registration. Okay, so I found this process of understanding where the source code sits and where the build code sits and getting the package JSON stuff set up to be, I found at least more difficult than most. Once I understood it, then it became a lot easier. So that’s why I made this part of the step you’ll now see if we fire up our WordPress install. And we log in here, and we go into a post. And we say, again, this is just freaking out because it doesn’t have the block that I need. And we say we want to add the workshop block. There it is boom, and there’s our block, ready to rock and roll. Okay, so that’s the sort of the basics that you need to get your blocks set up, you need to set it up in PHP, you need to set up your bold step, set up your block in the index file, run the bold, and then you should be good to go.

Okay, so our next step is going to be to add some components to our plugin to our block at least, before we do that, I just want to run through what everything is doing. So we went through what’s happening on the PHP side, we understand it’s loading the asset file, registering the block script, and then registering the block type using the block script. On the JavaScript side. This line over here, it’s basically saying import this function from the WordPress blocks package. So this is a special package that makes the register block type function available. This block style constant is basically a JavaScript variable that contains the styling for this block. Then we call the register block type with the same name as we used in PHP. It has a title that we can give it it has an icon that we can set it has a category, an example. And then it has an edit and a save method. So obviously, the function, whichever, I tend to confuse functions and methods when it comes to classes and functions, I’m going to use the two terms interchangeably. The Edit function is what runs when the block displays in the editor. So when it’s an editor, it’s going to show the div with the style that’s been set up and Hello, world step one from the editor. The save function is what’s called when the block is saved or when the paid post or page is saved. And then it’s going to show from the front end. So you can see the difference there. If we look at our post here, it says from the editor. And if we save it, it still says from the editor in the block, but if we preview it on the front end, it’ll say from the front end. So the Save part is what is physically saved into the database.

If you have a look at the code editor version, you’ll see here it says from the front end. So this is what’s stored this code this comments with the workshop block stuff, and then the contents of the block with the code that’s final, this is what’s physically stored in the database. And then that’s what’s used to render on the front end. There are some people that don’t like this way of storing this data, but it has its pros and cons. So we need to understand those two differences. So this will be where we will do most of our work with creating the block as it displays in the editor. And then here this will probably be a simplified version of the same thing using the content that saved and then just displaying it on the front end. Okay, so now the next thing we want to do is I want to add a component so let’s talk about what components are first, components are sort of special pieces of code that you can use in a React would be in the in the Block Editor that allow you to do certain things without having to rewrite the code. Now obviously the editor has a whole bunch of components. So it has an image component. It has a rich text component, which is what a paragraph looks like. And these are all in different editor will have the rich text. You probably find there’ll be a media company ponents somewhere, which will have the image upload options, maybe media, utils, whatever. So it’s a good thing to get into all of this and kind of see how all these things work, we’re going to start with using the rich text component. This is the most common component, you might see when you’re editing a page or a post in WordPress, it basically is the paragraph tag, if you will. And we’re going to use the attributes. So first, let’s grab the code. And let’s see what it looks like. So I’m not going to take the register block type stuff out, I’m just going to take the edit and the Save functions, and I’m going to replace our edit and save functions. So here we go. Okay, so the first thing is you have this new is this thing called props, which we’ll talk about in a second. There’s an unchanged content function. And here’s the rich text component. So this rich text component, when it’s transpiled, turns it into some code, which generates the rich text block. And then this is the save, which then does all kinds of other fun things. So let’s save this, you’ll see that my, my bold step is already automatically run. And let’s see what happens when we refresh our post. So you’ll see that it’s failed. Okay, that’s cool, because that means something’s going wrong. So let’s have a look and see why. Here we go. uncaught in promise reference editor, richtig is not defined. If you don’t know why this is, this is my Firefox developer tools very handy to open up while you’re developing. And you can see what’s going on. The reason this is happening is because I haven’t imported rich text like I imported register block type, I need to import the rich text component. So let’s go up here. And here it is there. Let’s import this. pop it in the bold step will run automatically. Yes, that’s done. Let’s refresh that page. Okay, another block validation failed. Now what this means and you might see this when you’re developing is that I have changed the code of the block, which means now in the same function runs, it ran something completely different and it doesn’t have this information is stored in the database. So it’s saying, hey, hang on a second, I tried to validate the Save content, what you’re telling me to render now is totally different. I don’t know what to do, and it gives you the zero.

While I’m developing, I can ignore this because I know that it’s happening for this reason, but it’s good to understand what it’s doing. So now if we add an image, just clear out the console. Now if we add a new workshop block, here we go, it’s registering the rich text editor, I can tell because it’s got all of these cool rich text fields that I can change. And I can start putting some content in here and go, Hello, this is text. And I can do things like bolding and various other things. And this is all part of the rich text editor. So this is how you can use an existing component to build a custom block. So let’s save this. And let’s preview it. And Hello, this is some text. There we go. We’re all happy. Okay, so this is working great. This is doing what we need to do. Now. The other thing to understand is attributes. Now, in this instance, I don’t necessarily need to use the attribute because you’ll notice that I’m typing in the text there. And it’s saving the data. And now the reason it’s doing that is because over here, I’m saying set attributes on the content, and it’s basically just automatically pumping that in, but it’s a good idea to define your attributes as well.

So let’s take this over here. And we’ll just pop it in the category. So now I’m actually defining my attributes. And I’m saying this is the content attribute. And the selector is the paragraph tag of the rich text. And it will then store that data. Now where this becomes handy is if you wanted to store some additional data on the block. So let’s say for example, I wanted to store some kind of ID on the block. So I’m going to create a new attribute. And I’m going to call it ID. And just for the purposes of this, I’m going to make it a string. And I’m going to leave out source and selector because then it’ll just store it on the block. And I’ll show you how that works in a second. And then here we’re I’m saying set attributes. Let’s let’s talk about this for a second. So what this is doing is, there’s this concept in React called props, we basically you can pass all the properties into a method. So inside of props, I’ve got the attributes from the block, and inside attributes, I’ve got the content. I’ve also got a set attributes method, which is passed from I think register block type, and a class name method, which is passed through and if you have a look at the class name, it will be the name of the block transport. So what I can I do is I can update the set attributes, mythical here, function volume zero, and say update the ID, which is the new attribute that I just added. And call it something like, let’s say my luck. Now, that’s not going to be obvious what it’s doing right now. Actually, let’s do a tie, I’ll leave it at my block for now. So if you do that, and we’ve made sure that run is running, the build is running, that’s great. If we do that, and we hit the post, nothing’s really going to change. I’ve added the ID, nothing’s really changed, I’m going to add some more text, which will trigger the on change. And you’ll see that if we have a look at the code editor here, you’ll see it’s storing, there’s the ID, my block, okay? Now, where this becomes useful, is, let’s say on the front end, I wanted to render something different, I want to based on the my blog content, I’m going to go and grab some data somewhere else and whatever and then render that as part of this, I can then do something like this, or what I’m going to do now is I’m just going to go and I’m going to go cats concatenate the ID attributes on the front end only. Okay, so that’s bolts. And if I now exit the code editor, and save this, I should save it. Actually, I probably need to refresh because I don’t think the codes refreshed. Okay, that’s fine. I expected that to happen. Let’s just remove this block. And let’s add a new one. As my workshop block, some text, okay, let’s have a look at the code. Okay, there’s the ID. So that’s good. Let’s save that.

Right, that’ll save happily no errors. And now we’re going to preview it on the front end. There you see it’s added the my block content, okay. So attributes are a way that you can store data on a specific block, you can either use them in the way that I have on the front end, you can also use that data, if you’re doing things with your block, if your block is going to select information from elsewhere, I’ll show you at the end of this workshop, how I’m doing that in an example. But it’s important to understand that attributes are basically just types of data that you can store on your block, and you can use them elsewhere. Right, the next thing we want to look at is we want to look at how to add our own custom components, or how to create our own custom components, or a combination of custom and existing components. So the first thing we’re going to do is we’re going to create a very simple new component for a label for our block. So the way this works is I can create my own custom components using this JSX functionality, which I showed you earlier. And I can pretty much do whatever I want using sort of HTML structure, which then gets transpiled through to JavaScript. So the first thing I’m going to do is I’m just going to create a folder called components because I like to stick my folders, my components in a separate components folder. And I’m going to create a cancel that I’m going to create a new JavaScript file. And I’m going to call it work sharp message, I think it’s qualitative enough. workshop header. And I’ll show you what I’m doing there in a second. No, don’t add this again. Okay. So in workshop here, I have nothing currently. Okay.

What I’m going to do is I’m going to show you what a simple hit it looks like, in the actual source code that I’m running yet. I’ll talk about the source code at the end in a second. But here we go. Here’s the message header quoted message, it doesn’t matter. So this is what the code looks like. Now, this is not something that gets spoken about too much in the handbook. This is something that gets talked about more in the sort of React world. At the end of this workshop, I’ll share some resources where you can learn about how components and things work. But let’s just copy out this. Put this in our workshop here, and I’ll talk about what it does. So I say so, the first thing I need to do is import the Component Object from WordPress element that allows me to create a custom component. Let’s just rename this to workshop message header for now. Okay, then I need to create a class called whatever the name of my component is, and it extends component, then I have a render method inside that class. Don’t worry about what’s inside there right now. And then at the end here, I have this export default WordPress message workshop message header. In the render method, I just simply return whatever my HTML is going to be. In this case, I’m just using standard HTML. I could use another component in here, I could do some JavaScript things. I could do whatever I want to do, but for now, it’s just a basic bit of HTML, h3 tag with some content. Okay, so that’s my component. I’ve got a great now what do I do with it? In my index file, I can now say, import work, workshop. And because I’m using PHP storm, I can it’ll autocomplete it for me and I can just click on it. And there we go. So import workshop message header from and the path to slash components workshop message. So it’s one file up from index, components workshop message header, there we go. Now what I’m gonna do is I’m going to take out all this attribute stuff just for now. And I’m going to take out all of this just for now. And all I’m going to do here is I’m going to say return workshop, Mr. chaddha. And in the save, I want to do the same thing. workshop message header. This is very simple. I don’t need the props anymore. Because I’m not doing anything with them. Don’t need the props there anymore. Here we go. So this is now a very simple version now of my Because I’ve just got the message header, I don’t need the block style stuff anymore, I could have taken that out a while ago, I don’t need the rich text anymore. We’ll put it back in a second. And there we go. Right. So there’s my that that and that. Now what’s cool about the bold step is it’ll auto detect that I’ve got this file in the components, and it will automatically run it and compile that into my index j s. So if I just refresh my block now it’s going to give me a save validation error, which I expect because I’ve changed the code. So I’m going to remove this block. And then I’m going to add the workshop block and look what changes now suddenly, I’m seeing the Welcome to our workshop header. You’ll see it is an h3 tag. And that’s now what our what our block, what our block does and how it looks like. So if we go preview in a new tab, there we go. Welcome to our workshop. So I’ve just created a very simple custom component, I can put anything in here, I can put more content, I can run API calls and get post data, I can create a post list, I can do all kinds of interesting things using this custom component. But this is how you create your own custom components. you import them into your block, use this kind of HTML style JSX code, you’ll notice that I’m doing two types of return, it doesn’t really matter, which is which this one is used more for if you have deeper content, which will go into the next step. I can also do it this way, that’s also fine. But that’s how you create a custom component. So you can build all kinds of fun things using this component JSX style format. Right now that I can create my own custom component, the last thing I want to do in this workshop is combine these components. So I want to create a message component, which combines the header and the rich text area. Now for the sake of simplification, I’m going to cheat outrageously and jump straight to versions. Step Six of this workshop. If you’re working through this workshop, I have created branches for each of the different steps. So you can see all the code as you’re going through. But in Step six, I’ve got finally the workshop message and the workshop message header. So the workshop message header we’ve already created, which is great. Let’s have a look at the workshop message component. So this is what it looks like. So I’m going to copy this out. And I’m going to show you what I’m doing here.

So here we’ll create a new component. JavaScript file, we’re going to call it work shop. message. I’m not going to add it and we’re going to dump the code. Okay, so what am I doing here, I am importing component as we did previously, I’m also importing the rich text component, because I want to use that in my in my message, and I’m importing the message header. Okay, so that code is going to become available as well, you’ll see that I’ve moved the attributes, and set attributes and class name destructuring. To hear many differences where I was using an index file, I was passing in props here. Here, I’m using this props. And I’ll come back to how this all works in a second, I’ve moved the unchanged content function to this component as well. Then I’ve got my return. Now my return has a div with the class name. It has the workshop message header component and my rich text component as it was in the earlier example. And then I’m doing export default workshop message. The reason I got this dove is because he can’t have two components next to each other inside of a return function of a component without it being wrapped in something else. So you need to wrap it inside of a div. Okay, so that’s the message, the header stays the same, but I need to now change the index. So let me show you what that looks like. The final version of that. I’m just going to copy that whole thing art. I’m going to show you what it looks like. Okay, I don’t need it anymore. Example can stay that can stay cool, right? So here, here’s the Edit method. The props is back. Okay, so here I’m doing this is called D structuring. So I’m saying take the props that are being passed and pull out the attributes, the set attributes and the class name. Then I’m passing it to the workshop message component with the same names I’m saying attributes is going to be equal to this attributes. Set attribute is that class name as that, this then passes these things into the props of the workshop message component, which is why this then happens because I want to D structure or extract these copies elements out and use them in this component. Okay? Then on the Save, what I’m doing is, I don’t want to do all this kind of stuff that I’m doing in the message, and I want to be doing the updating and unchanged and updating the content. On the save, all I want is the final output. So the output div, I just want the header and then I just want the content of the rich text editor using the content that’s been updated in the workshop message. Okay, so there’s the header, there’s my index on my save, everything else should be working fine. The other thing I need to do, I’m not importing my workshop message header anymore. I’m importing my workshop message. So let’s clean this out. Okay, okay. I am also importing the rich text component again. So let’s grab that. So that doesn’t fail. There we go. That should be bit. So now I will step will have run. And in our project, we’re going to get an error because we’ve changed everything. That’s fine. We expect the error to happen. That’s fine. Okay, workshop message header is not defined I interesting index somewhere I’m calling. I’m calling workshop message data. So I do need that as well. Okay, so let’s go import workshop messages. If you’re wondering how am I inviting my editor does all of this because I’m using PHP storm, which has built in support for JSX. If yours doesn’t, either, if you’re using VS code or one of those, there are ways that you can add this or just get used to typing out the path to the final file, I do recommend getting a good editor and having it set up so that it will do all this for you. There we go. So that’s done, the build will have run automatically, let’s do a refresh. Block validation failed, we expected that that’s fine. Let’s remove the block. Let’s delete the error. And now let’s add the workshop block. And boom, there we go. It has our header. It has our rich text. So you can say some text here. When we save this, and we preview it, it’ll then show Welcome to our workshop, some text here. So what we’ve done is we’ve taken two components. One that we created ourselves, one that already existed in the rich text, we’ve combined the two of them into this workshop message component. And we’re then calling the workshop message component. In our edit, we could create another component called maybe this could be edit workshop message. And this could just be workshop message, and then we could put it in. Or we could even go as far as what the starter block does, which I think is quite cool that they’ve done it in the startup block. Let me show you here for a second. In the startup block, they’re actually under the Edit method, they’re actually saying import the Edit file.

Let’s see over here, import edit from edit, import, save from save. So if I go into the Edit, which is this guy over here, see they’ve got this default, this is kind of similar this component export default function. If you remember from our message header, we had this export default, same kind of thing. And then they’re doing everything as a separate component yet. So that’s kind of a cool way to do it. You could also do it as we’ve done it just in the edit and in the safe. Okay, that sounds like and it does feel like a lot. And the thing with thing with switching from PHP and JavaScript and getting to know these things, is to kind of play with it. I spent a lot of time figuring all of this out understanding all of this. In a little while, I’m going to show you some additional resources that I recommend you have a look at. And hopefully this will give you a good idea of how these things work together. The code is all there in the block development workshop. Look through all the different branches. See how it all works. Right. So for the last step of this workshop, I just want to run through some kind of live examples that I’ve worked on. The main one being for the seriously simple podcasting plugin. So if you get a hold of the plugin from, or you can grab it on GitHub, find my find my sources, we’ll find the plugin source turkeys on mine, find the plugin source directory, you’ll see there’s an index file, you’ll see there’s a bunch of components that are created. There’s an edit player and various other things. So go through this, take a look at the code. And you’ll see how I’ve created different components I’ve created. for editing different components. I’ve created separate components to do the actual editing. And this just kind of gives you an idea of what is possible. with custom blocks. There’s a nice big custom talk that I wrote with some custom HTML. That is that is available in the real world. So feel free to go through and take a look. And let me know if you have any questions. The other thing I wanted to share with you is some resources. So when I first started building blocks, I had no idea how React worked. I had no idea how sort of Gutenberg worked underneath the hood. So the first thing I did was I did this React for beginners course, by Where’s Bowser highly recommended. It’s currently 50% off. And depending on where you are in the world, you might get an extra percentage. So go and check this out. I know right now, South Africa, has a very good price wherever you are in the world might be different. But it’s well worth the investment getting into React. The other course I would recommend is the Gutenberg block development course by Zack Gordon. That’s also currently, depending on where you are in the world, you get a percentage off. And this is a very good course to give you the basics of how the core Gutenberg plugin works. It gives you the element library, the blocks area, all of these sort of WordPress specific libraries that Gutenberg exposes, which is a great resource for understanding all of those things. So I highly recommend first starting if you have an idea about React first Lockwood React for beginners, if you have no idea about blocks, then start with the Gutenberg block development course. And then finally, one of the chaps over delicious brains wrote an amazing article on building blocks, which is very similar to this workshop. So I recommend reading through this, he talks about attributes. He talks about a edit function, he’s got a custom, so function. So it’s kind of very similar to this workshop just in an article format. And reading this article, while I was learning to build blocks kind of just helped cement some of the ideas that I wasn’t sure of when it came specifically to Gutenberg block development. I hope you’ve enjoyed this. As I mentioned at the beginning of this, I am skipping over a lot and kind of focusing on what I see as the most important concepts that you need to know. building some custom data. I recommend, as I always do reading through the block development handbook. It’ll give you an A it was noticed when we did this workshop, we work purely from the examples they’ll give you some great examples to work with. And then adding these resources that I mentioned. Now we’ll just kind of build on that. If you have any questions about this, you’re welcome to drop them on this workshop. Or you can get hold of me on Twitter. i’m john underscore bassinger. I hope you enjoy building blocks. And I hope this helps you in some way. get to a point where you feel comfortable to do that. Okay, thanks very much.

Workshop Details


Jonathan Bossenger

WordPress Developer Educator at Automattic, full-time sponsored member of the training team creating educational content for developers on Learn WordPress. Husband and father of two energetic boys.