 We're gonna get started. Welcome to Creating Advanced Gutenberg Blocks. Whoops. My name is Eric Debelak. I'm a senior developer and co-founder at 11 Online, and this year we started Block Party, which is for Gutenberg Blocks. I've been around WordPress for a long time. I tried it way back in 2004, and then started using it more in 2006. All right, is this good? Okay. These days I'm mostly a React developer. I do a lot of React, and then on the back end we use things like Lumen, PHP, or Flask, which is a Python API framework. Then I also do Android development, and I still do WordPress. Before we get started, have people tried Gutenberg yet? Have people tried making Gutenberg Blocks yet? Does anybody know React? Okay, I saw one, one of these. It's okay. What is Gutenberg? I'll just do a big overview, and there's gonna be a lot of things in here that might be super unfamiliar because Gutenberg development is unlike WordPress development as it is today. So if everything is unfamiliar and weird, that's okay. Just kinda go with it. I'll try to introduce you to some concepts that really, okay, that's okay. That will help you kinda get started and conceptualize what you're doing, but if all the code looks crazy and scary, don't worry, that's, you just have to learn the syntax. Okay, I don't, don't do that. That's, we have a meme of my CEO. There we go. That's one of these. All right. All right, there you go. Excellent, thank you. So, you always wanna have a meme of your CEO. So Gutenberg, it's, what is it here? Who knows? Soon, hopefully. What you see is what you get. I mean, kind of TinyMCE is what you see is what you get, but we'll kinda go over that this is a lot more like that. The content paradigm is blocks. Everything is a block. We're gonna be writing blocks, designing blocks, little pieces of content. And it comes with a lot of simple blocks, but you can build your own, which is what we're here to talk about. And it's written in React.js. You don't need to use React.js, but you should. So it's just one of the things you're gonna have to learn if you wanna make Gutenberg blocks. All right, so let's have a demo. See if this works. Just, this is a set. Set expectations, okay? Okay, so, okay, so this is a Gutenberg editor if you haven't seen it. It's really, you just come here and you choose some blocks and you say like, I'm going to write a paragraph and you can add, you know, an image or you can add, we'll add an image of my CEO. Who I love, but this is very similar to what we're used to, right? Like, it kind of feels like TinyMCE, no big deal. There's some things that are nice, like you can rearrange things. They're working on some drag and drop stuff. There's all the extra settings are on the right hand side. But I think where Gutenberg gets really interesting is not in just how it replaces TinyMCE, but it's the additional possibilities that it opens up for us. Because it is a, what you see is what you get editor that you interact with. You're not using short codes. You're able to do something way more interesting and I'll give you an example of a pie chart. So I'm from New Mexico. So we're gonna talk, we'll make a pie chart on Chile. If you ever visit Albuquerque, you're gonna get a question at every restaurant, which is red, green or Christmas, okay? Red Chile, green Chile, or both of them. So we'll just do a little pie chart with Chile. We'll assume that there's some voting going on. We'll add another slice. We'll say, I don't know, 35 people on green Chile. Orange, okay. So, I mean that's pretty different. And then we can come over here and suggest a size a little bit and you can say, oh, I wanna change the labels. I wanna make it 3D. How about spin it around? Give it a donut hole, right? This is what Gutenberg opens up for us and this is where I think Gutenberg gets exciting. All right, did I convince you that it's exciting? Are you excited? I'm excited. Okay, so some basics. Gutenberg puts everything in the content. It's the content box or block or you use it in templates with the content. So you can say, with some caveats, goodbye to post meta. If you're used to developing sites using a lot of post meta, you don't need that anymore. Well, with some caveats. You still might want it for searching or for some other things, but for the most part, you don't need to use post meta for all these different fields. Gutenberg uses attributes as settings on each block and then there's a lot of good resources and we'll kind of go over all this stuff in more detail. When you register a block, the block is basically two things. It's an edit method and a save method. And what the save method does is it takes all your attributes, which are all those settings and it saves it as HTML. And so it might look like this. So this is what gets saved in the content, of in the page content. And then if you have attributes, there's two ways of dealing with attributes. Attributes can either be attached to an HTML element or they're saved as JSON in HTML comments, which is a kind of weird way of doing it, but it works really well. So like if we have like a pricing table block here and then all this is our data associated with that block, just as an HTML comment. You don't see it on the front end. This gets pulled out, I assume using some filter. And all you get is the HTML. On the editor side, Gutenberg takes those attributes, parses them and then it creates that editor method, that editor component using those attributes. And then what the editor method does is that's what allows you to interact and make all those changes like I was doing. And like I said, the front end of the site just shows the saved content. So we'll just do a really simple example to conceptualize this and then we'll get into more interesting things. So this is the register block function. This is JavaScript. You set some default attributes, which attributes again, that's your settings. And Gutenberg does validation, where it says based on your attributes, does your save methods HTML match what I think it should be. So you always need to declare these, otherwise it will break the validation. Here's our edit method, okay. Pretty simple. Again, this is react. You have some built-in stuff that you get that are passed in as parameters. And then we have this very simple method, which all we're just doing is we're saying, is this selected? If it is, we're gonna show one of the built-in plain text inputs. If it's not selected, we'll just show a p-tag with the text. The plain text method has an on change, which uses the built-in set attributes to change the attribute, okay. And then the save method. Remember, this is what saves your HTML. Very simple. Save a p-tag with your text. Okay. So a lot of react kind of tooling around react is complicated because you have to compile everything and use webpack or babble. But their create-gootin block is a really useful tool because it does all that for you. Once you install it, is everybody familiar with NPM? Okay, some people are shaking their heads. All right, NPM, if you don't know that, you'll need to get used to that. That is the new world of WordPress. So NPM, once you have installed create-gootin block, you name it, cd into it, and then you run start and it will run a watcher. So as you make changes, it will recompile your code as you go. So what's built-in? Gutenberg, one really nice thing about Gutenberg is there's tons of stuff that's built-in just ready to go for you. Set attributes, again, that's what deals with changing your settings, and it also is what tells the editor that you can save the page. Until you run set attributes, you can't save the page because it doesn't think anything has changed. So that comes with it, is selected, tells you, is the user selected this block to interact with it or not? There's tons of built-in editor components. In our example, we had plain text, there's rich text, media upload, color palette, drop-down, interblocks, the list goes on and on. So there's, if you go to the GitHub repo of Gutenberg, they have two different types of components. One is just components and the other is blocks. So if you kind of look in there, those are all things that you can import into your project and just use right out of the box. Let's say you want more. If you're not familiar with NPM, it's Node Package Manager. Because we're writing in JavaScript, you can use NPM to install any package you want. One thing for example that we've done is there's some weirdness with the color palette. If you put the color palette in a drop-down, they have a custom color palette, that's another drop-down and you can't put a drop-down in their drop-down. So all we did is we looked at, okay, what NPM package are they using for their custom color picker? We imported that and did our own implementation of it and it was, it took maybe 20 minutes, right? 650,000 packages, you can probably find whatever you need on NPM, okay? So now we're gonna get into some simple, I shouldn't call them, they're maybe not that simple. They're as simple as I could make them to cover a lot of the concepts that really show what can we do to make some really exciting blocks. So we're gonna start with simple statistics. So our goals are is we wanna make a simple statistic block that allows users to input as many statistics as they want, okay, and then just have it count up when it appears on the page, okay? Not too complicated. So what are some strategies that we wanna use, okay? We need to have attributes, but since we don't know how many statistics people are gonna use, we won't need to have an array of attributes, right? So we can have some flexibility in the number of statistics people put in. And since Gutenberg only saves HTML in the content, we don't get any of the JavaScript interactivity on the front end. So we need to do something to overcome that and what we're gonna do is we're gonna use data attributes and then we'll write a jQuery script to parse those attributes and start the count up animation. Does that make sense? Okay, all right, so we start when we get the file structure of create Gutenblock, we get a directory called SRC, which is where we do all of our editing and we have an init PHP file. And this will look like if you're used to plugin development, this is gonna be everything that you've always been used to, okay? What do we do? We're gonna just enqueue some styles and scripts. In this one, you get some basic, the create Gutenberg block stuff comes with some styles that are editor specific and front end specific. And there's one function that will load things on both the front end and the back end and another one that will just do the dashboard. So we have a count up library, right? That we just pulled from GitHub. And a peer library that just is looking to see, okay, when does this element appear on the page? And then we have our custom count up JavaScript that parses and starts the count up animation. And then for the editor side, we have our the block JS, which that's the react stuff, right? That's the only place on the site by default that you'll load react is in the dashboard. And that's where you get all that interaction. And then we have just some editor CSS. So that's our PHP file or main PHP file just in queuing some stuff. And then we move to our SRC block block JS. This is where all the react stuff happens. At the top of the file, what we're just importing some of these styles, right? We're importing I189, which is the internationalization stuff. And then we start importing stuff from the WP global. So the WP global, if you're not familiar with it, you might have used it for the API. If you just go in your console in your browser on a WordPress site and do W, console log WP or just type in WP, you can see tons and tons of stuff that's associated with that. With Gutenberg, it adds all the blocks and components and everything to this WP global. So we're just gonna import some things, register block type, that's what we need to start. And we'll import our plain text. Am I going too fast? Everybody, thumbs up, thumbs down. No, okay, so I want thumbs up. All right, we're gonna register our block. Okay, again, everything here out of this from the create Gutenblock, I only added this last line here. So when you do this, it builds a working project for you and you can just start playing with it from there. We're gonna give it a title and that's how you find it when you press that little plus button. Actually, I should show you guys what this looks like before I go into all the code. Oh, and by the way, it does look the same on the front end as it does on the back end. Okay, so simple statistics. It's gonna be really simple. We're, what do we want? Here's something, a lot of sites put on. I never know what to do. We'll say it takes a lot of time, a lot of cups of coffee to make some websites. Okay? All right, and then the front end, same deal. Okay. That all makes sense. So all we need to kind of get started is we just, all the stuff up through keywords is to help people find it. So there's a few ways in Gutenberg that you can find your blocks. You can actually do, I think it's forward slash and then you can start typing and so you don't have to go and press that little plus button to add blocks. There's little shortcuts on the right-hand side. There's three or four ways to get it and depending on how you do it, you either would use the keywords like statistics or the title and then you can have an icon and there's different categories like embeds and I always seem to use common. And then we set up our default attributes. Again, we don't want to break the validation. We need to let Gutenberg know what kind of attributes we're expecting. So we have our stats array, simple. You can't, you cannot define like attributes within an array, like if you have an array of objects, you can't do that. So you just have to go with just an array and you can put whatever you want in there. And then a random key, which all we're using the random key for is so that we have unique IDs on the front end when we're starting our animations. Okay. Now we'll kind of go through the edit method. Again, you know, all these parameters, these are just things we get for free with Gutenberg. When we do the edit method, we're just gonna check to see if the random key is what we said as a default, otherwise we're gonna make a new random key. When you're writing React, if you haven't written React, everything that you do is a component and you tend to organize your code in these little chunks that do one thing. So you'll see as we go through these, that's what we're gonna be doing. We're gonna be making these little tiny blocks of code that do one thing. And they're just defined as constants again. I don't wanna get into like ES6 and React too much. Hopefully it will at least be readable if you're not used to it. There's a lot of conveniences in shorthand. So we're gonna make an add row button. Basically all this is, is a button. Does this have a pointer too? Which button? Red line? Oh okay, nice. Fancy. Basically all this button does is it has an on click method that it puts a new stat at the end of our stats and then it sets an attribute to our new stats. So we're using set attributes saying, let's just add an empty object at the end. One gotcha if you're not used to JavaScript development. JavaScript is passed by reference. So you need to make new variables instead of just modifying the variables, the attributes that you already have. Because how JavaScript works is it says, oh the reference to this variable is the same, it didn't change. So you need to make a new variable. So that's all we have, right? It's a button, on click. We add some new stats to the stats array and then we set it. Delete stat works much the same way. It's just a button, on click, whoops, wrong button. On click, we're gonna use slice and we're gonna take out the attribute or the stat that we don't want anymore. And again, using set attributes. And then we're gonna make some just convenience methods which is render plain text to, we're just making a more flexible function that can take in what type of field it is and what the index is and make an input for us that will save to the right piece of data in the stats array, right? Again, on change we're just, you'll see a lot of things use the on change method. So we'll kind of go over that more in the other example. And then we have another method just to start the count up animation in the dashboard. One thing you'll notice with a lot of react stuff in general in Gutenberg is no exception is there is some duplication of effort. We have kind of our editor side or editor animation but we also have to make another set of that for the front end experience. So this just uses a library, it's nothing too fancy. And then the main part is always the return. So in react, whatever you return is the HTML that's being shown. So what we're gonna do is we're just going to, we're going to take our stats that are again part of that attribute global or the attribute object that gets passed in. We're gonna map through them which just goes through each item in the array. If it's not selected, we'll start the count up. If it is selected or and then we'll do the different pieces of it. So if it's selected, we're going to use our helper method to make a plain text input. Otherwise, we're just gonna show some HTML and the same thing for the label. And then if it is selected again, we're gonna show delete stats so that you can delete the stats that you want. Is this all conceptually making sense? Yeah, good, okay. And then at the bottom again, we'll just say, are we selected if so, we'll add a row. Okay, we'll do the add a row button. So it's really not that much code, right? I don't think it's a lot of code. If you can imagine writing that in jQuery, you'd probably write 10 times the amount of code. Save function is very similar, all we do. Have some HTML, map through the stats, put them on the page. Okay. So I didn't show you some of the code, like I have the thing that parses out. Oh, actually that's one thing we should talk about quickly. Is, again, since we don't have that interaction, we don't have JavaScript on the front end. All we're doing is we're passing in the stat value as a data attribute, right? Because otherwise we don't know what the countup value is. And then if you look on GitHub, you can see I have that countup.js. All it does is it goes through each element with a class name of simple statistic countup, gets that value and starts the countup animation, okay? So what are our goals, right? We wanted users to put in as many statistics as they wanted and have a simple countup animation. So our strategy is we use an array to allow flexibility and then we use data attributes to save that countup data so that we can parse it on the front end with a jQuery script. All right, how are we doing? You guys feeling, is this drinking from a fire hose? Is it okay? All right, so now let's look at something that's gonna feel more familiar, I think for a lot of people, which is a weather block, simple weather block. So let's kind of take a look at what this is. We'll do weather here. So we have a few things in this weather block. We have some unit settings, right? We can change it to see if we want. We have an API key, this is for open weather API. And then we have a city input that allows us to say what city do we want the weather for and we have some methods to save the API key and then on the front end we'll see the same thing, okay? So this, nothing too complicated, but this will feel more familiar hopefully if you're developing plugins. Again, all the code's available here. So what are our goals for this one? We want to save our open weather API globally. We don't need them, we don't need a user to put in their API key every time they want a weather widget, okay? But then we do want users to set their temperature and weather units, or their temperature units and city per block, okay? All right, system strategies here. We're gonna use server side rendering. Gutenberg allows server side rendering, right? Which opens up a lot more possibilities for us. So why do we want server side rendering? I don't want people using my open weather API key, okay? We're gonna save the API key on the WP options table all through Gutenberg so that all blocks, all weather blocks, have access to it. We're gonna use those right hand side controls like I showed you for the temperature unit, and then we're gonna use a full react component for the edit method so we have access to the react life cycle. The react life cycle has a bunch of different methods that get called depending on what happens. Like did the component mount, did it update? If you're familiar with, there's a bunch of, like Android development does the same thing, iOS development does the same thing. If you're familiar with any of those things. So we're gonna look, start again with SRC slash init. And we have similar things, right? We're gonna enqueue some styles, okay? Include for the dashboard only. We're gonna do our block JS again. We're gonna enqueue that and enqueue our editor CSS. Hopefully this stuff is familiar for you guys. We're gonna register our setting so that we can save the setting on the options table. Okay, this is all just standard WordPress stuff. And now we're going to get to the service at rendering stuff. So Gutenberg has this other, has this method register block type that also exists in PHP. So you can register a block in JavaScript, PHP or both. And so on this instance, we're gonna use the PHP version because it gives us this render callback method to say what function do we wanna call when we want to render our block. Otherwise it's very similar. You don't do the names and stuff and the icons in PHP, but you do have to define your attributes. And so then let's look at our render block. This is just a very basic API request. We say, okay, let's get our API key from the database. If the attributes, we get the parameter of attributes, which is an associative array. If the attributes has a city and we have an API key, we're gonna make an API request to open weather. We build our URL, use WP remote get, decode the stuff we get back, and then we're just gonna make a little convenience thing for if people don't wanna see a metric imperial that show them CF or Kelvin. And then once we have our weather, we just return some HTML. That's all we have. So hopefully this, if you guys are used to developing plugins or things like that for WordPress, this shouldn't feel unfamiliar. You guys good with that? Okay. All right, so the JavaScript side will be probably less familiar, but we're gonna just do the same thing that we've been doing, right? We're at the top, we're gonna use the built-in stuff, we're gonna import it. In this case, we're using a simple debounce. If you're not used to debouncing, do you guys know what debouncing is? No, I guess? No? Okay, so debouncing is a way to delay when a function is called. So what it will do is it's kind of like, in a sense, you're kind of like listening to say, has this changed a lot of times? And if it has, I'm not going to call this function until it stops changing. So people commonly will use this for like scrolling or if you're doing scroll events and stuff like that, so you don't call too many events in the browser. We're gonna do it so we don't make too many API requests when we're typing in the name of the city and run out of our rate limit for the day. So again, we have to register our block type just like we did before. We don't need to say what our attributes are, we already did that. This is all similar, but in this case, instead of having an edit method, we're going to use a react component. React components technically are a function. So Gutenberg will be able to use a react component in edit instead of having a function. And it will go over that last. And since we're doing server-side rendering, this will be the easiest part, return null. We don't want anything to be saved because we're gonna deal with that on the server in PHP. Okay, so if you've done any react, this will look really familiar. If you haven't, I'm sorry that this is, it might be overwhelming, but we have our editor, we have our component, which we've imported at the top. This is WordPress, or Gutenberg has a wrapper around the typical react component as an abstraction so that if react changes their component API, WordPress will deal with that, or Gutenberg, I should say, soon to be WordPress will deal with that for us so that it won't break whatever we've been building in Gutenberg. So they can provide that, they provide that layer of abstraction to prevent any kind of breaking issues. When you have a react component, you have something called state. React is basically a state machine if you're familiar with that concept. If you're not, what that means is instead of manipulating each little thing on the screen, you just change your state and then from that everything else responds. So you're only changing the state and then whatever you have just changes. So we have some state, why do we want state? This state is local to the component, why do we want that and not saving attributes? Well, the big reason is that the weather is gonna change, right? So we don't want to save the weather as an attribute because it's gonna change every, I don't know, how often does it change here every five minutes? So we want this to be saved locally but not be available on the next page refresh, okay? For the dashboard. And then we set our weather API just to an empty string and then is saving to false which will be for a button animation. All right, now we start to get into the life cycle. Component did mount. When the component mounts, what do we want to do? We're gonna use the WP global and we're gonna use the WP API to get our API key, okay? If you've done stuff with using WP API in JavaScript this should look really familiar. These are all methods just built into WordPress ever since the API became a part of core. So what we're gonna do, we're gonna get our setting and then we're gonna save it to our state so that our component now as it mounts gets the key, saves it to the state so now we have access to this API key. And then when the component did update this will run many times. Whenever anything changes, this will run. So we're just gonna do some simple checks so that we don't get the weather constantly. We're gonna say, okay, do the city change? If the city didn't change or the units didn't change or if we don't already have weather or we don't already have an API key, we're just not gonna. So component did mount, just like a lot of other React life cycle methods has a lot of parameters that get passed in automatically like what were the previous props which that's an inheritance thing, what's the previous state? That's again the state that is local to that component. We're gonna make save API key. This again is using all the stuff that's been in core since the REST API. This is all documented really well on the handbook so just take a look at how some of this stuff works. One difference is that we're going to use this set state. So set state, kind of like set attributes is that's a React, set state is a React thing and that will just allow us, that's the method that's given to each component to save the state and all we're doing there is saying okay, we're saving, now we're done saving. And then now here's again remember what I said is you can't save something until the attributes change. So we have to do this really dumb thing which is if we're just changing the state, we still wanna allow the user to save the post. So we have to do just a dumb thing to tell. Hey Gutenberg, there's been a change here. Okay, get weather. Here we have more duplication of effort unfortunately but we wanna repeat our method of getting the weather in PHP and do it in JavaScript so that the people who are interacting with the dashboard can see the weather, can see that it's working, see that their API key is valid. This basically works the same way. I wrote the API request in jQuery because I thought that might be more familiar. Otherwise it's all the same. Again this, we're debouncing this function so we don't call it more than until it stops being called for one second. So that's what the thousand milliseconds is at the end. Okay, and then we have our render method again. Render is what gets shown, that's the HTML that we see. And this is all pretty basic, same thing as what we did in PHP, right? But we're doing it again in JavaScript. But we do have this other thing, which is our controls. So React, when it returns, you'll see two different ways that React will do this. It'll be parentheses, which is when you're returning a single element or you need to have an array because you can return an array of elements. React does not like it if there's two adjacent elements that it's returning in a component. So you either have to use an array or just use a single HTML element where everything else is the child. Inspector controls is again a built-in thing. That's what's on the right-hand side. That gives us everything that we need when you select a block. That's our right-hand side controls. So again, we're gonna use isSelected. What's unfortunate about Gutenberg is that the Inspector controls are global to all blocks on the page. So if you don't use isSelected, your controls are gonna show no matter what's selected. I don't know why that's the case, but that's how it is. So Inspector controls are global to the page. We're gonna just use some built-in things, which we'll go over in more detail, right? Select Control, again. Gutenberg provides all this for us. It's really nice. You have a Select Control, you pass in your options. On change, use set attributes. We have our text control, which this is what's going to set the state for our API key so that we can save it locally. And then when you click on the button, that saves the API key to the database. And then it provides this helpfulIsBusy, which is just pulled from the state. Okay, so that makes sense. Feeling good? Everybody's good? 10 minutes? All right, okay. And then when we are, this is further down in the render, this is that second item in the array. Again, we'll say, is it selected? If it is, we'll show a text control where they can set the city, right? Starting to see some patterns, use on change, set attributes. And then we just down below, is we say if we have weather, let's show it. Otherwise we'll show no weather. And then this is just in detail, so you can see. I forgot that I put this in. But this is just bigger, basically. So again, what are our goals, right? We wanted to allow users to globally save the open weather API key, but then set their other controls based on the block. We use server-side rendering, so we don't expose our API key. And we saved our API key on the options table, use inspector controls, and we use the react life cycle. Okay, so there are a lot of gotchas with Gutenberg. Gutenberg's a moving target. I found out yesterday morning in the airport that they released a breaking change, and I had to update my slides and code examples. Luckily it wasn't big. It's getting better, though. Every release is getting better. Validation is one that trips up a lot of people in the beginning because, like I said, Gutenberg revalidates every block. It wants to know that your HTML matches your attributes. And if you're doing things that are more complex, like some of these examples, and you're saving those attributes as JSON in the HTML comments, it's going to say, do these two things match. If it doesn't think it matches, it says, whoa, this is wrong, and this is bad, we're not gonna let you re-render this block, or this code as your block. You'll have to change it with some custom HTML. But the best way to get around this is you use those default attributes. And in the future, when you make changes to your blocks, there's also a deprecated block method that's optional when you register the block, and that's an array where you can put in all your deprecated blocks so that what it will do is say, hey, this doesn't match. What I think it should be, then it will start running through the deprecated blocks until it finds one that matches. Arrays don't allow for declaration of sub-attributes, which is good and bad. If you're used to maybe like MySQL or strongly type languages, you might think it's bad if you use JavaScript as kind of like anything goes anyway, or like Mongo, just throw anything you want in there. That's kind of how arrays work. Set attributes is another gotcha. It has no callback. Unlike setState for React, which has a callback, setAttributes doesn't have a callback, which means, if you're not familiar with that term, is you can't, a callback is usually an anonymous function that gets passed in as soon as the first function is completed. So Gutenberg doesn't let us know when setAttributes is done, unfortunately. So that's kind of a hassle. You have to play around with how you wanna do that. Using out-of-the-box components don't really look like the front end, unfortunately. But that's one reason why I like to use isSelected and show either the edit component when they're selecting it, and otherwise just show HTML, so that users will have a better sense of what will the HTML actually look like when they are building their page. And there's inner blocks. Inner blocks are nested, so you can make a block that has basically total freedom for other blocks to be thrown in there. The one downside to inner blocks is the inner blocks are global per block. So if you can't use three inner blocks, right? Because then all that content will be in all three places. You can only use one per component, one per block. The other great thing that has me excited about Gutenberg is templating. Templating, like if you're used to using custom post types, this should look familiar, but there's some extra things in there like template, which is an array of Gutenberg blocks. So now when you're building client sites and you have something like you're building locations or whatever it is or team members, when they open up that page, if you're using this templating, there will be a Gutenberg page filled out with all the blocks and some default content if you want, and all they need to do is click into them and change the content. And there's even controls like template lock where you can allow them to not add or move anything. So that was a lot of information, right? Five minutes, what questions do you guys have? Yes. So that's with the templating. So in here you can, this is just an associative array and you can add extra things to it. So, and on all the attributes for your blocks, you can put in defaults. So if you wanted to, for any block, you can put in some default content. So for those of you who had never seen ES6 or React, was it conceptually, did it make sense the things we were doing? Yeah, okay. I encourage you to look at the repos, right? Those are there. Fork them, do whatever you want. I tried to choose the simple examples that covered a lot of different areas of Gutenberg development so that you can kind of see, building off of those two things, you can, like there's a lot of permutations of other cool things that you can do. So, yes, I think so. Yeah, yeah. So it depends, right? I think, you know, like we've been building custom blocks because we think it's a big opportunity. But I do think that if you, so I would say there's, it's kind of a double-edged sword, right? Because like that pie chart block I showed you, you can kind of go nuts and do whatever you want. You can choose all the colors and you can, you know, that might not be what you want for a client site. What you might want for a client site is no options or maybe a few options, right? So they don't go crazy and mess up the site. So I think that there's kind of maybe two different approaches. One will be infinite customization, right? Change the border radius, change all the colors. The fonts are gonna be pulled in from the theme. And the other approach is I'm gonna build blocks for the branding guidelines of my clients. And I might say like, let's say I have a call-to-action block. Maybe I'll let them choose from three background colors or maybe I'd let them choose from, you know, have an image to the right or an image to the left, but I'm not gonna give them infinite customization. So I think in some ways there will always be people who if they have to strict branding guidelines, you'll always be developing custom blocks because, and I can show you quick, how the default blocks are really customizable. So let's take a look at the paragraph one and I'll just put in some warm-ups. Okay, so what can I do? I can change all this stuff, right? Make it as big as I want. I can do this. I can make this unbelievably ugly if I want to, right? So this is, you don't want your clients doing this, right? So I think there will always be, there's gonna be a big need for custom Gutenberg block development to match those branding guidelines. This is the default paragraph one. Yeah. Yes. Yes, I agree. But thankfully, I mean, hopefully I've shown you that simple, that first simple example, that wasn't that complicated. And what you can do then, you don't need to give them any of this. You can, I forget how you do it, but you can deregister some blocks. So what I anticipate doing is we're going to definitely either deregister all this stuff or just have our own, right? And so, but thankfully it's not that hard because everything is there. This is, the P tag is basically the rich text component wrapped in a P tag. Yeah, I don't believe it does in Gutenberg. So yeah, the one thing with Gutenberg is it's really, it's not geared for people that make client sites in a lot of ways, the defaults. The defaults are built for people who might want this, right? It's built for just users that it's more of a square space type of experience. So I think that, yeah, I think there's always going to be a lot of work in making blocks that meet branding guidelines. So hopefully, you know, my talk was a lot about more of the advanced stuff, but hopefully in the beginning, you kind of saw that. That side doesn't need to be scary. You could just throw in a rich text block and have your own CSS. And if you don't put this stuff in, it's not there. So at least that's encouraging. Yes. Yeah, so there's a column. Yeah, there's a column block that's, it's still, I think it's still officially experimental. It uses interblocks, but yeah, it's still experimental, but you can, you know, add something here and then you add something, another pair. I always forget how this thing works. Oh, okay, yeah, just like that. So you can put in columns and then there's, I forget how you change the settings. Some of this stuff is still, still needs some work. Yeah, yeah, yeah, exactly. We're gonna do every once 5.0 comes out, every new site is in Gutenberg. I think that, you know, our clients use a lot of custom fields and post meta is, you know, why do we use post meta? It's because it's the only thing available to us. It's not a great solution. It's excluded from search. It's, you know, it has a lot of performance concerns. So I think that that switch away from post meta and a better experience of not like some, here's a list of all the fields and you just, you don't really know what it's gonna look like. We can just make a template. They put their content in. I think it's gonna be a much, much better client experience. It depends, I think it depends on what the previous experience is with WordPress. I think that Gutenberg is going to be, the templates are gonna be great. I think that for people who use WordPress a lot, let's say they're in their site three times a week, they're gonna be able to use Gutenberg well. I don't, I think that the people who maybe log in once a month, Gutenberg is gonna be more confusing until maybe some things change. There's a lot of, what does this stuff mean? What does that plus mean? And until they kind of get, I think you have to use it. Even see you saw I got confused with it. I mean, we use CMB2, but I just talked with the CMB2 guy. I'm interested in working with him on some things because I think there still is a place for post meta. Maybe it's a, maybe there's gonna be a wrapper that allows you to save data into a Gutenberg field and into post meta because it's useful sometimes to have that data to get all the doctors at this location or maybe it's a wrapper around taxonomies instead. But I think there's gonna be definitely some use cases to do some of that stuff. Well, there are Gutenberg enabled themes and you can do.