 OK, so just to start, I'd like to gauge how much experience you guys have had with things like, has anybody installed Gutenberg? OK, has anyone tried to make their own Gutenberg blocks? OK, how many people know a little bit of React? OK, how about ES6 or ESNACS, as some people say, JSX? OK, all right, that's good. So a little bit about me, there is a great introduction. I don't really need to add anything other than we've been building Gutenberg blocks already for, I guess, most of this year, and we started block party this year. And so we've been really diving into Gutenberg and trying to figure out what are the use cases and how to build some really cool things with it. So for those of you who don't know, what is Gutenberg? It is the new WordPress editor as of sometime, hopefully soon. And Gutenberg is what you see is what you get experience. Much more so, TinyMCE was kind of billed as that, but this is much more of what you see is what you get experience. And the content paradigm is blocks. Everything is a block. You add blocks to the page, and that's how you build out your content. And Gutenberg, by default, comes with simple blocks, but it's pretty easy to start building your own custom blocks. All right, so we're going to have a little demo. This is the gift my CEO gave me. So when you install Gutenberg, this is just the default demo page. And this is what it looks like. This is how you can add content. And then this is reflected. If you have a Gutenberg-ready theme, this will be reflected really closely on the front end, or it should be exactly. And if you want to add more blocks, you just come here and you say, oh, I want to add another paragraph. And then I come and I can type in some content here. OK. All right. And then you just type in some content here, and then it gets added to your page. So this is great. It looks good. Is it that much better than what we have now? I think it's a little bit better than TinyMCE and some of the other page builders. But what excites me is the kind of custom things you can do. So let me give you a little demo of some things we can do here. We'll add a pie chart. Now, how many of you have been to New Mexico? OK. Does anybody remember the New Mexican question? Red or green? You'll hear this at every restaurant you go to. Do you want red chili or green chili? So we'll just make a little pie chart. We'll say 35 people want red. OK, we'll do green. Does anyone know the other option? Christmas. Ooh, there is someone that's been to New Mexico out there. OK, I want to say 45 people want that. We'll make Christmas orange. All right, so we have a little block here. This is our little preview of what we're building. But is this what we want? Let's see. Let's play around with it a little bit. Maybe I want to change the labels, right? And it updates for us in real time. I don't want anything. Maybe I want it to be 3D, or rotate the chart, or have a donut hole, or I want to explode something. This is where Gutenberg becomes really powerful, where instead of just typing in a paragraph, I can build my UI components in the browser and see it update in real time. This is where Gutenberg becomes markedly better than the current options out there. OK, so the Christmas tree didn't light on fire. Thank goodness. OK, why should we bother making custom blocks? Besides these really cool things that we can do, is there another compelling reason why we should be making custom blocks? And there is. And this is, do you have branding guidelines that you follow? Does your client have branding guidelines? If so, Gutenberg gives way too much freedom. So here's an example of the default paragraph block. This is what you can do just with the options available to you in Gutenberg. Do you want your client sites or your company sites to look like this? No. This is too much freedom, way too much freedom. And what we want, when we build a successful site, what do we want? We want content creators focusing on creating content, not on making all these styling decisions, right? We want to make it easy. So this is, I think, the most compelling reason why most of you will want to say, hey, I want to start making custom blocks. I want to make blocks that take away some of this freedom, but also allows my clients or my company to build websites where the content creators, they just go in there and they make the content and they don't have to worry about this. All right, so a little bit of background. Gutenberg is written in React.js, which is a front-end library from Facebook. It's very, very popular, and there's a lot of tutorials out there on how to learn it. Most examples of React.js will use ES6, or sometimes called ESNext. A lot of times, WordPress documentation calls it ESNext and JSX syntax, which makes writing React a lot easier. And then the concept of how we interact with these blocks is through attributes. We interact, we change attributes, and that's what changes our Gutenberg blocks. And then the blocks are saved in the post content as HTML. And if the data is tied to an element, the attribute will just be tied into the element. Otherwise, it gets saved as JSON data in HTML comments. So one exciting thing for me about Gutenberg is we currently do a lot of sites using PostMeta, which if you know much about performance, how the database works, PostMeta is not a great way to build sites. But now we can do things with Gutenberg, where we can forget about PostMeta in a lot of ways and just put all that content right in the WordPress content. When you register a block, all you need is an edit method and a save method. The save method is responsible for turning the attributes into HTML that will be shown on the posts and pages. And like I said before, the attributes can be saved in HTML comments in the JSON format, much like this. And then on the editor side, Gutenberg reads the attributes for each block and then passes those in the editor method so that you can interact with them and change them. And the editor method can include a preview, like what we saw, a preview as you build it of what it will look like in the save method. And another thing that's exciting about Gutenberg is that you can build templates. So this is an example just from the WordPress handbook. It's a custom post type for a book. And you can see there's a template argument in the array. And then that's an array of blocks. And you can pass in attributes by default to those blocks. So imagine now you're building out a site. You have a custom post type book. Someone adds a new book. And they have the page already built for them. And all they need to do is click in and add some content. So again, I think this is a much better experience. And you can lock the templates, which is also nice. Say, unlike a regular poster page where you can click little plus button and add a new block, you can lock that. So they can't move blocks around or add their own. There's a lot of great resources that are getting better all the time. When we started building blocks, there was almost no documentation. And we read a lot of source code. There's still times where you still need to read the source code to get a sense of how these blocks work. But you can do that on GitHub and then the documentation that's written. Some of it's in the readme's on GitHub. And some of it is on the handbook at WordPress.org. OK. Getting started. We can't possibly cover everything here, but I want to give you enough to get started. And then I have some links to more advanced examples that you can look at and play around with. So hopefully this is enough to get started. So first of all, modern JavaScript does not just run in the browser. You need a build process at least. And this makes writing JavaScript, frankly, a whole lot nicer. But it does require us to have a few things set up. And Gutenberg is no exception to this. So the code needs to be compiled into what browsers can read. And to set up these processes, we need at least Node.js and NPM installed in our computers. This is really easy to do. You can just go to Node.js.org, download Node.js and install it. And that comes with NPM, which is the Node Package Manager and Node. And that's what we use to run things locally to build things. Once we have these tools, we can set up things like Webpack or Babel. When I first started doing React, there was no zero configuration tools. And I remember how long it took to set all this up. But thankfully, there are much easier options now. If you've done React, you might be familiar with Create React app, which is a zero configuration tool. And someone, I'm not going to say his name, because I'm going to probably butcher it, he created Create Gutenblock, which is an NPM package that you can install globally. And then whenever you want to make a new block, you just type in Create Gutenblock, the name of the block. And it comes with all these commands, like NPM start, which NPM start will build a development version of the plug-in so that if you have React DevTools, you can interact with it more. And it will also be a watcher. So it will continually watch for code changes. Whenever your code changes, it recompiles the code. And then you just refresh your browser, and it will show up. It also comes with NPM build, which is really useful because that produces a development version of your code, which will be a lot smaller. And it will take out some of that interactivity through the React DevTools. So I want to cover some basic ES6 so that it's easier to follow the code samples. ES6 is a much nicer way of writing JavaScript, and it provides some handy things that make especially writing modern JavaScript easier. The first one is the arrow function. So these two examples on the left and right are equivalent, almost. For the most part, we can say it's equivalent now. For those of you who are interested in how it's not equivalent, the arrow function preserves this. The variable this. So if you have a class and you're using arrow functions in it, this will maintain its scope so you can still have access to everything else in the class. It's very common to use mutable and immutable variable declarations in ES6, and that's using lat and const. And mutable means you can change this, and immutable means you can't change this. And so if you use the wrong one, your linter or your build process will give you a warning and say, hey, you're changing a variable that you said was immutable. This is becoming more and more common in JavaScript development, especially with Redux, where a lot of people started changing how they think about immutability. But that, again, will help you follow some of these examples. Destructuring is another thing that is very common to use because you're pulling things out of props or attributes. You're declaring a lot of variables. And so these two examples are equivalent. It's just that the bottom one, which is the ES6 way, is a lot more convenient to write. And then JSX. JSX is an XTML-like JS syntax where you still have access to all of JavaScript. So these two examples are equivalent. The left is the vanilla JavaScript way. And that React create element, what it takes is it takes a tag name, and then it takes properties, which you might think about them in HTML terms more as attributes. And then the children, which is anything within those tags. I think the version on the right, which is the JSX way, is a lot more readable, and it makes a lot more sense. So most people feel that way, and so it's very common to use. If you look, you'll notice class name because you're using JavaScript, that this is really JavaScript. The class name is the JavaScript way of changing the class because class is a reserved term in JavaScript. And so anytime you're doing anything JavaScript-y or HTML-ish you need to do it the JavaScript way, which means you're going to use a lot of the same things, like CSS properties and things like that. OK. Gutenberg has a ton of stuff built in for us to make it super easy to build blocks. Set attribute is a function that changes the block attributes for us. So we don't even have to worry about that. That's all built in. Is selected is also built in, which just lets you know has the user selected my block. Are we currently editing this block? If so, selected will be true. If it's not, it will be false. And then editor components, plain text, rich text, media upload, there's all these built in components that are just ready for you to use, which make everything very straightforward and simple. There's complete lists here listed on the GitHub repo. And you'd want to look, especially at components and blocks. Sometimes this gets reorganized, so just pay attention to where things are put at the moment. And these actually might be wrong, because there was just an update to how things were organized. OK, adding more. One great thing about using NPM and Node is you have access to over 650,000 packages. So let's say there's something that you want to do with your Gutenberg block, and you don't know how to write it, or you say, oh, I don't feel like writing this. NPM probably has a package for you. And all you need to do is NPM install it, and off you go. It's very nice, very useful for extending the default Gutenberg functionality. OK, I've gone really fast. I know. Do I still have you? OK. All right, so we are going to go over a very simple example. This is even too simple to use on a website. But I want to give you a sense of how easy it can be to get started. And before I go over the code, let's just, I'll just quickly show you how it works. It's called the simple paragraph. And so I can type in some text. And you see when I click on it, I have access to edit it, and otherwise it gives me more of a preview. That's all it is. OK. Very simple, but this will give us an idea of how to get started. So when we start, when we do, and this example uses create Gutenblock, when we start, the directory structure is going to look like this. We have our plugin PHP file, which is where some things are defined, like the plugin name, version, et cetera. If you've been building plugins, this will be very familiar, because it's exactly the same. And then we have our SRC directory, which has init PHP, where basically all the PHP code lives, where you're in queuing styles, in queuing scripts. And then unless you need to change that, mostly where you'll be working is in block, block.js. That's where the block lives. And when you build this, well, even building it in a development way, there'll be another directory that mirrors the SRC directory called dist for the distribution, which is the code that actually runs in the browser. That's the compiled code. So when we start, we just do some simple imports. In this example, in the create Gutenblock, it provides style.scss and editor.scss. That's just style.scss gets loaded both on the front end and the back end. Editor is just for the editing experience. And then we'll just import some standard things, like the underbar, underbar for internationalization. Register block type, which is how we define a block. And then we're going to use some default things from Gutenberg. We'll use the plain text and then a fragment, which the fragment is just a wrapper. And then the plain text is how we have a text input. Very simple. Register block type. So register block type just takes a few arguments to start. You have the namespacing and the name. You have the title. You have an icon. And most of this stuff is just to make it discoverable through that little plus button. There is another way to add a Gutenberg block, which is if you do a slash, you get a list. And you can actually search for it. And this will search often with a title and the keyword. So that's how those are different. And it's just things to make it a little more discoverable for users. And then you want to define your attributes. Remember, attributes, this is one thing that I think will trip up a lot of people. Attributes is how you interact with the block. So when you start, you need to define some attributes to get started. Now, remember I said that there's two ways to deal with how those attributes are saved. Either it's attached to a tag, or it can be saved as JSON. If you want to attach it to a tag, you need to provide a selector, like what we have. And it's just like CSS, I want to use the p tag. And then the source is, give me the children of that p tag, which you might think of that as inner HTML or anything inside those tags. You can define a type to make sure that you're getting the data you expect and provide a default. If you don't provide a selector, that will then save the attribute in the HTML comments. So in either way is acceptable. It doesn't really matter. More depends on your use case. Is this something that, am I providing data that's attached to a tag or not? In many cases, you're not. So and then we get to those two functions, those two methods, edit and save. So and this is, again, this will look like it's a commerce-separated list of an object. So edit is a key in the object. And edit should be a function. So we're going to use destructuring. What you pass in is called props, which is just an object. But you can destructure in the parameter and just get all the values that you need. So we're going to pass in attributes, set attributes, class name, which is something that is global to every single Gutenberg block. Every Gutenberg block by default has an area that you can add a class name, which you just come to advanced, and here you have it. And that's just built in always so people can specify a class name. And then from our attributes, we only defined one attribute content, so we're going to get that in a variable two with destructuring. Now all we're going to do is, so these methods need to return a valid JSX or the vanilla JavaScript equivalent to render to the page. So whenever you return something, that's what's going to be rendered to the page. And in our case, we're just going to use a fragment. And the reason why this is something else that can be tricky when you start doing React is whenever you return something, it either needs to be an array of something that's enclosed in a tag or it needs to be just a single tag with something in between. So fragment is a built-in Gutenberg thing that allows you to build stuff and not really worry about that if you just put everything in the fragment. And then we're going to say, is this block selected? That's what the selected question mark means. Is it selected? If it is, we're going to display our plain text input. Otherwise, we're going to do a preview of a p tag with the class name and the content. That's all it is. Also the curly braces, what that means is you can execute JavaScript in that. That's what it means. So if it's a variable or if it's some kind of conditional, you need to put it in the curly braces. The plain text component operates in a very simple way. All the default editor components have an on change method that they use. So in this case, when somebody changes that input, we're going to use set attributes to save that new content. So that's going to be used. All the editor components have that. And as long as you define that on change and use set attributes, it will update your content. And the save function is very simple because we already wrote our preview. Our save function is just what the preview shows. So that what gets shown on the front end is exactly the same that gets shown on the back end. Again, we do destructuring. All we care about is attributes and class names. From attributes, all we care about is the content. Any questions so far? Did I lose you? Or does that mean I explained it so well that you don't have any questions? Yeah, so that's just on the imports. OK, I should explain this better. So when you're working in the editor, just in general, even without Gutenberg, there's this global called wp. And it has things like the API. There's methods for the API. I don't remember all the things that are in there by default. But when you're using Gutenberg, it also exposes some other sub-objects, like editor, blocks, and element. And you just import directly from that wp global. So I haven't set that up on mine. And I don't know if you can do that. So it's not a part of your local code base, because it is just a global that's put on the window. And so there might be a linter out there that does that. But I haven't used it. Any other questions? So here are some examples that I have just publicly on GitHub that will really, if you want to dig in more, I think would really help. So the first one is how we're approaching doing Gutenberg for client sites, which we haven't done one yet, but we're developing this method. And what we're doing, and if you download that and play around with it or just look at the code, is we're taking away all the colors and all the different editor things, all the style changing. And we're giving people a list of classes to choose from. So if you want to have a button, right now I think we have four classes that you can choose from. And then the theme will deal with those styles. So when you're building a site, instead of the content creator being like, oh, what colors did this button be? They just say, OK, I want a primary or a secondary style. So we're taking away that freedom, but taking away that freedom also means that they can focus on what they're doing, creating content. And then everything they do is going to be, according to the branding guidelines, because all they're doing is choosing a class that the theme controls. If you want to look at some more advanced block demos, I've done some other talks on creating advanced Gutenberg blocks. And these are two repos. The simple statistics one is just a way where you can add a bunch of statistics. And it will use this in a way to have a flexible layout. And you can put a bunch of things in there. And then the Gutenberg simple weather block uses a third party API integration. And it does, instead of rendering in the save method, there's a way in Gutenberg to render in PHP through the plug-in so that you can do things like protect API keys, or do anything that you might want to not expose to front-end users. So hopefully those examples are simple enough to follow if you want to learn more, or just come and find me and talk with me after the talk. I'll give you a few gotchas at the end. There are a lot of gotchas with Gutenberg development. At least we found that to be true. One of the big ones that tripped us up initially was validation. So what happens with validation is when you save a block, it gets saved in the post content as HTML. And then when you reload the editor page, it will take a look at the attributes, and it will take a look at your tags, and it will try to recreate your Gutenberg block in the editor component. And if something doesn't match, Gutenberg freaks out and says, hey, I think somebody's been messing with your content, and it doesn't like it. So when you make changes in your saving content, it's really easy to break the validation. And as you start playing with that locally, you're going to run into issues, and it's going to break things, and that's OK. But you want to make sure, at least when you do it, I'm going to release this plug, and you can refresh the page. And then if you ever need to update it, there is an additional optional key in when you register Gutenberg block for deprecated versions of your plug-in. So what will happen is Gutenberg will run through your current version and say, oh, this doesn't look right. And then it'll say, is there a deprecated key? If it does, I'm going to run through those versions, those deprecated versions, and still see if it matches. So Gutenberg does provide a path for upgrades. But it's really easy to break the validation. Some other gotchas, arrays don't allow for declaration of sub-attributes. So arrays are kind of like if you ever use Mongo, throw anything you want in there, which is amazing freedom, but it also can create problems when you're not careful with how you do that. SetAttributes has a big downside that I don't understand why it's like this right now is that it has no callback. So if you don't know what a callback is, a callback is a function that's called when another function finishes executing. So it can be either anonymous or not anonymous. And if you've done React development, setAttributes is very similar to setState. SetState does have a callback. So that's really nice. You can say, did my set, did my state update, then when it's done updating, I can do all this other stuff. And if it doesn't, then I just wait for that execution to finish. SetAttribute doesn't have that. So you don't know did your attributes update yet or not. So you have to do some hacky workarounds like setTimeOut, or it's not a great piece. And then using out-of-the-box components won't look like the front end. So that's why we do that preview in our example. Because otherwise, those components don't really look like the front end. And so it can break that what you see is what you get experience. And then there's a really great block called inner blocks, which is super helpful because it allows you to nest blocks within another block. But one big gotcha with that is that it has a global scope for that block. So you can't have multiple inner blocks in a single block because instead of having separate content, it shares content. Those are kind of the big gotchas. There's a lot of new features coming out all the time. The latest release introduces child blocks that goes along with this inner blocks concept of you can specify blocks that are only available inside of other blocks, which I think is a really great feature that they've added that will make making really exciting custom blocks a lot better. So any questions? Are you drinking from a fire hose, or is that? Yes. Yeah. There are issues on GitHub that said attributes should have a callback. And so strictly speaking, like Gutenberg doesn't provide a lifecycle. So if you're familiar, there's a lot of frameworks that use lifecycle, mobile development as life cycles. But what's nice is you can use regular React components in those editor and save methods. So when you do that, you have access to the full lifecycle. And then you just pass in the component name and you use that instead. Yes. Besides the callbacks, are there any kind of limitations that vanilla React has that? Not that we've really run into. There's some oddities with some of those default components, like for instance, the color picker is in a dropdown. Or the custom color is a dropdown. So if you put the color picker in a dropdown and then open the custom color picker, which is a dropdown, it closes it. There's some kind of weird things like that, especially around some of those components. But since you can use in your editor and save methods full React components, really what you have available in React is available in Gutenberg. It's just sometimes a little more work than, if you don't need the lifecycle, for instance, I don't bother writing a regular React component. But if you do and you want something like local state or you need component did mount component did update, then yeah, you just write your own component and it's fine. Yes. I had Wyatt. On the bottom of the screen, you had a website address. Yeah. And it says that the slides are there. Is that the direct link to the slides? So there'll be slides and links to the code samples there. So just go right there and the slides will be there. There's not like a button or something. Do you have to click? No, no, no. It's just a page. It's a blog post. And there's links to GitHub and the slides. Yeah. Thank you. Custom Gutenblocks, how do you deal with making a backwards compatible? Yeah, so that's what the deprecate it is. So deprecate it is an array where it can list all the deprecated versions of your block so that it can still revalidate. And I believe what happens is when it still finds a version, it tries to build the new version. I don't remember the process of how it goes through the deprecation exactly. And then when you want to edit something, again, that's been deprecated. And I'm not sure what, you know, this is, I think, an unknown to for the future. It was like, what happens if I have a custom Gutenberg block plug-in that's out there for five years? How many deprecated versions am I going to have? I don't know what that's going to look like in the future. But right now, that's the path that's being provided. Any other questions? Yeah, thank you.