 My plug-in I can use quickly to see if there's something. Yeah. Okay. Yeah. I mean, we introduced templates at World Camp US, I think, last time. And since then, we added template locking support for nesting. So you'll be able to declare your whole page. So here I have a template here and just a bunch of fields. I'll create a new one for clarity. This is a plug-in to allow you to create templates with the UI. But you can define those on your own with code or whatever you like. Just to show an example, so page template. Let's say it's for post-type pages. I forbid adding and removing blocks. I can give it a title. It's a text. And maybe an image. Okay. Increase the size of it. Yes. Let's see. I don't know the short code. It's fine. Okay. Let's say this is all, let's add a price field, for example, a number, save my template. If I go to create a new page, now the page is filled with placeholders and the content is great or just fills like the titles, like my awesome book, for example, or choose an image and add a price. And you see the insertor is hidden. You cannot add other blocks. You cannot move the blocks. You just fill the blanks, basically. So, yeah. Yeah. That's also pretty flexible and why we haven't really locked individual blocks down. Because you can control everything from the template level, and it's more flexible for people this way. There might be some things that we still need to do at the block level, but that's still in flux. But already with this, you can, like the other locking mechanism is that I think the one that you can insert, but you cannot move. I can change the template to show that. I forbid adding and removing, so I can move blocks. And now if I go to the page, I cannot add the blocks, but I can move them around. So, yeah, your choice. Okay. Let's move on to start with the examples and take it from there. Okay. So, before we start, we have some material. If you want to get set up, we have people to help you. You need, like, a WordPress install. If you don't have one, you can go to Poopy Life, and you create one on fly, like I can create. And you install here. It takes some seconds. It will be ready. There you go. And we can go to the plugins, install Gutenberg, of course. Once you are done with that, we have this repository you can go to, GitHub, you know, we add Gutenberg dash extensibility dash workshop. I can zoom in maybe a little bit. I can zoom to the toolbar. And so, this repository is a plugin, basically. You can download it here, download zip, and upload it to your WordPress install. Once you have that, we can, like, work together with this repository. We have several examples here. We can follow along. And you can create your own blocks as well. So who need help with set up? We have a bunch of people around. Okay. I'm going to just move forward. So the first thing we are going to do, I hope it's, I can zoom in. We are going to create some blocks. And to do so, we are going to start from an empty file, basically. And so the idea of creating a block is, like Matias said, we need to create the, we need to define some generic information about the block, like its title, its description. I can create a simple object here. I'm going to use ES file. Okay. My block is a JavaScript object. It has a title. So let's give it a title. Let's call it notice block, a description, my awesome notice, and a category. So for categories, you choose, we have, like, a list of categories available. You choose one of them. I'm going to just go with common, common blocks. And you can add also keywords. These are helpful if someone searches the insertor to find your block easily. So I can add, I don't know, a message alert or something. And like Matias said, we need to define, to build a block, we need to define two representations of the block. One for the front end, so how to save the block to post content. And one how to edit it in the editor. So the first one is save. So let's, how do we want our notice to show up on the front end? It's just, so it's a function. It receives some props. We are, we are not going to use those at the moment, but we will see those later. And it returns basically a representation of the block in HTML. And to do so, we have this helper called createElement. Or if you know GSX, you can replace createElement with GSX. I'm going to just grab it. So it's available on the global WP variable.element, that createElement. So I grabbed it in this variable, and I will return the representation of my notice, which is going to be a div. And it's content like my awesome notice. That's about it for the save. And to start, we are going to start static, static, which means the representation is the same on the front end and then on the edit screen. And we are, we are not going to edit anything. It's just a static block that shows this notice. Okay, that's how I, yeah. Just to add, as you continue with the writing that one, the something that you might see in a few times is a concept of dynamic and static blocks. Generally, the distinction is a static block is block that's saving the final output as HTML, and that's going to be rendered by WordPress exactly as it was saved. And that includes like paragraphs, images, the quotes, like almost every basic formatting element. Dynamic blocks are the equivalent of short codes. Those need to be processed by the server at the time of rendering the page. The most clear example in core right now is the latest post block, because the latest posts are dynamically generated at the time of rendering. That block doesn't save HTML at the moment. It just saves an HTML comment. And if the server then process that and generates the final output. But there's an important distinction that, again, there's not a hard line separating static and dynamic blocks. You can take any dynamic block and define static content for it. And this is very powerful because you can think one of the biggest problems with short codes is that if you're not in a context where the server could process the short code, you end up just with the text gibberish that very often pops up in either emails or RSS clients that you just see the actual text short code. The way blocks work is that you can use the save function to specify a fallback for a dynamic block. So if you have like a latest categories block, you can have a fallback that maybe it's just a URL to your category page. So when if the server cannot process and generate the list of categories, you will get a URL to a permalink for the categories. So that's a flexible tool for the developer to make sure that the blocks work as best as possible in multiple contexts. So if you can imagine like a contact form, if you're seeing that posting an email client or a RSS reader, you won't be able to generate the form. But maybe you can specify a fallback that's like a contact me button that sends you to a page to have the contact form. So if WordPress is able to render the contact form, that will be fine. If it's not able to do that, it will show the fallback HTML that's specifying the save function. And on the other hand, if you have a static block like image, you can turn it into a dynamic block by registering a server render callback. So you can do that with any block right now. If you basically register the render callback on the server and you get all the attributes for the block and you can manipulate that on the server. So it's the definition between static and dynamic is really whether you're hooking a render callback function on the server or not, yeah. Should I continue? Okay, so now we have the block object defined. We have to register this block object in WordPress. And to do so, we have this function available called register block type. You can access it in the block's global variable. So register block type. I give it a name. So I'm going to wordcamp eu-slash-notice. It needs a namespace and I can close these. And so the first parameter is the name of the block. And the second is the block config I just created. Okay. So I have this bunch of JavaScript code. I can grab it and go to Gutenberg. I open the console and just pass it here. Yeah, I will go to another page and disable my template plugin. I guess I still have templates. So I'm going to just disable my templates plugin before going forward. Okay, let's go to the post. Create a new post. And I'm going to pass my block I just created. And now, if I go to the insertor, I can search for notice. This is the block I just created. So here it's available. It shows the editor representation here. And if I save and I go to the front end, it shows here the front end representation of this same block, which is the exact same thing for now. So that's the first step, creating just static blocks. The next step, I think in the way we create block, we have to ask ourselves some questions. But the next step, we have our static representation on the front end. And so we should ask ourselves, what do we want to make editable in this block? What do we want to allow the user to edit? So the first thing we will allow the user to edit is the content, also the text inside the notice. So my awesome notice, we don't want this hard coded in our save function. We want to use what we call attributes. So attributes are the variables that change the properties of the block. So instead of showing just a string, I'm going to use the props parameter I have here and grab the attributes. I'm going to call it content. So what I did now, the save function will return the content attribute instead of just the static text. And the next step is to define what's this attribute and where is it saved? So we have this attribute property on the block object. We can add here. The name of my attribute is content. It's type is an array. That's an array because the representation of HTML in Gutenberg is an array of elements. So each time we need to represent HTML in the editor, we use an array. The source, we are going to use what we call attribute matchers, so the children of something. So I'm going to continue. It will become clearer. Selector is the div. So the children of the div is my content attribute. It will be parsed automatically into the content once we load these blocks. So that's the definition of my content attributes. The last thing I want to do is I want to be able to edit this attribute in the editor. So I'm going to create blocks. Gutenberg has this building component we can reuse and together and compose to build our edit interface. So one of them is rich text component. I'm going to grab this rich text component. It's available in wpeditor.richText. And the rich text component is an editor representation of a formatted HTML. So it allows us, it's like a small tiny MTE where we can write HTML and add bold italic and stuff like that. So to create this content attribute, I'm going to use this rich text. So instead of static string we had in the editor representation, I'm going to use the rich text component, give it the value which is the content attribute. And if I change this value, I need to tell Gutenberg that the user changed the value of the rich text and you need to save it to the content attribute. So I am going to write a small function here, which is an event handler, basically, update content. It receives the new value as parameter and it will call this specific prop we have called, yes. OK, I am seeing that some people are trying to build things. This sample, you can just use the playground file and follow from there. You don't need to build anything. This is ready to use, so you don't need to open the terminal or try anything. And also, if you are having any problems following, you can just raise your hand and we will try to. Sorry. Line to it. Yes, thank you. So I built this event handler, which we will call each time on change happened. So each time the user changes the value, we need to save it to the content attribute. I think we are done with this. So I will just copy this thing again. I will refresh the page because my block is already there and I'll register again. Oh, it's already registered. I guess my plugin is installed, so that's why. I'm going to just end register it quickly for the demo and register block type. And you notice, oh, boom. You cannot do that. That's changed its name to avoid having to and register it, like notice 2. OK, now it's registered. And if I search for notice, I will have two blocks. Which one is the editable one? I got it. So now I can edit the content of my notice block. I can add any formatting I want, save the post. And now when I preview, my second block is not saved yet for some reason. Oh, the other tab. Oh, here it goes. So I saved my content and it's shown properly on the front end. So that's for editing stuff inside the content editor. But as Mattias said, we can add components to edit the block attributes on the inspector control or on the toolbar. We'll see in the next step how to do that. So what I'm going to do is add a class name to this block. And this class name will change depending on the status of the notice. Maybe it's success, danger, or warning, or something like that. So I will use another attribute I will have to define, which is called, let's say, type or status. Status of the notice. I define this attribute. It's just a string. That's all I need to do. Status, sorry. Status is just a string. And now I need to provide how to edit this value on the editor. To do so, we said we are going to add control to the inspector, which is the sidebar of the block. So we grab this special component provided by Gutenberg. It's called inspector controls. It's also available in the editor global variables. And we are going to grab another one, which is select control, I think. Correct me if I have errors. OK, so it's in components. So we are going to the edit representation of our block. And we can just add here inspector controls to add inspector controls to the sidebar. And the children of this component is going to be a select box where we are going to choose if it's like a warning success or something like that. We are going to choose the value of the new attribute to add the status attribute. So I'm going to use the select box, select control component. It has some properties we need to define. So its value, basically, is our status property, status attribute, sorry. And when we change its value, we need an event handler to change the status update status. And I'm going to just copy this function because it's very similar. So update status, new value. And this time, I update the status attribute. And we need to, it's a select control. So it's a select box. We need to provide it some options, I guess. So options is like, each option needs a label and a value. So the label default, you default. Let's duplicate this. And now danger, warning, warning, and success. I think I'm all set. Looks like I don't have any error. Just the name again because it's already there. Let's get back to our console. Now I can register my new block which is called notice3. Let's add something to differentiate and enter, it looks like I have syntax error somewhere. Let's see what Prettier said. Here you go. Rich text, where is the rich text? OK. Let's try again. OK, it worked. Now we have the notice, no, refreshed. Notice3. And if we open the inspector control, you'll say that we can choose the status here, like the select box we just used. We can enter some content, use the status warning, for example. And if we save, if we go to the code editor to check the HTML, we have this class name, warning added. So we can style it differently by enqueuing a new style to the front end. So all these blocks I'm building right now, they are available on the plugin I just we shared with you. So each step is a separate plugin. So for example, the one I just did is the third advanced block. We can try it here because it has the styles already enqueued so we can see the difference. Actually, it's a bit different. So if I change, I can change. With just a class name, it changed the color. And it's the same on the front end, I guess. There you go. So that's about it for static blocks for, yeah. And like Mathias said, on the next step, we are going to see dynamic blocks, how to enhance this block with callbacks on the server side to generate use dynamic data. You have something to add? No, just checking if people are having trouble following up or if everything is going well. If need some time, we can maybe go around the table and see. Yeah, let's do that. Any questions so far? We have a question here. Do you have a question? I'm looking at the third example, Advanced Static Block. And I see plaintext component control. Yes. That's something I didn't know it exists. So a few words about it, how it works. So plaintext, the exact same thing as rich text, but you cannot format. You cannot use bold, italic, and stuff. Just for the simple text, simple string. It's not HTML. The rich text is for HTML, for method content. And plaintext is for string. It's like a text area, basically. So when we have a plaintext and rich text, we don't have to manage focus for the rich text because it's the only one rich text. Managing focus, I believe in the last versions, you don't have to do anything. It just works automatically. Even if you have multiple rich text, it just moves automatically in the last versions. OK. I think so. I'll have to try that. Yeah, which has one question on the components. One of the main goals about having this, can you show on the console how the components? I mean, there are split between components and editor. But the idea is that WordPress Core would offer almost everything that you need to assemble a block so that you don't have to write any custom controls. Yes. I cannot zoom this area. Yeah, if you focus it, I think you can do common plus. It's focused. Oh, there. No, it's. I can zoom, but I cannot zoom. It's weird. Yeah, is there a menu or something? In any case, we already have a whole list of components from plain text, rich text, inspector controls, text controls, rage control, all different UI elements that you can combine. The idea is that you shouldn't have to reach out to custom React components for doing this and that you can consume most of what WordPress offers. Yes. Yes, that's a good advice. And part of that also is for like a design language that WordPress offers to users. So users have a consistent interface through which to interact with the admin. Instead of everybody inventing their own text area, you have the one that WordPress provides out of the box that hopefully provides all the functionality that a developer would need. And from a user's perspective, anytime they interact with a block that uses a text area, it's the same experience. They don't have to learn something new each time. I'll give it to you in a moment. And I would have to re-scale my. I just wanted to show like just in the topic of like one of the main things you have to think about when creating a block is the sort of the level of granularity that you're going for. If you can imagine like a contact form block, you could create a single block for the whole contact form. Or you can create like individual blocks for each field like the name, the email, the send button. And that will give users the ability to reorder the form fields, for example. But it would also make other things more complex. So and that's where the whole concept of child blocks comes in is that you can set some relationships between these blocks so you can offer. I have a quick example here from like a to-do block. And if we think of a to-do block, we can think of just the list of tasks. And you can think, OK, we should create a block that handles multiple lists at once. But you can also think of the to-do block as, OK, what if we create a block per to-do item? This is what that's doing. This is just, again, a rich text field. The only thing is I'm adding like a custom element and a custom status so you can check the to-do. But it's a single block. And what I've defined is that when you press enter, it creates another block of the same type. So you can end up with a to-do list item. But the advantage is that you get some Gutenberg controls for free because now you can reorder the items just by using the Gutenberg arrows. You can even select multiple elements and move them all together. So this is when you think about how you should structure a block. You should think, how much do I need to build myself and how much can Gutenberg provide? And there are enough solutions for almost every case. You could also say that there's value in having all of these. I mean, another benefit is that it simplifies the state management because if we check the, let me go to the code editor, here it's much simpler to keep track of what task item is checked because it's just a single value. I don't have to keep an array of all the list items and update that as the user manipulates that. So I get some like a little state management for free. And just in the topic of edit and save differences, like the interface for the to-do block is, so the edit interface has all these extra elements so that you can, the rich text component, but the same thing, it's just an emoji here for the checked and not checked. And that means that the user has the ability to interact here in a very rich environment. But if I switch to here like another context that's not rendering anything complicated, it can still display something that's useful. So that's kind of the difference between the saves and edit. Here I have something that still communicates the same. It's not interactive because in this context, you cannot interact, but it displays something that resembles the semantic structure. Yes, I'm going to switch away. Oh, it's fine. Okay, now let's see dynamic blocks. I'm not going to live code this one, but I will explain like it's just a small example. So the only differences we had with the previous block is that we are going to use this function called width select, which is like basically, Gutenberg is providing different APIs to ease building blocks. And one of them is how to access data from WordPress. And the data module is used to access data from WordPress. So width select, you can wrap any component in width select and grab content. And we have a lot of selectors to like grab functions to call to grab content. For example, here I'm using get entity records. So I'm wrapping the entire edit function of my block with width select. And I'm saying, okay, I want to grab the lists of posts, the last posts in my WordPress. So I grab get entity record, the entity type is post type and the post type is post, so these are just parameters. So what this will do is that it will feed the component that is wrapped with props, with informations. And in this case, it will feed it with the posts prop, which is like the list of posts available in WordPress. This is async. So the posts can be loaded the first time it's empty. And when it's being loaded, it re-renders with the full list of posts. So in this example here, I'm gonna just use var. I'm grabbing the first post of these lists. There are other ways of doing it, just for demo purpose. Now I'm just grabbing post list, the zero element. So it's the first post. And the representation of my block, I'm on edit. So the representation of my block in the editor is a div. And if the post is not loaded yet, it shows loading. And if the post is loaded, it's going to show the title of this post. So basically this dynamic block we're trying to build, it shows the last post published on my website. So each time I publish a new website, the content of this block will update itself with the new website. And so this is the editor representation. But the save representation as explained by Matthias before, we don't actually need anything because it will basically be dynamic. So it needs to be rendered on the server. But as a fallback, if we want, if in context where the server is not being executed for some reason, we can provide a default, like a fallback, like the post is not being loaded or something, depends on your dynamic block, you can provide more useful fallback HTML. In my case, I would just use returner for now. And on the server part, so until now we just saw that we can pass blocks to the console and it works. But if we want to embed blocks inside plugins and inside websites, we need to register this script we clicked and we enqueue it to WordPress. And to do so, we just use the regular functions from WordPress, like register script and enqueue script. So on any time registering some scripts, and where is it? The block. Okay, this one. But for dynamic block, we need to do something else. We need to register the block type also on the back end to say, okay, so we have this dynamic block, but when you want to render it on the front end, call this function. It's kind of similar to how shortcuts work. It's enhanced like the block with dynamic data on the server. So we register our block type. You should give it the exact same name you used for the JavaScript part. The script is just the handle of the script loading the JavaScript part. So I registered the script here. And if it needs styles, you can add style. So this block will load this style on the front end and on the editor as well. And the property called render callback is the function that will be called when this block needs to render on the front end. So I give it a function name, render dynamic block and it's defined here on the same file. So what does this function do? It just received the attributes of the block if the block has some like properties you define on the inspector on the block toolbar or anything. It received them as parameters and you can use them to render your blocks dynamically. So what I'm doing here, I'm just using regular PHP WordPress APIs like WP get recent posts. I just want one post. The post status should be published. So if I have no posts, I render no posts. And if I have a list of posts, I grab the last one and I render this div with the link to the post page. And so we can try this block. So we are done. So we just have a function on the back end and an editor presentation on the front end. We can try this block. It's called dynamic. Here it is. So in the editor, it uses the edit function we defined to show the latest post. And if I save my post and I preview it, it's here. It's not working for some reason. Or maybe my last post has an empty title. I guess it is the case. This may be my last post, so I'm gonna give it my title publish if I, okay. Now it's showing the title of the last post. That's about it for dynamic blocks. There's nothing more to know. Just render callback on the back end. It received attributes. You can use them if you have some attributes. In my example, I don't have what I can define. Any attributes like I did for the status, for example, for the notice block. And it will be automatically feeded to these dynamic blocks on the server. And you can use this attribute to render your HTML on the server. Should we move to the next block? Let's just add one small point. I think you might have noticed, as he was going through the example, both the JavaScript part and the PHP part had very similar logic as far as what they were doing. They were showing the latest post. And so a lot of people, their initial reaction might be, why do I have to recreate the same thing in JavaScript and in PHP? That's kind of a waste of my time. So there is one solution to that. There is a component. We were talking about all these components that WordPress provides. There was a component that was built called server side render, which does something of a, it would provide a preview of what that would look like on the front end. Now the main caveat to that would be, again, ask yourself, is that the ideal experience through which a user should be editing your block for simple examples or an example like this may be? And so in that case, if you're saying to yourself, I'm just recreating the same thing, you don't necessarily have to do that. You could leverage this component that does that for you automatically. No, I did before moving forward with the other things that were planned. Do you have, I don't know, from the people that have built blocks or if you have tried to follow along, any rough edges or questions or problems or ideas you tried and you didn't know how to do or stuff like that that you want to bring up? We have a question there. Hi, my name is Lawrence. Thank you for all your brilliant work so far. And I have a question you showed to do, example, from a data registration perspective, I was wondering how you would suggest using the checked and checked status of all your to-do items to be used in different contexts? Yeah, for like other places in your website or extracting data from WordPress into other different parts, you have the data registered. I want to use it somewhere else. That's the next example. Yes, okay. I'll quickly talk about the to-do one. Either to-do one was registering the attribute as like the normal way in which you register Gutenberg attributes, which means it's going to be added to the HTML comment and that means that it's accessible to the main parsing mechanism that we have on the server. So if you register a render callback for that block or you just want to check the status of any to-dos, you will get that attribute as a checked Boolean. So that's already built in into the comment mechanism because it's not, I'm not keeping the state of the checked in item in the HTML itself, but as a separate attribute. You get access to that from anywhere. And you can, from that you can build like, you can build even another block that just has, keeps track of how many items have been completed just by looking at those attributes. Yeah. If you want to explain that further. Okay. So the next example is exactly like an answer to this question because we can save attributes as post meta, meta if we want. So how do we do so? In the attributes definition, like we saw earlier, there's this source, we can give it meta. So it means this attribute called description will be saved as a meta. And you give it the name of the meta to use. Like in this example, it's called short description. This is the name of the custom fields used. Okay. So and then in the edits interface, you use it exactly like any other attributes. Like in this particular example, I have, I'm using a plain text. So like a text area to update this description. And that's about it. And my block doesn't save anything to HTML. It just renders anything. It will save just this description as a meta. The last thing you need to do if you use meta attributes is you have to register your meta on the server. Because like how Gutenberg works, it uses the REST API and to be able to access and update this meta, we have to register it on the server. So we call register meta. We provide the meta name. We use short description. Show in REST should be true. And single in general, it's true. It means we need to save one value and you give it a type. So that's... I guess that's the main difference with the to-do blog is that this is saving a meta for the whole post. And the to-do blog is keeping, the to-do item is keeping state for each individual to-do item. So in that case, you're probably better using the comment attributes so that you can still query each individual blog. Like we have server functions for doing that. So you can get each individual blog and get the attribute for each individual blog. But the point is that again, you have a lot of flexibility around how you save attributes because some blogs can be saving them in HTML. They can be saving them as a structured data in the HTML comment or you can be saving it in meta or you could also potentially be saving it in other custom post types if you want to... If you build that loop. The main question is what's the best way for each particular case. And that depends on the kind of experience and the kind of optimizations you want to provide to users. Like I've seen other to-do blogs build slightly different with not a single items but as a full array of all the elements and that's much more a better candidate for being saved in meta because you're just keeping the state of the whole post and the to-do list available in the whole post. But if you want the granularity of each individual items, the HTML comment is likely a much better way to handle that. So we can try this blog quickly. Like it's called MetaBlog and I can put like this is a description. If I save it and I go to the core editor, I don't have anything actually just a reference to the blog on the HTML but if I update the page, the data is still there because it's meta. So it's saved. That's all I have for the blog's examples. I wonder if we should do a break before the plug-ins. Yeah, let's do a little break. I don't really think we have much time for a break if we want to fit in a whole other section. Well, okay, can we just, can we do like five minutes for reels? And all right, cool, five minutes for real and then we'll come back and do the rest. Yeah, and again, if you have further questions or things you want to share that you have been playing with, please find one of us and ping us about it. Okay, with whatever we did so far, we are going pretty fast, I think. Yeah, because the QA took quite longer. Yeah, please interrupt at any point because a lot of these things would only make sense when we can hear like your questions or concerns, otherwise it's like a ton of information that it's hard to make sense of. Yeah, so the last part is how to make plugins inside plugins for the editor. So far you saw how to work with blocks which is inside the posting area, but there are also some ways to extend functionality inside. So let me show some existing examples. You also have them if you install the plugin we provided, it's already there. So one of the ways of extending block is first you saw this sidebar thing when you can edit and see document and block settings and we also provide a way to code your own sidebar if you need to provide special functionality for your users. And by design it also provides the spinning features which allows you to, here in the header, it allows you to have a shortcut for your application so the user can turn it on and off, sub to them, by default it's on. But this is quite the most complicated one. There are also other extension points. If you go to the document sidebar, there are many plugins at the moment that are using that to add their own thing. So this my post starting to info is a way of adding things to this area. So all the old plugins could migrate and use the same approach. And let's take, and let's try to do the same. Basically what I will do, a bit differently, I will use built-in editor inside WordPress for plugins. And so you just go there just to show you that you don't need any build tools, anything you just use whatever you know today. If you know basics of JavaScript, then it's perfectly fine. Also let me switch to this view. So the thing I use can select this plugin if you have installed. And we have this playground provided, I removed the block sections because it's already done. And if you look at this code, it's quite similar to what you saw before. So first of all we also provide global element for plugins if I remove that one because you are inside this. Oh, that doesn't work now. So you still have this auto-compete feature provided by the core. So it's pretty nice, you don't need to look. As Raiad mentioned, everything we provide to build the blocks is already exposed. So plugins, element, editor, those are namespace you can look at. If you type wp. You can see all the global variables that are out there which is pretty handy if you don't have documentation before you, you can just start exploring that way and see what's that. And it's pretty awesome when you are using components because then you can see all the things that are used to build core editor inside and you can also use themself. So everything you see on this page, you just need to find it somehow and to make, you can use it yourself when you are building your things. So the register plugin also contains this first parameter which is namespace. It's a bit different than the one you saw for blocks because this one contains slash inside doesn't have to contain the differences because when you register block it's new. The name needs to be unique with the plugin. Only the namespace needs to be unique because as you see this soon, you can define more than one extension points inside the plugin. But let's start with something very simple. We also will need this create element thing which is basic stuff to do everything. But we need to pull in another variable which is inside edit post which is a way of accessing the editor for the post. And if you start and type plugin, there is this plugin post status info. A special component allows you to bring your own piece of HTML into the section I showed you before. So we just need to bring it in, assign it to variable. In fact, you can use it directly inside. This is just the conversion we are using for a brevity. You don't want to type this thing. We should move it, use it more than once. And again, we are doing the same thing as Riot did. So having element, providing some props which we don't need at all. And we just provide some text. See, I don't want you. The last thing we need to do is just need update the file, go back in here, refresh the page, and you can see WCU hello and boom, we are done. It's super simple to do it. It's just we provide all the building blocks. I hope that we will have time so that you could explain how it works behind the scenes. So that's one point. Another one is like when publishing, many plugins use this space to add some information. At the moment, it's quite static. So, I mean, you can provide some functionality. This is one of the existing extension points, this panel. We plan to have also the way to change the publish button on this step. So you could do some additional, like do you really want? I don't know. We discovered that this post-hams has some wrong syntax or something. Do you want us to fix it or whatever else? You can provide additional functionality, but let's just recreate whatever is in here. So again, before we start, because we are using now more than one element in here, we need special component that is exposed inside a element namespace. It's called fragment. What it does, it basically, instead of wrapping it with div, I should do that with HTML, you need to have a special component that allows you to have multiple childrens. So what I need to do now is to wrap this thing and it should basically work the same, but now it allows me to bring in another component next to it. As you can see, I'm still using the same plugin, but it will dispatch those elements in different places. So you don't really need to worry too much about what's happening behind the scenes and knowing the IDs and stuff like this. You look into HTML. You just need to know what kind of components do I need to use? Again, all of them are prefixed with plugin for making life easier. And let's start with prepabish panel and bringing in, it has some properties. I think I have these links here that might be quite hard to recreate, but they are all in Gutenberg Handbook. They are linked there. So we will share them after the workshop so you can check the documentations in details. But by default, you don't need to provide anything. The only thing you need to do is provide text, update the file and hope it works. Yep, it works. You can see the text in here, but it's not that nice. That's why we hold habits, switching to editor. So we can provide props and let me check it because I don't remember. So there are three props, class name, which we skip. There is title and initial open. Showup one is pretty nice. We will show it soon. Let's make it false. And let's open it again. As you can see now, you have panel which has collapsed. You can also close it and open it. If I go back and change the flag to true and refresh the page and go in here, try publish, it's open. So that gives you some ideas how those kind of plug-ins works. So the more components you know and know how it works, they provide very sensible defaults, how they should work. And your role is just to provide right attributes to make sure it renders the way you want. So this gives you a lot of flexibility. Also, just to show you an example how it works for the post-publish panel, the only difference is that it's different plug-in. I mean different component, oh no. As you can see, it's over there. So are there any questions so far for what I showed you because we have maybe 20 minutes. Can someone, okay. So the brilliancy of WordPress in general is that we can make it whatever we want to. So by default, WordPress registers both types and taxonomies, et cetera, but we can also unregister them. How does it count for elements in the plug-in panels, for example? Do you have an unregistered plug-in and could you provide an example? Yes, so maybe a answer. So you can unregister all blocks that are registered. That's one way. You can also unregister every plug-in that were registered by other users. There are also hooks that were ported from PHP to JavaScript and they allow you to modify both plug-ins which doesn't make so far that much sense, but for blocks it makes a lot of sense. So all the core blocks and plug-in blocks, you can use hooks to update them. And regarding those slots, so far you can only add them. We are looking into having, like, when you go to this document settings, in a way it's how to remove panels from them. It's doable, but we need some, you know, make sure that we provide a viable way to do it. And also maybe on the design part, if you want to have a user give those choice on, I don't know, maybe it's really unclear so far, but we are looking into it, definitely. Is there any chaos we can remove from this? Yeah, I mean, any parts, like. You can always say if you... If there are many that if the theme doesn't support it, like the regular ways that things work in WordPress, if you don't support the feature image, or the post type doesn't support and excerpt, like those kind of things. I think one good point before we, like the way the plug-in API is being modeled in the editor is to sort of provide as much flexibility as possible but try to move away a bit from one thing that WordPress has done before, which is have location-based hooks, basically, towards something that's a bit more functional oriented. So instead of just registering things in, like, bottom area of something, you would be using components that actually describe the intention that you have because that would allow WordPress to evolve the UI, knowing that the semantic relationship between the plugins and the interface is clearer if you have something like the post-published flow and you are registering a plugin for that area, and maybe in the future the post-published flow is no longer a sidebar. It becomes a model or a separate screen. We can still take that plug-in over and continue there. If we just name things like bottom of something, that might change when it's no longer the bottom, and it prevents the design progress of WordPress from being able to iterate on the interface because now there are dependencies with location-based hooks. And that leads a bit into how declaring interfaces and the mechanism in which, because they are very similar, like some of the things we saw in the block interface when you define a toolbar or the block inspectors, you're defining all of that in your single block interface. You're not really concerned. You're not looking at where is the panel or where is the sidebar and finding the DOM element for that and then showing something there. In your block, you're just saying, I'm displaying this element for my block and then I'm using this component inside the block that's called block inspector. I'm using this component that's toolbar and it's up to Gutenberg to figure out how those things are going to be placed, when they are going to be shown. We have more flexibility even on other devices, like mobile is handling some things differently, but the semantic relationship remains so the plug-in author doesn't have to be concerned about knowing exactly where he needs to display something because it's using a more semantic way of declaring those UIs. So, yeah, I mean, to explain on that a little bit more on the technical side, we use this concept called slot and fill. So when you create markup or you create these elements, I think it's natural for people to think, oh, I'm creating HTML and HTML obviously is shown in the DOM sort of in place. And as we've mentioned a few times throughout the course of this workshop, we're pressed, as part of this project, we provide a number of components and components are this interface by which the person who's developing a block or a plug-in doesn't necessarily need to be so concerned with what is generated. It's a more friendly, meaningful way to express what they are trying to do. And so one way that we do that, obviously, is just take some props of a component and map them to DOM attributes directly. But it can go much further than that even so far as where things appear on the page. So in the blocks example, we showed you inspector control and one neat thing about that is even though if you put a div or something like that in a block, it shows in the post content when you put inspector control, it showed up in the sidebar, which is maybe unexpected because that's not in the same place in the DOM or on the page. And that's exactly what we mean by slot and fill. We can leverage features of React, specifically one called portals to allow a developer to use these components to express their intent even if the output of that is put somewhere else on the page. So to explain what a slot and a fill is, WordPress and the editor interface, we can define a number of what we call slots and put those somewhere on the page. So inspector that could be in the sidebar, all of these plug-in extension points, those are slots. And they may not have anything in them by default because their whole intention, their whole reason for being is to be occupied by zero or more fills. And as a block author, I can use the inspector control, which under the hood is just a fill. But you don't need to know that really. You just say I have these inspector controls and anything I put in there is magically portaled to the sidebar. And we've taken that idea and applied it to an extreme in the plug-ins case, because a plug-in is one unit, but it may need to integrate with several points in the application. So instead of having to implement this part, this part, this part separately, you have that one plug-in root component that says, okay, for the pre-publish, this is what I wanna show for the post status, this is what I wanna show. And it's a nice, simple interface. It looks like HTML, but these components hide the fact that it's really redirecting that output to a different part on the page. Yeah, and the biggest shift here, like the paradigm shift that you have is that you should stop thinking about, like even when you represent a block, you should not be thinking about how that's going to be translated into the DOM. You should leave that up to the software that's powering that, in which case WordPress and Gutenberg. And you should be focused on how you declare the functionality of your block. And in a way that has inherent semantic value, like the block, when you use the block inspector, you're just saying these certain settings that I'm defining here are of secondary nature, in a way. That right now, that secondary nature is being displayed in a cyber by Gutenberg. On the mobile apps, it might be displayed entirely different, but the semantic relationship is the same and it remains. So it's, on the contrary, if the way in which we allow people to display things in the cyber is that we give like a bomb hook and we say to the client, oh, find the cyber element with this ID and render this HTML there, that will immediately stop working when the, like if you're in a different context, like mobile apps or even another implementation of the editor that doesn't, or when it moves into the customizer. I don't know, like the element, the interface that contains these elements might change. It's not something that's steady in stone. But if you declare your block by using these components, you're just saying how your block should work. And it's up to the platform to figure out where these relevant tools should go. And it's also flexible in that, for instance, if you go to the ellipsis menu at the top right, and if you choose the fixed toolbar to the top, now the toolbar of each block is going to be rendered in a different place. But nothing changed from the block author perspective. This is just the UI system placing the things based on how it needs to work. And if you select another block that has like, do you have an image or something? Or add an image. So the toolbar is now contextual to the block. It's just not displayed next to the block. But it's using exactly the same thing that the block has specified. So this is very like the fixed to toolbar. It's a very simple plugin extension. And you can imagine plugins changing many things here and relying on the fact that blocks have specified how they work in a semantic way to have a, and that goes back to the question about the page builders because the page builder has access to the semantic definition of a block, they can provide a different interface and still doesn't require the block author to change anything because it's relying on these concepts. Like in another case, the H ones for the heading element are being shown in the cyber inspector. But that's again, that's a choice of the block author that's saying, I'm putting this as secondary importance to the other. And in the actual toolbar, it's a subset of the elements. It's just the H2, H3, H4. That's mainly for accessibility reasons. And the more advanced controls are in the cyber inspector. So it's really, the point is that using these components is more about the semantic relationship and it's less about where things should go. That's up to the system and that's where you should be, we should be free as a community and project to iterate on where things are being shown without requiring authors to be upgrading their blocks to follow up and catch on on those things. 10 minutes. Yeah, so we have 10 minutes left. We're gonna open up to more questions. There's one over there. Awesome, thank you very much. Is there a way to expose hooks in all the examples as someone who's building is anywhere from you to expose hooks so that eventually someone can pick up and implement those hooks and modify what I did. Yeah, you did mention hooks here. So Gutenberg does have a hooks implementation which more or less matches exactly what you would expect from the PHP implementation. The difference is that we're applying this idea of components and extending it to extensibility in a way that allows a block implementer to express the semantic meaning of controls and how they should appear in the context of a block. So it's a slightly different way to express versus a hook implementation. You can imagine if you tried to do that with a hook it wouldn't be so much declaring the interface of a block so much as hooking into the specific implementation of how it happens to appear on the page at that point in time. Where we do use hooks more extensively are for things, not so much for things like UI, but for things like data. So one example is block registration. So when you register a block, what a plugin might want to hook into that and do something, add an attribute, things like that. So we do have a hook in place that fires a filter so that a plugin author could hook into that and override anything on a block, for example. Does that help? Next, any more questions? I just want to know if Gutenberg at this moment is compatible with any of the translation plugins? Like the multi-language for a given site. I've seen some examples. In general, it should be compatible. Again, like, let me see if I, like a lot of, it depends on how they work. Like some work with short codes where you divide the content, some work with separate post types. Again, nothing is changing from like, all short codes still work. So it's more a matter of how they could be updated to be presented in a better way because you can think of, even if you mark up, if you have all the content in the multiple languages in the post content and it's just being filtered out through short codes, you could imagine having like views in Gutenberg that only shows based on which language you have selected as you are editing. So it could be, it's a, in general they should work, but they, I haven't seen anything optimized for the opportunities that this offers now. It's, then if you, even if you copy short codes and you pass it in, I don't know if I can, I mean I don't have time to show it now, but if, like we have the ability to when you pass the short code to interpret the short code that either transform it into a block or show it in the short code block itself. Every multi-language that uses that should be able to hook into that system and maybe provide an even better experience at what's possible now. Examples that deal with post type is even simpler because the separation is already there. So I haven't seen any, I think we've seen a few issues with some of them, I don't remember which one that was submitted on GitHub, but again everything should be, it's either a bug on Gutenberg or something that can be improved on the plugin side. All right, well if there's no more questions, is there anything else that the team wants to talk about or cover or mention before we jet? Cause otherwise, you know, we'll just give everybody three minutes before lunch. Tammy's nodding like, I can't tell if you're just excited about lunch or if there's something you wanna say. Okay, she's just excited about lunch, that's very legitimate. Okay, well thanks a lot for coming. As has been mentioned before, make.wordpress.org. There's Slack that we hang out in, you can ping us and ask us questions and say, we really like what you're doing or we hate what you're doing or we have this idea or whatever. You know, file issues with ideas and open pull requests and stuff with ideas if there's something you want to do that Gutenberg doesn't do. Yeah, talk to us. So thanks so much for coming. If you have any more questions, you've seen these people's faces for the past three hours, you should be able to just pull them aside in the hall and ask them questions. That's totally fair, that's why we're here. And yeah, thanks a bunch for coming and build cool blocks. Cheers.