 Hello, so we're going to start a little early because we've already packed a place. So I've got a lot of content, so I'd like to maybe start early if that's okay with you all. Woo, cool. So hello, my name is, well first I want to start off by thanking the organizers. This is a really cool word camp and one of my favorite word camps, that's why I applied to speak here. I'm from Austin, Texas, so I came a long way and yeah, I hopped over the entire continent to get over here. And also thank you to the sponsors for making this possible. So quick about me, my name is Anthony Bruschel. I am an innovation developer, a WordPress innovation developer at WP Engine. I'm also the media lead for WordPress 5.0, which should be coming out very soon. And I'm a musician and a video game developer. And I've actually been combining my two passions of WordPress and video games to make a WordPress powered video game. And if you want to learn about that, you can look it up at broken.place. So let's start with a quick Gutenberg overview. Just to be straight up with you, this will be very in the code. This is going to be a dev heavy talk, because I want to try and explain it. Hopefully if you're not a developer, it will at least illustrate why this is so good for WordPress, because this speeds up the development time. It makes you more, it gives you more agility. So I hope that this at least illustrates that if you are not a developer. So Gutenberg is a rebuild of the editor experience. I think we've all clearly established that. I think we're all pretty familiar with the block editor. It uses React and JavaScript, if you didn't know that. And it utilizes a block structure for content. And I think we're all pretty familiar with that. It's a lot of page builders have kind of adopted this. And now WordPress is adopting this. So why Gutenberg? I'm going to tackle all those juicy questions first, because these are the questions that usually I am asked in the middle of my talk. So let's do them now. Why Gutenberg? The overall goal is to make it simple for new users. It's to allow you to see the content that you are producing, and not guess through short codes or HTML of what your content's actually going to look like. So I really like this quote. I won't read it, but if you want to read it, you can. Matt posted a blog post recently about an FAQ list for 5.0. And I think it's probably the most clear write-up of where the direction of Gutenberg will take us. And I highly recommend that you read that. So I also want to give this disclaimer, avoid technical debt and go to 5.0. It doesn't matter if you're even ready for it, just go to 5.0. And if you're not ready for it and you don't have time to test, install the classic editor. I know that I've actually been listening to talks throughout the day, and I've heard that a lot of people are echoing this, so that's good. So the classic editor will be maintained until the end of 2021. So we'll see 2022 is when we'll probably get an idea of when that's over, right? And I don't anticipate it even being over then. Imagine all the people that can contribute going forward or make their own classic editor plug-in, right? So this is great. This gives us all time to ease into Gutenberg. Imagine, I don't know too many people that have sites that they maintain the exact same site design for more than two years. So at least we get two years to build a new site, right? So what am I excited about? I'm excited about the agility that developers now have to focus on content creation and kind of the thinking that developers now have the ability to do. Like, they can now build applications with the content creator in mind as opposed to building the end product. That's where I think the fundamental shift with Gutenberg is coming. And WYSIWYG is now actually WYSIWYG. It's funny how we've been using that term. What you see is what you get for many, many, many years, but that's never been really true because what CSS takes over in the front end, right? And what you see is probably going to be a little different. And a modern JavaScript framework is going to bring some really cool thought leaders and developers into our ecosystem. We are now the cool kids, again, because we like JavaScript. Back in the day, we did PHP and a lot of people, I guess, rose their nose to WordPress because we were PHP focused. So now we're the cool kids in the cafeteria. Everyone's going to sit with us. So Blocks, what are they? This is the post editor view. You've been seeing this all day. I'm not going to beat a dead horse. Blocks are the different elements that make up your post. And they have dynamic controls that only show when relevant. And I will illustrate what that means very shortly. So it is built on React. And React, it has a component-based approach. And components are really interesting because they're dynamic and they're well documented. Many components that are in the React world, you can just grab the source code, drop it in your plugin, and almost one for one, copy and paste that component over to your code. And it pretty much works. For instance, I used the media element library. I created a Gutenberg component for it. And I literally copied from their readme into mine. And it worked somehow, which is kind of exciting because that means that we're kind of factoring in the general use case for these snippets of code. So what do I mean by components? Components are, think of them as snippets of code, right? In the same way that you drop a block in, an image block, well, we have it in a more granular level in the code to where we can drop in an icon, right? Like an icon is something that we, or an icon button is what it's called. And an icon button can do things. When you click on it, it does this function, open, right? And in this case, what it's doing is it's opening in the context of a media upload component. And what that means is open the media library. And what happens is, when you actually select your media and return it back, it passes an object back to the editor and says, here is all of the information about those images that you selected. Do what you want with it. So now developers are also gaining really cool tools, not just content creators. Developers now have this icon button that they can do custom things to. You can give it a custom class name. You can have CSS that only impacts it. And this is the editor view. So you can actually have CSS that works independently there. So you can also do components inside of components. And that's also exciting. As I illustrated earlier with the icon block or the icon component, you can throw that inside of media upload to hit functions that are available to it. And we can also now style inline. So CSS, how many times have you overwritten CSS for a specific ID? And you create like 50 different IDs, and you have 50 different pages, and you have to maintain the CSS over time, and you just build up this really long style sheet that doesn't need to be so long. I think one thing we will see is people will start thinking of CSS more globally in the Gutenberg future. Because imagine here that I have this div, and this div has a background image. And the background image is what's important, and what's important to that block specifically. What we now have the ability to do is put that inline here, and on a per instance basis define what that piece of the CSS is. And the user doesn't have to know CSS to do that. The user can actually just go in the inspector and click a button that looks nice and easy for their eyes to take in and select what they want. And then it builds on the code from there. And you can wrap a div around a component, which is really exciting, because then you start having these dynamic snippets of code that are contained within your layouts or your elements. In this case, I'm putting a div around a rich text component. And the rich text component is basically like the new Gutenberg text editor where you can highlight and bold, italic, whatever. Think tiny emcee in some ways. And you can also use what's called inner blocks in your custom designs. And an inner block is a component that requires two lines of code for the user to put on there into their block. First line is in the edit state. So there are two states that you are working with content. The edit state is when you're building your content. The save state is what's pushed out to the database. So if you're working on your content, inner blocks, what it says is give me all the content that's related to this block and push it in here. And inner block is essentially the Gutenberg editor put inside of something. So imagine you build a two-column layout. And you only want a Gutenberg editor inside of this one column, but you want to have some static assets on the other side. Well, then people can start adding more and more blocks within here. And you're packaging Gutenberg within your own custom elements in your own custom block. And I'll show you what that looks like. So here I have a block that I made. And hey, that's kind of big. And in this block, it's called WordCampYYZ. I learned that Z is Z. Well, my Z is your Z, right? So I'm trying to say it. But if you look in here, I've got this plus sign. And I can add a block in here. I can say I want a paragraph block. This is my, right? And maybe I want to add an image. And here's Gutenberg on a skateboard, right? But if you look at the containing block, I have Photoshopped this one. I'm proud of it. But if you look at the containing block, this purple area here, if I click on it, I have these controls over this block. I can say it's blue now. I can say it's purple. But the block editor is contained within this special functionality. And if I want to add another one of these, let's see, maybe I want to have a divider here. This was just an example of CSS changing. I took the simplest thing, changing something from red to green is very noticeable. So let's say I have some divider text and maybe I want to add another one of these really fancy blocks of mine with more blocks. Maybe I'll put some columns in here. So this is a column content piece, right? And maybe in here, I'll put an image. And let's do another Gutenberg on a skateboard. But you see now, these are different, but still based on this custom workflow that I see as being, I guess, necessary for this piece of content. Yeah. I've heard that in Gutenberg's continuing development, the nesting of blocks is regarded as a high priority. Yes. Is that not essentially what you're doing here? That's essentially what I'm doing here. Yeah, that's what's so great is in the code itself, all I did is I said, I want this div here that has all of these dynamic pieces. I want the block editor to appear within that. So then you can get really creative and start separating content and making your own cool layouts, right? Yes. In what way? So those are the things that I would say are global things that you want to define in your style sheet, but they're never on a per instance basis. I don't want to say that this block on this page can only do this kind of responsive thing or whatever it is. The thing, so in the case of this one here, the thing that I found was most important was this background image, URL image, right? That's inline. And that I do want to have a perfect instantiated version of that, right? So what I have there is there's this button here. And then if I hover over it, it says Image Background. So as I was showing you earlier, that open with that icon button, this is that icon button, you can click that and it opens the media library. And once you select your image from the media library, it passes it back and then sets it as the background of that block. So then you can do some really cool stuff there. It doesn't have to be just background images. It can be anything you want. It can be with some custom JavaScript functionality, chat boxes, whatever you want it to be. And that can coexist with your editor. Is this responsive, Gutenberg responsive, more or less, if you compile, quench it down then? Yes. Yes, it is. Responsive images have been addressed, like if you load Gutenberg on a mobile phone, the mobile version of that image is what's going to load. If you want to run tests against that, webpagetest.org, you can actually define the browser and you can run tests to see how that performs. So yeah, this is my block. It does really fancy things. This trash can icon here, it removes the background image. So if I click this, what it then does is it says the attributes that define what that image is, get rid of them. And then the editor updates that. So I'll get into attributes next, because let's look at how that data is defined, stored, and manipulated. I heard earlier today that what's really great about Gutenberg is now we have a schema on a per block basis. Imagine, so the REST API was really great because you could query a post and it returned back to the content. And we're like, oh cool, I can take this content and shove it into another screen that processes HTML, right? Well, what if there's a screen that doesn't use HTML? How do you take pieces of that content? You can't. But maybe that div that I had with the image background, that image is still important and it's important to all screens. Maybe I'm in a VR world and that image needs to show up there. That's not HTML, but the image is still the image URL. So you can now query in a more granular way what the content is and you can then use it in different mediums. So attributes are the important bits that are either stored in a hidden comment in the database. So if you ever look at a Gutenberg post, you'll notice there's a bunch of commented looking pieces of code that have a bunch of, I guess, well, the attributes, really. But they are key value pairs of image URL for that image. What's nice about that is that you can then on render query those and do things with them. So these are the audio attributes for that block. You'll notice, though, that these say that they have this argument of selector. And what that means is, so here's the data saved in the database for an audio block. These are those comments that I was mentioning. If you look here, the ID is stored in here. And the ID is important because you can then do things based on that ID. You can do a REST call based on that ID and return back all of the data that's important about it. Is that the ID of the media or the ID of the post? ID of the media, yes. And that's what's important to it. But you'll notice here that I have this argument of selector audio. And that's attached to this source attribute, right? What the selector is saying is that the thing that we know of as important in this block is what's contained within source in the audio HTML. So you have the audio element that contains a URL. It's now mapping that to that URL. And now let's say you don't define a selector. Maybe you don't have a way to map to that containing data within the HTML. You can not define a selector. And what it'll do is, by default, throw it into that comment in the HTML, which is, by the way, stripped out on the front end when a user visits a page. So they don't see that messy data. They see the final HTML. So the classic playlist block exploration. So this is how I got into Gutenberg. Before Gutenberg, I was, I'm PHP Dev. But before PHP, I was an object-oriented focused person. And I built flash games. So now I'm kind of going full circle to the object-oriented world again. And that's exciting for me. But I had to learn JavaScript in the process. So a year and a half ago, I think, is when I started work on Gutenberg. And my goal was to make the playlist block for the Gutenberg that ships. You might notice there is no playlist block currently because I'm still trying to figure out how to do this. But I did build one that has the essential parameters of a playlist. So let's look at that. Has anyone ever made a playlist before? Has anyone had any experience? I remember the audio tag. Yeah, with multiple audio files. In the end, what that is is just a short code. It's a short code that says, here are all the IDs. And that short code goes through a PHP function that then returns back some HTML of this really nice player, right? In the Gutenberg world, we need to do something similar. And there's a lot of custom functionality that we built into Playlist. And that was built very long ago. But you'll notice here on this right-hand side, these are all of the, I guess, arguments that the short code expects. And two of these arguments have never even been exposed in the editor. And those two are show track numbers and the playlist style. I don't know if you knew this, but there's a dark style to playlist. So what I found is that we needed to expose those one. And that's kind of hard to do with Admin UI. You have to then build your whole, your checkboxes. Just a checkbox, the logic behind it is there's a ton. But we have these nice little components for checkbox control that is, as I mentioned earlier, those dynamic snippets of code that you can then just paste in here. I literally copied and pasted these and just changed the attribute that it was triggering when you toggle it. So that attribute that I mentioned earlier, all of those important pieces of data, some of them can be boolean. So they can be true or false. In this case, it maps them when you click the button. But you'll see here that all I had to do was copy and paste this to then expose settings that we didn't have previously in the editor. And that's where I see we have a lot of, that's where the agility comes in for developers. They can work more quickly and focus on what the end result is and not how to get there. So you'll see here, this is how I actually store the playlist in the database. There's no other content that's stored. Because what I'm essentially doing is I'm utilizing that short code that we've been relying on for many years. So again, here's the important information is IDs and it has an array of IDs and then we have a show artist is set to false. So. I'm sorry. So it's saved to the database in these, the carrots and that's interpreted as a comment. But it's never rendered on the front end. So what's actually happening on the front end here is we're using the original core PHP. We are taking all of those attributes and we're throwing them at the short code function that we've always used, right? So what we're saving to the database is this. It's kind of like a short code, right? It's about this exact same thing as a short code. And then you're throwing it into this function. And you'll see here the WP playlist short code function accepts IDs. If the empty IDs, it does things, right? So it knows then, if you feed it the same data that it expects, if you're a plugin developer that relies heavily on short codes, well, all you need to do is just send those attributes to your function and you're all set. And the big thing here is we can still talk to PHP. This is a huge thing I think is overlooked with Gutenberg is that we're not going to just JavaScript. We're using JavaScript for the editor, yes, because we want to start saving and make a uniform way to alter content. So how do we talk to PHP? There's actually a render callback function that you can define in wherever your initialization of PHP is, like if your plugin's main PHP files, think of it that way. And all you have to do is define a render callback and right here, do render callback. That is the function that I want it to trigger and send these attributes to. And then this is the function just for demonstration purposes, but this is what my render callback looks like. And all this outputs in the end is just a div that contains things that are based on those attributes. And then it returns the HTML. This is PHP here. So this is what renders on the front end. So what the render callback, think of that as when a user visits a page, what happens to the attributes? Where do they go and how does it end up? And if you look here, it says return HTML. This function returns back whatever that final HTML looks like and in this case it's just a div, so it's nothing special. But if you have a function that does a lot of crazy things it'll just return back that big blob of code and then it'll return that back out to the editor in real time. Or there's another option. You can do this really messy thing that I had fun doing in a hackathon. You can build a short code. If you look here, you'll notice I've got a short code in here and I'm building up this big long string to then equal a short code that a user would expect. And then I'm feeding that into the do short code function. So you can build up your string that way. That's a quick and easy way to get compatible with Gutenberg if you're fearful of it. Or you can go to the new routes which is kind of building more dynamic content that's static and all the new things. We won't get into that so much. But this is how you adapt your existing content. One thing that's also really cool is you can transform one block into another block. And what's cool about this is that let's imagine that I have a custom gallery functionality and I want users that are using the current gallery to use my gallery. I can define that in my plug or in my block what I want it to change from and into. So in this case, you'll see this is an example of a paragraph that can change into a heading. And all it's doing is it's saying what are the important pieces of this paragraph? In the case of a paragraph, it's just whatever text is typed in there. In the case of a gallery, what are the important pieces? All of those IDs of those individual images are what I need. That's the only piece of data that I need to then make my special fancy gallery. So it's just knowing how to map the data from the existing block to your block. And this is a very easy snippet to add to your block because yeah. So you can also transform from yours into another one too. So you can add I guess options for users to not use your block although probably you don't wanna do that. You wanna get them to you. So how do you make a block? Some useful resources. I'm gonna talk a lot about Create Gutenblock because it has been the easiest way for me to develop and it requires one single command for you to make a plugin and a block ready to go. Like you can just start coding, it's amazing. So in GitHub, you can follow along with Gutenberg and read the source code. I've actually found in my block creation, I can take a one to one copy of an existing block, let's say the image block. I can take that code in the index and I can just throw it into mine and I have my own special block that matches exactly what the image block does and then I can start tweaking it. And I think that's the right way to do it. Zach Gordon also has a really cool course on JavaScript. He kinda has two different tracks. He's got the beginner track if you're looking to learn how to use the editor and he's also got this really detailed code, I guess code heavy course that will explain every single file in Gutenberg and I did that one and it made so much sense to me. I didn't even go through the course one by one like step one, step two. I was skipping around and looking at different files because I would start developing and be like, why don't I understand this media library thing? Go to the videos and he's got a whole thing on it, a whole video that focuses on it and that's just my learning process. Others may do it differently but I'm a visual learner too so it really helps to see things and it's a very visual guide. The Gutenberg Handbook is awesome too. This is kind of where you should look if you are trying to understand the block API. If you're trying to understand some of the decisions that were made design wise or technologically, why we went in certain directions, this kind of helps explain them and what all of these things are, like packages. Packages in the Gutenberg world are, well, they're there, you can read about them. I won't get into that. I'm gonna get on tangent if I do that. But yeah, so I highly recommend checking out the Gutenberg Handbook. So create Gutenblock Toolkit. This has been a lifesaver and I think a majority of Gutenberg blocks are made using this now. Amadoice, I always say his name wrong, I hope I said it right at the last name, but Amadoice is well known in the community and Amadoice is built this and open source this create Gutenblock Tool and it requires zero configuration. If you need to build a plugin, there's a lot of times you have to build a, you have to build your own custom configuration based on your workflow. If you have a way to lint and or whatever, you have to do that each time you make a plugin and maybe you do have your boiler plates that work well, but this can be seen as a boiler plate for blocks contained inside of plugins. So if anyone is using NPM version 5.0 or greater, you have the command to run, to create a Gutenberg block without ever downloading anything. You literally type npx create dash Guten dash block and then you name your plugin or your block and it will create a plugin with that block contained inside of it. So npx is the command I was talking about earlier. If you have NPM 5.0 or higher, you have that command at your disposal. And then once you're done with that, you just change directory into the block and this isn't a terminal, by the way, I'm gonna do this live, so this will be fun to watch. And then you literally type npm start and from there it does all of the things to configure this or to run webpack and to monitor changes and it's got a full toolkit built into it so that you can just start creating content. I would recommend just running it, even if you don't know what you're doing, running it and just explore the files because the files are heavily, heavily documented. He has every single function documented so that you can understand what it's doing, like editor styles. It's very clearly documented where the editor styles are, what they're doing and how you can change them. So yeah, let's freaking do it. So I am in my terminal here. I'm in the plugin directory. I think we all know where the plugin directory is, right? So I'm gonna type npx create-gootin-block and somebody yell out an animal. Panda. All right, so create-gootin-block-panda. So when you run this command, it does a bunch of great things and installs all this crazy stuff and creates a directory for it. So right now I just created a directory called panda. It's now installing some npm packages that are required for it to work, like webpack and all of the other nice tools to, yes. Oh, sure, yeah, well you'll see here actually, I'll go over the files that are contained in this because basically all this is doing is it's creating a boilerplate plugin and creating the block. But the functions that register this block are still gonna be the ones that you can put those in your function file for your existing plugin. Still gonna do the exact same thing. When I say register the block, I mean like it literally makes it to where you have your new block available when you search through the block list and that's what the register does. So cool, that was really fast. So I'll go into panda and I'll do npm start. So right now it's watching for changes in panda and I'm gonna go ahead and go to my local instance. So let's make a new, let's go to the plugin list and let's see it. So we should see panda here, yeah, there's panda. So you'll activate that plugin, right? The plugin is now activated. Let's create a new post and I'm just gonna hit slash, just so you know it's a keyboard shortcut. If you hit slash it gives you the block list and you can start typing a block name and it'll autocomplete. So I'm gonna type panda, woo, it's there. So now you have this block available, right? So this is the edit view and if I publish this I can view the post and this is the saved view, the front end and the back end work independently. But what's great about this is that I can now go through, I'm gonna use the YYZ plugin for our example because this is already in my workflow already but so if you look here, this is the directory. Imagine that said pandas and we'd be looking at the exact same thing. And inside of this directory we have node modules which is created by NPM, it's all those packages and we have source. Source is where you probably wanna pay the most attention. If you look at plugin.php though, you'll see this is the same thing we've been doing forever. We've been defining the plugin name and all of that through the comments and this won't change, it's still registered by PHP. So if we look inside source we'll notice there's a block directory. There's also this init.php. Remember I said there was initialization that defines your block and your styles and all of that? That's where this is happening. And you can look in here and see that this is loading the editor assets and where is that pulling from? Well, it's pulling from, let's see, CSS, right? So there's a CSS file here, common dot, there it is, editor.css, style.css. So it's easy to navigate this and kind of figure out where everything is talking. So let's look within block.js because this is where the meat of it all is. This is where the block is actually defined. There's a function called register block type and the block, the register block type is where you name your block and this is what, let's say I duplicated everything within this and you'll see that, let's see, where does it end? It ends right here. If I duplicated that snippet of code and renamed the block, there would be two blocks that I could then edit. I would recommend making it multiple files though. So what you would do is you'd create another file named whatever your custom functionality is, dot.js and leave it in the block directory and that's enqueued through here. So let's say I did create another block. I could just, I have another one here. I'm gonna rename it to block two. And this is gonna create not yyz, but let's do yyz. That's the American version. Yeah, that's the American version of the plugin. Localization is important, right? But you see how this is my workflow now? I'm editing this and let's say I finish this up. All I have to do now is go into this main, paste in here and say block two. Now it's gonna automatically enqueue that and then that block will be registered. So then you can start building up a library of blocks that are specific to whatever functionality you wanna build. I'm gonna undo that because it's probably a lot of syntax errors. Sorry. Yeah, yeah. Okay, so inside of a block you'll see there's that content I was saying. We have the save function. This is what's pushed to the database. And the database receives a return of that div class which is based on a lot of dynamic data like the div style which here is dependent on the attributes that are saved or that you define. So div style, what does it have? It has background images set to image. And I've got this height set here. This is just to demonstrate that there is an attribute for height. So let me go ahead and add YYZ. And if I click on this you'll see that height changes in real time because that's an important thing. But all that's happening here in the code is that height is just adjusting based on the numbers of that slider. Now that slider is really interesting too because that is another tool that developers have to add at their disposal. If you look here we've got this component called range control. And range control, you can set a min and a max. So the beginning of the slider, the end of the slider. And this is heavily documented in that component. You can go into Gutenberg, find that component and there's a readme file that says this is how you use it. So in this case, I liked it because it did the min height or the height min max thing. And I'm a musician that plays with synthesizers so I thought sliders were the coolest thing to use. That's fun. But you'll see that the code is not really difficult for control over the height of this div to have dynamic control. You can define other pieces of CSS in there and it doesn't have to just be height. Your imagination is the limit. I was trying to think of a really cool CSS thing to change before this talk but I just stuck with all of the things. That's why you're asking why I was changing the color that way. So yeah, let me get back to presentation mode. So editor styles as I mentioned earlier. So these are important I believe because your editor's experience is a little different than the front end. And we keep saying WYSIWYG like what you see is what you get and you're gonna see this content rendered exactly in the editor as it's gonna be on the front end. That's not always true because sometimes you need buttons available to your users to change content like images. Maybe there's an overlay that says edit image and you click on it and it does something. Well that edit image button is on the page and you have to factor it in with your CSS. Maybe it sits in a Z index of higher than the image and it has to overlay but it could also push content around. So your WYSIWYG experience what you need to do in some cases is define the editor CSS to adjust to look like the final product. And what's nice about that is it's separated. There's two files editor.css and style.css. And style.css is your global CSS. Think of this as what is important on the front end what is important on the back end. That purple is still gonna be shared on the back end and the front end. So this style sheet should be applied to both. So yeah, you can get really crazy with it and you can start building cool style sheets. Some useful React methods as I mentioned earlier there's two states or there's a few states there's the validation state but I don't wanna get into that cause that gets confusing. But we got the edit method and the save method, right? And the edit method is where we are building our data. Save method is what we are sending to the database. I know I said that earlier but I wanna say again. So component did update another one that's interesting because what this does is it watches for changes. With the playlist block we had an interesting problem where there's a function called initialized playlist in WordPress currently. And what that does is it says, all right, take all those IDs and do all this crazy media element stuff to then create HTML of this player that has a bunch of audio files. Now let's say I was in my editor view and I clicked a check box to not show the artist names. Well the editor didn't know that it needed to update again cause it needed to re-render, right? So component did update watches for changes within the block. And what it does is anytime there's a change it triggers whatever's contained within that method. And that's really nice because then you can do real-time updates while you're turning the slider or whatever it is. But that's for if you're using things like PHP because there's like a disconnect there. That initialized playlist function was actually PHP that we had to trigger. So this was allowing us to do that. And component did mount is good for initializing data. That's just when the block's added in. It's kind of a method that you can hook into. And that's what's cool about React is that you can read the React documents and find all these really cool things that are happening in the background that you can hook into like focusing or when you hover over something. Like there's ways to identify when a user has done that. And it makes it really easy to do that where you don't have to start writing JavaScript from scratch. And I honestly don't, I would not say I'm a well-versed JavaScript developer but I can still create blocks easily. And that's the important thing is the React framework allows us to use those components in a way that you don't have to be a crazy developer to do things. And that's what's exciting because that gives our users that were less inclined to write HTML, they might be okay with doing something like this if you're just copying and pasting functions from components. So I think that's really exciting. Question, question? Yes. This thing updates directly. So I get that it updates the editing experience. Is it also updating the front? It is not. So it's what you're doing in the edit method is you're building your data, right? And then once it's finally done, that's when the publish button, that's where it's hooked into in the process. The functionality of publish is still the same. Yes, absolutely, absolutely. Okay, earlier today somewhere in another session, I got the impression they were doing the updates actually live and I thought that's really good. Well there's a save, it saves. Autosave will draft or save your revisions and things like that. So all of the safeguards are still there in WordPress. So you're not going to accidentally publish data. If anything, you should be more confident now that you're building and seeing the content change in real time. But we're not talking about rollback, are we? I'm sorry? We're talking about sort of taking a netted session and saying there's an autosave and if you don't, if you didn't save, you can't roll back step by step, right? You can, there's a, there's a. You can. Yeah, I believe there's a. That's the ultimate thing then with autosave. Undo, redo. Step by step rollback and you can undo to the point that you want to resume. Yeah. I think the point you're making is was it's saving the state and I can see the back end as like a step back. Yes, yes. It's saving it in the back end. It's not, I think what you're saying is it's not, as you make changes, it's not saving to the database. Yeah. It's being rendered by a PH, whatever user it is you want. If I close the laptop in the middle of editing a post that didn't save it to the post, because it's in my browser. Back up in steps as opposed to, it's the whole session or nothing. Okay. Routing back on the editor itself. Right. So when you re-save, a rollback means you go one save back, two saves back, three saves back. I think I was able to do that before. I bundled my blog post one time and I was able to trace it back and no. Yeah. I don't think any of that core functionality is changing. That's still going to be, it's just that. That complements the auto save perfectly. Yes, and there's little things that need to be fixed in Gutenberg. Like there's race conditions between auto saves, and let's say you upload an image. Auto save may get in the middle of that. So far we haven't seen anything big happen from that, but that is an issue that we're looking into. Because everything, like the auto save needs to know not to do an auto save while you're doing certain actions, like uploading images. Because uploading images kind of have to wait for those to actually upload and finish and return back and say, okay, you can use this image now. So yeah, that's another part of it that works for you. A lot of errors, are you sure you want to leave this site even though you know you've updated that a lot? I think maybe with custom fields. So you've actually saved it and sent it to the database, but for some reason the interface things you haven't. I keep getting that pop up. Oh, interesting. But I can't remember though if the last version of Gutenberg fixed that. I think new versions have fixed it. We are in a very stable place now. Your hand has been up for a while, I don't want it to be tired. Yeah, so ES6, yeah. So think of, the JavaScript is being used to then generate the markup at the end, right? The markup being the HTML in the end that pushes out to the database. So the JavaScript doesn't need to have to do anything server-side. Everything is client-side that it needs to process and determine how to save. So you shouldn't need, there shouldn't be any, I'll put it this way, there shouldn't be any server dependencies for Gutenberg. I'd be more worried about older computers that are using old browsers than I would worry about server configurations. Your hand was up. Yeah, is that still firing to the database even when it's in a reserve area or is it just holding it in the browser? It's doing it the exact same way. So we're still saving post content on an ID key basis, right? Like ID three is tied to this post with this content. Yes, yes, yes, but not on the published post in the edit, in the revisions and all of that. So that is where the data is being fed. But we're not changing, we're not adding new tables, we're not doing anything like that. If we added new tables and things like that, imagine at scale with enterprise. So the browser crashes, you lost whatever that session was. Not entirely, because you have a draft. The draft saves your progress, so. Hit the database. Right, I'm talking about the publish, different than save and this kind of front field. Your draft state is of that average. Okay, so. That's what the database, but it goes in. Yeah, so here's a post that I'm writing right now. It's called, this is saved draft. And let's just leave the page and leave there. You'll see that it's still saved as a draft and I can continue on and edit just as I was earlier. So it's saving the draft, it's not published and it's not conflicting with, let's say I do publish it. Now this is published, I'm not too sure the behavior. So what's funny is I've been working on Gutenberg for years now, but I haven't been able to create content because I've been so in the code. But I believe that if I start making changes here, it'll save my draft and I can go back. I believe so, I'm not 100% sure, but I would imagine, I did not give it time to actually trigger the autosave. So I guess that was also a factor. But yeah, I'd be interested to look into that. And if you do find that that's not working, please file an issue. Well, there, autosave. It just did it, yeah. So it should, if I leave, it should have only those two paragraphs now. That's funny, it's a different speed. Now I guess not, oh yeah, there's an autosave. View the autosave and then you can restore the autosave and then you've got your content back. Yeah, so there's like I said, there's safeguards for everything in WordPress and we're not changing those safeguards, we're not abandoning them, we're just adapting our editor to the new new new. Yes. A second part of the question related to ES6. That's all only admin if somebody who's not computing on the browser, there's no ES6 necessarily involved in the site. Yeah, so it'd be a React that takes over in all of that. So React is kind of what parses and makes things happen on the browser side. It's called ES5, so it's just fine. ES5 is also fine and that's one great thing about the Create Gutenblock toolkit is that ES5 or ES6 are both acceptable ways to write your block. So you're not forced to use one or the other. And yes. No, no, it does not because what we're doing is we're generating the markup, right? So we're trying to aggregate all of these crazy dynamic things to final markup that's saved to the database and that markup is HTML that every browser knows how to read. Yes. Yes. So when you hit the app, no requirement on your actual server to like do anything we want. A nice way to illustrate it is. A local machine. Yes. And then the HTML is parsed later on. So remember the attributes? Yeah, well yes, but well in the editor and then it's passed down into this. So imagine that when you go to edit a post, it's a blank slate and then what it says is give me all of the content and if there's a bunch of blocks, let me parse through them and repopulate this JavaScript editor based on these attributes and pre-populate all of the settings. So imagine that setting where I had the purple. It'll pre-populate the purple and now I'm editing in the edit state. And let's say I change that to blue. The JavaScript changes that to blue and it says the final markup's now blue and you save it, it pushes that out to the database but that's only HTML. So everything is client side. You had a question next? Yes. So React framework. Yes. So the REST API heavily depends on, or it heavily depends on the REST API because, no, no, no. So they're two separate things. REST API is more so that you can consume data or use like webhooks to change data or change information, whatever it is. But the React framework is just a JavaScript framework so that we can have a more component-based approach to building things. So you're not building vanilla JavaScript every single time you wanna have a checkbox, like those sorts of things. Yeah, and the REST API is, that was actually part of the reason why we got the REST API, right? So that now we have a way for modern JavaScript frameworks to talk to WordPress. Look at Calypso. Calypso was just a bunch of REST hooks that it was talking to in changing settings for whatever your defined site was. And that's what this editor is actually doing. There are some blocks that depend on the REST API because what they need to do, like the categories block. Category says query, give me all the list of categories and let's use those IDs and give me back data based on those so then I can make a list of them. And the React component knows what to do with that, with that data that it returns back. Yeah, and yes. So let me just see if I understood this. What's going into the page table is a combination of HTML and front-end stuff encoded in HTML comments, is that? Yeah, so let's look at a post that I made earlier today that is a little longer. What is this one? Yeah, so I'm gonna zoom in on this. So you look at here, these are those invisible comments I was telling you about. These are stripped out in the front-end. And if there is any dynamic, or if there are any dynamic things that need to happen, it does that on the front-end, strips away those comments and applies whatever is important to them to the market. And majority of the time, these are not important to the front-end. These are more important to the back-end. So the back-end knows update the view of the editor based on these IDs to give me a gallery and create a gallery block and then now I can edit that. So what it's doing is it's saying, give me the published post and recreate all of those blocks for me when I click the edit button. And then now you can edit that and then it saves it, so it pushes. So it consumes and then pushes back out when you need to save. So there's two interpreters for the entry here. When it goes to the front-end, all those comments are stripped out. When it goes to the admin side, they are interpreted in some way and turn into Gutenberg blocks. Exactly, exactly. Couldn't have said it better myself. That's exactly what's happening. Yes. And that's the thing is I think there's a lot of hidden great things in Gutenberg that are coming to light. Like the inner blocks thing I was showing you earlier, that is amazing. That means I could make an entire block that is a layout and tell my content creators where they're allowed to click. The rest of it can be static content that they can't change. So you can get into some really dynamic layouts but you can lock content and keep your editors from getting, I don't know, a design itch and wanting to start getting crazy with it. You know? Yes. I think everyone's kind of like, well, where does this fit in with Page Builders? Page Builders was just like, it gave your editors everything. Yeah. They could like, show the video in a column that they've decided and where it's like, something like Advanced Custom Fields was like, all kind of ugly. It was a job. The world I'm looking forward to is imagine blocks that are capability-based, right? So imagine me going to a page that a marketer had gone through and said, this is our blog post about this event that we're having. We need to have this ad here, here, and here, but I need you to work on content here, here, and here. Imagine that person that should not be able to change the marketer's content going into the page and being able to not be able to click on the things the marketer created but write the content in the space that is available to them. Actually, you can have them edit a screen that only shows the things that they were editing because who cares about the rest? You didn't call those blocks because they're not part of his blog. Then you can feel empowered to give your content creators the ability to edit your homepage. Imagine that, like no one should be touching the homepage without approval with design and everything like that, but if it's just one snippet of text that changes frequently, maybe it's our event for the week. Of course, you probably want that to be automatic, but imagine that you'd go in there and you'd change that event for the week, but you don't want them touching the rest of it unless they have the capability or the permissions to touch it. And that's in a future. That's in a future, though. I want to be clear. You can do it with a different field now. More than six months. I'll put it to you this way. You know that block that I just created right now? An editor cannot go in there and change that background image because that is hard-coded into that. Now imagine that I created a hard-coded layout that has this dynamic piece here and a hard-coded image here. When they go to edit the page, this hard-coded image is hard-coded. They can't change it, but they can change the content next to it. So you can already do that in a way. You can create your static pieces and then define where you want your dynamic pieces by just using the inner block component. But again, it's a new frontier. We're discovering all of these new ways to create content and it's exciting because you can do all these cool things. Yes, I think, am I good on time? How are we on time? You're running almost at it. At it? Okay, one last question. Okay, when Classic Editor opens this, what does it understand? So the Classic Editor, let's say I turn off Gutenberg, this HTML will still render in the front end. I know, but all the comments, are they gonna... I believe they stripped it out. I'm not 100% sure. I haven't done a lot of going to Classic Editor. I don't have a way to do that right now. It should render fine. Now, imagine existing content. If you have an existing post and you open it in Gutenberg, it creates a classic block with that content contained. I believe what it does is it converts it to, oh, yes, it converts it to HTML and I think it strips out the HTML. I believe so. I'm not 100% but I think it converts it to just HTML. Which you can see here if you view the code editor, that HTML there. One thing I will caution is do not change a number in there because if you do, it won't validate when you switch back and it causes issues. So there's a validator that says take what's in the database and make sure that the content doesn't ever change. So try your best to avoid this view but you can access it if you really need to see your data. Okay, well, I hope this illustrates the agility with Gutenberg. Thank you so much. Thank you.