 Okay. All right, cool. So, yeah, Brian did a great job with the overview of Gutenberg just kind of looking, peeking under the hood a little bit to see what types of, you know, functions and objects and everything are available to us to do Gutenberg development. My goal with this second half here is to provide some practical examples. So, what we're going to do is I'm going to show like a few scenarios. I'm going to, a few examples of like, let's say client ABC came to you and said, I want a Gutenberg block that does X, Y and Z. How would we build that start to finish? Like, what tool would we use to scaffold that out and provide this like build tool for us? We'll get into what, why that's necessary in a few slides here. So, what tool would we pick for that through to how do we actually code up the block so that they show up in the WordPress admin and then function like the way this client is asking for. So, we're going to do that twice. If we have enough time, we'll do it once with this static call to action block and then a second one with this dynamic block that will go reach out to the WordCamp Detroit site, the REST API endpoint to grab its latest posts and then shoot those into the page dynamically. So, anytime there's a new post published, it will always show the most recent content. So, that's what we're going to dive into here. My name is Kellen Mace. I'm there to do my intro at the beginning. So, like Brian, I won't spend too much time but I work for somebody called Web Dev Studios and my Twitter handle is there. So, at this point, I'll take a brief pause to send out my slides. So, those of you who want to follow along with the slides or if you want the code repository as well that we're going to be working on, I have all the two finished blocks that we're going to work on. I have this GitHub link right there. So, if anybody wants to go to that site, you can grab both of them right there. So, with that, we'll keep rolling. So, we'll start off with talking about those real-world code challenges I mentioned, like what those are, what they're all about. So, this is the first request that we got from our client here. So, client request number one, you're the developer, you're on deck. It's up to you to implement this, right? The client, super cool client, as a matter of fact, came to you and said, I want to spread the word about WordCamp Detroit on my site. I'd like a Gutenberg block that I can use as a call to action. It should include the option to select an image, have an area for rich text below that, and I want the whole thing to link to a URL that I choose. So, some of you, if you've been doing WordPress development for a little bit, you've probably built things like this before using tools like Advanced Custom Fields or Pick List or CMB2, things like that. And those work great in half a year. The benefit that we get doing this in Gutenberg, though, is that we get a live preview of this data. So, the user, as Brian mentioned, it's more of a true, what you see is what you get. So, instead of just filling in a few fields in Advanced Custom Fields, you know, Metabox, and then guessing at, like, I hope this looks right in the front end. Let me go check. You have to save it and then go to the front end to actually get some real feedback, right? With Gutenberg, the advantage is, as we're editing it in the admin, that little preview that the is working on, it's live updating. So, what it looks like right there will be what it looks like on the front end of the site. So, it makes for this really great editing experience. In my opinion, it's going to help WordPress to stay competitive with some of these other platforms that are coming about due to this really rich editing experience that Gutenberg is going to provide for us. So, this is the first challenge that we'll code up today. It's going to look like this. So, this is what we're going to use. So, they've chosen this white image. They plot that right there. And then below that, they get a little rich text field. So, they've, like, entered one text here, entered to create a new paragraph, entered another line here, and then behind the scenes, they'll have one other field to specify a URL. So, if anybody clicks on this banner here, this called action, it will then link them to whatever URL the client specified. So, that's the first thing we're going to build. The second one that we'll get to after that is this one. Again, super cool client. They were so impressed with you the first time. They came back again this time. They wanted you to build a dynamic block. So, we're stepping it up a little bit. We'll get into the difference between those two. Brian mentioned it, but we'll reinforce it. So, the client comes back again and said, I'd also like a block that pulls in the most recent WordCamp Detroit blog posts. Just their titles and links to them would be great. I'd like to be able to control how many posts are displayed, and my designer has provided you with an SVG that we'd like to use for the block's icon in the WordPress admin. For whatever reason, they have a certain icon. They think their team will recognize well, and they'd provide that as an SVG. So, they want that in the little Gutenberg block chooser tool. They want us to use that icon for them. So, this one's a little different, right? Because we can't just take what the user has, the values they've given us in those fields, and just save them to the database and call it done. Because this one, we want this to be dynamic and to pull in the blog post. So, if five minutes from now, WordCamp Detroit publishes a new one, any time anybody reloads that page, it's there. It's going to show that new blog for us. So, we'll see how that's even possible. So, that's what we're going to accomplish with the rest of this session, and then the next one as well. So, that second challenge then for the dynamic block, that one, the list of posts, it'll just look like this, right? So, they'll be able to control how many are shown, and it'll just be anchor tags, links to those blog posts that folks can click on this super cool client's website. All right, so where to start? If you were just tasked with this, to put these two blocks together, where would you even start, right? There are a few ways that you can do this. One is to roll your own WordPress plug-in. So, those of you who are familiar with writing a new plug-in, you could start by doing that, absolutely. But there are some challenges there because we're using all this modern JavaScript tooling. It gets pretty darn complex. We'll visit that in a minute. Next one is you can use WPCLI. That stands for command line interface. So, if you're somebody who's comfortable on the command line, there's a command to build these blocks. So, we'll see how that goes, upsides and downsides there. Last one is create this tool called create Gutenblock. It's a really great tool. We'll talk about the pros and cons of that now as well. So, go through each of those real quick here. First option I mentioned is roll your own plug-in. So, this one, in order to do this, you must be familiar with configuring Webpack and a number of NPM modules to set up the build process. If that sounds like a little foreign to you or like something you haven't done before, you're prepared to spend lots of hours doing that. It takes quite a bit to configure all this stuff and wire it up to produce the resulting JavaScript and CSS files that would be sent to the browser. There's a lot to that. Beyond that, you would also be responsible for managing those dependencies yourself going forward. So, both Webpack itself as well as any NPM modules you're using to build this whole app that we're going to talk about, if those have version updates or need to be swapped out or one of them is deprecated, it's up to you to swap those out. So, this can become a little cumbersome and requires a lot of knowledge to do that. So, I would recommend against that if you're not super comfortable. This session's almost done. I'll go through just this slide and then we'll break to talk about the winner that I'm going to propose to you, which is the last tool. Next one is WPCLI. It does have a command, WPCScaffoldBlock, that will scaffold out a block for you. There are a couple of downsides to that, though. At this point, it doesn't support modern tooling like that whole Webpack build process I was talking about. This makes writing evenly mildly complex blocks a little more cumbersome instead of writing them out so that they look like markup. You instead have to use some of the techniques Brian was talking about where you call this L function and pass it the type of element you want it to create. It doesn't even look like HTML. You just have to imagine that it's creating that after the fact. It makes things difficult. So, I would advise against that, and then you can't use the majority of pre-built React components you'll come across on the Web. Most folks who use React, which, as Brian said, is the technology underlying Gutenberg, most folks who use that use this JSX syntax I'm talking about. So, if you're abandoning that and going for the WPCL-I route and not doing anything extra like the tooling and stuff we talked about, you're not going to be able to use any of their libraries. So, what we'll do instead, what I'll recommend to you is using this create-goot-and-block tool. So, I'll break now. We'll break now and then we'll talk about the perks, why we've chosen that tool, and then proceed with actually spinning up a newer press point and using this and then building our blocks from there. Our two example blocks from Super Cool Client. The first one was our static one for the call to action, that they have a few fields to customize, and then that second dynamic one where they'll be able to reach out to the WordCamp Detroit site and then generate a list of blog posts. And that one will be, you know, update every time there's a page reload. It'll grab the data fresh. So, we'll break for that and then I'll meet you back here in a few. Okay. Hello, everybody. Welcome back. Is anybody joining us now that wasn't in the previous session? Yeah, okay. Cool. I'll do a little five-second recap then what we're doing today. So, this morning, Brian Richards, my companion here was kind enough to do like an intro to Gutenberg, like some of the underlying tech and functions and stuff like that. And for the second half of the presentation here, we're trying to do some practical examples. So, we'll do some live coding of like, here's how to build a few Gutenberg blocks start to finish. If you were asked to do this today, how would you even do that start to finish? So, that's what I'll be addressing. So, for our real-world code challenges, we had super cool client come to us and said that they want one call to action block that's going to look something like this when we're done. They can choose, select an image, some text, and then URL to link to. Then they came back. They were so impressed with us from that first block. They came back and said, I'd also like a block that pulls in the most recent WordCamp Detroit blog posts. So, we're going to create a second block that looks like this. It just outputs the posts from WordCamp Detroit. And this is always dynamic data. So, if WordCamp Detroit five minutes from now publishes a new blog post, anytime anybody hits this page, it'll pull in that new post. So, we'll take a look at how to do both of those. In the previous session, I talked about how do you even get started then building these Gutenberg blocks. And the answer is you need some kind of WordPress plug-in to provide those. So, our options are a roll your own plug-in, which requires a lot of knowledge for how to configure Webpack and a number of MPM modules and be prepared to spend hours and hours doing that. Another one is to use WPCLI, but out of the box it doesn't come with that modern tooling either. So, the solution I was recommending is using this tool called Create Gutenblock. It's similar to... If anybody is familiar with Create React app, if you've ever dabbled in React, it was painful for a while building anything in React because you had to do this whole tooling setup I'm talking about. You had to do this all yourself. It was very cumbersome. So, the engineers at Facebook created this library that's a single dependency called Create React app. So, if you run that one command, it will create a new React app for you and it manages all the dependencies that your app requires on are kind of hidden behind the scenes and all you have to worry about is that one dependency. So, it makes it super easy and you have nothing to manage. When Gutenberg hit the scene, this guy, Ahmad Owase, who's a WordPress core contributor, really active in the community, he was inspired by Create React app and creates a similar tool called Create Gutenblock. The idea is the same. It only has a single NPM dependency. So, you don't have to worry about setting up this super complicated build process. This developer toolkit does all that for you. So, I really recommend it. This is what we're using at my company. We have to do this for our internal Gutenberg block plugin that we've built. So, what it does is it configures Webpack, Babel, ESNext, ESLint for linting, React, SAS, and so on all for you so you can get started building blocks right away. Instead of configuring how all of those things work by yourself. And I have the link there on GitHub as well. Before we proceed, also I should mention, if you're in the first session, if you want to follow along with the slides right here, I just tweeted a link to the slides as well as this GitHub repo where you can see the finished blocks. So, they called the action block and then also that recent blog post one. They're both in that repo. So, if you just go to twitter.com and you can find Mace. You can find both of those. Alright, so with that, this is our chosen tool then so what I'm going to recommend to you. So, with our next phase of the presentation here we'll talk about how do you do that then? Once you've chosen your tool, how do you create a new plugin using Create GutenBlock. So, this is a little cover next here. Alright, so first one here is to create your new plugin. So, if you go to the Create GutenBlock GitHub page by there it'll tell you how to install that tool. It's really easy. There's only like one or two lines on the command line that you would need to run to get that installed. Once you've done that though then you're ready to actually create a new WordPress plugin. Have it scaffold out a new plugin for you. So, first before we do anything build anything on top of Gutenberg I would recommend having Gutenberg itself. Probably a good idea. So, if you don't have that already on your WordPress site I would just clone that down. You can do this two ways. From the WordPress.org plugins repo you can in your WordPress install you can go to add new and then add the Gutenberg plugin. Or, if you're comfortable with get and the command line you can run this command to clone it down. I recommend this method though because if you get the one from WordPress.org it doesn't include all of the source files. And those will become really handy. If you're going to be serious about building Gutenberg blocks you'll want to look into this plugin with all kinds of examples. All kinds of pre-written blocks. So, you can look at those and see how the core team does it and then kind of emulate that in your blocks. It's super helpful. So, I'd recommend doing it this way and not getting it from data or again just so you have all the original source files for all those blocks. Alright, so once you have that we can create the new plugin in your plugins folder. So, whatever WordPress site you want to get started on you just run this one command right here. NPX create a Gutenberg and then give it some kind of name. So, for us we're going to do WCDET blocks. Alright, and then next one just run this command on the command line CD and then the name of that new block just to go into that new folder that we've created. Alright, so at this point I'll start doing some of the live coding. Live demos always go great as you know. So, if things break I apologize. I'll try not to let that happen as best as I can. Alright, cool. So, here's my local site as WordCamp Detroit site and this is where we're going to scaffold out a new plugin and build our blocks. Alright, so on the command line I've done all I've done so far is just what I mentioned on the previous slide where I ran that NPX create Gutenberg block and I gave it a name. I get some output here it says you know creating and then the directory is called that and then all done. Go build some Gutenberg blocks it says. And then add a few recommendations at the end that this create Gutenberg tool outputs it says get started sorry, the screen is a little cut off isn't it? It says get started. We suggest that you begin by typing and then CD the name of that folder so go into that folder and then NPM start. Let me get this where we can see it. There we go. Okay. Alright, so we'll do what it's suggesting. We'll do CD into that directory and then NPM start. Alright, so here I am I'm inside of my newly created plugin that create Gutenblock has scaffolded out so now I want to run NPM start it'll start the build process so look for any file changes whenever I make any changes it'll run webpack again turn all of my React and JSX and ES next all these crazy terms it'll take all of that and turn it into the JavaScript file that gets sent to the browser and shows up there. So here it is it says it was compiled successfully the first time and now it's watching for changes so from here on out any changes that I make it'll continue building that so if you want to see exactly like what we're even talking about here what that create Gutenblock thing has done for us this is what my site looks like right now so if I go into that particular plugin that we just created this is what it does for us here so there's one file sorry I had pulled up our finished example but not the new example that we're going to build out both will be imported alright cool back on track now alright so this is what that create Gutenblock has created for us it gives you this plugin .php which is very very simplistic you'll recognize this if you ever built a WordPress plugin just our usual headers on top there and it just requires this init file that kicks off the rest of the plugin if we look at init then it's a source init this is that file that it calls right here that it requires if you look in here it's calling in queue block assets and it's calling this file that is so these are the block assets for both the front end and back end so here's a CSS file that's used in both places and this one says in queue block assets for the back end editor only so this is only needed in the WordPress admin and we're just loading up the JavaScript files right here and the CSS file as well so that's it for init so what this tool does for you is it takes everything inside of the source folder right here any blocks that you may create here it'll take all of that code it'll bundle it up and it'll produce three files in the end that it puts into this dist folder distans for like distributable files or the files that will be distributed to the browser so what it does for us is in the end it just creates these three files that we send to our WordPress site since blocks.build.js editor.build.js and then style.build.js so two of those are used only in WordPress admin because you only need them as you're editing the file and then any that are needed on the front end would be in the this style CSS file is included on the front end as well for any styling that block needs alright so that's what the tool is going to do for us it's going to create anything we build we create in source it's going to ultimately create these three files and it's going to listen for any changes so like I said any changes we make to things in source it'll detect that it'll build these new files and then spit them out right there so if we just reload the page we'll see our changes right away alright so with that said let's keep truckin so we've done this so far we've created our new plugin and we've moved into that directory and taken a little look around to see what's there next year there's a few housekeeping customization things I recommend so for whatever reason this framework names the main plugin the main file plugin.php which you've been around the WordPress space for a while like the best standard practice is usually to give it the same name you know as the plugin plugin folder so that's what I like to do so we'll do WCDET blocks I'd recommend doing that instead of just like plugin.php so I re-nated to that next one add a check for the core Gutenberg plugin if Gutenberg is not active then display an admin error message and deactivate our plugin that's something that this framework doesn't do out of the box either as I mentioned here it just requires that file right away without even knowing if Gutenberg is even active yet so that's something I would recommend adding as well I had some code we can paste in to do that so we'll spend too much time on this but we're just saying when the plugins get loaded we're going to call this function right here it will check if the register block type function exists if it does not then we're going to display an admin notice right here that says Gutenberg blocks requires that the Gutenberg plugin is activated and then we're going to deactivate our plugin since it has Gutenberg as a hard dependency right it can't work without it if that's not true though if this code doesn't run because that function does exist then it will just proceed on to require the file that we need that we need to load up the plugin alright so I'll just grab all of this and paste it into our new plugin plugin that we have right here so instead of just the require I would recommend pasting this in so we'll save that now let's give that a test in our browser so I'll go to the admin let's try this out we'll go to the plugins page so here's the core Gutenberg plugin select this I'll try to deactivate that and then I'll try to activate ours this is the new plugin we created there and it shouldn't let me so I get this message here it says required please install it so I'll do it in the reverse order then if I activate Gutenberg and now I try it's over the last oh WDS you're right dang it the live demo is going swell for the sake of time we will not do that so that's in the GitHub repo for the correct way there for now we'll just leave it like that the other housekeeping items I had I would recommend doing we've already taken the tour so we know what these two folders are here I would create a blocks folder inside of source since we plan on creating more than one block with this with this tool what it does is inside of source right here it just has the example block living right there but this can get a little confusing if you plan to add if you need any other directories so for my companies plugin that we use for Guten blocks if we look inside of source right here we have blocks we've nested all of our blocks, we have components which are some things that are shared by a few of the blocks we have a sass folder with some global style stuff in there template tag if you start dumping all your blocks right here you don't really have any room to have any other directories like that I would recommend nesting at one level more deeply so inside of source here I would create a new folder and call it blocks and then just this example block that the plugin provides to us we can put that inside of there instead alright so yeah we just did this create a new blocks folder and then put the example block inside of that after that point we'll need to make one change let me see inside of that example block it comes with a block.js file that one I would recommend changing to index.js and I'll show you why here so here's the example block you can see the name that it comes with is block.js but that's kind of non-standard if you look inside of Gutenberg the main file for every for every Gutenberg block is named index.js not block.js and that makes it easier when you actually import them you see this file blocks.js this is how Webpack knows where to look for all of your blocks right here so see how we had to go down to the file right here we had to say block.js if you use index as a file name they don't even need any of this you can just say import block and that's it in our case though because we nested at one level more deeply we would have to say blocks and then block but again you don't need that like index.js you just need to get it off if you've chosen to call it index so we'll do that as well so I'll save that and I didn't mention either that as this tool is running it will report out on any errors that occur so here's one right here so can't resolve oh I typed block block instead of blocks block there we go save that thank you that's what I forgot index.js there we go okay we compiled successfully so that means we went to look inside of blocks here and then further inside of that block and we didn't give it any file name it's going to assume oh you want index that's the main one so this is what was actually loaded up alright so that was it for just like how I would recommend customizing this tool right here so from here on out we'll get into the the good stuff how to actually build this stuff so two commands you would need to be aware of one we already are running right now it just listens for changes and rebuilds the the plugin there's a slightly different one the npm run build and that's to build a production code so I think that just like minifies it and does a few things that you would want for production but not necessarily want for development so those are the two commands to be aware of right now we're just running the first one alright so the naming convention I recommend if you're going to use this this tool to scaffold out like a new plugin and create a new block this is what I've come up with for like a good naming convention here so we are talking about index.js that's the only file that's required since that's where the block is actually registered and WordPress can work with it beyond that though you can have any of these others that are needed so I recommend doing like editor.scss scss for styles for the backend only icon.js if it has an sbg icon if you remember one of our requests from the client said they did have a custom icon so we'll need to do that render.php if this is a dynamic function that we need to render every time to be to be different like our second block we'll build we need some kind of php file that has a callback function whenever this block is output this is what determines what gets rendered on the page and lastly style.css styles for the front and back end so all of these are like how it's done in the core of Gutenberg plugin except rendered.php they do it a different way but for our purposes like I think this is a good naming convention so we'll stick with that so how to create a static block so before we move on to this let's just take one look at that example plugin that ships with this so if you recall like blocks we created that directory and we moved this example block that comes with create block there let's take a quick look at that so do I have all the correct things activated finally there now I think I do okay and we will rename our function here to make it more clear we'll do give it a better name so it's a little more recognizable but we should be good to go with our with our blocks here alright so I'll go to posts and then add new and we'll take a look so I'll take example block hang on I'll draw an npm install come on so Gutenberg is not active and I'm getting the arabesset at the top so let me fix that real quick because we'll need that to proceed wise to forever I've already npm installed I'll have to do the build it it's working earlier today of course now it's decided this out we'll do we're going to get rid of goot bear with me one sec sorry try to grab the version for wordpress.org instead this is the one I said won't have all those bundled blocks inside of source reference this but we'll see if we can use it just for now to get this working that's looking good add new we're in business the core Gutenberg plugin I had wasn't building for some reason so I just grabbed another copy of it we'll keep rolling here we'll say example block so you're probably familiar with this if you've messed around with Gutenberg at all this is just the chooser where you can search for and click on whatever block you're interested in so we'll take a look at this and see this cgb block this is the example that comes with this create Gutenblock tool you can see right here I get this green background div it says hello from the back end I'll click publish on that we'll take a look on the front end to see what this looks like let me see save it as a draft publish there it goes now it's published so on the front end you'll notice it's different it says hello from the front end so we'll look at what controls those blocks just as one basic example alright so we'll take a look at this pre-built block right here before we do anything else so here it is the block that comes with this lets look at the index js file this is the one I said is the main file the only one that's required to tell WordPress here's a new block this is what it looks like here so you can see in this block importing the other style sheets it's a style and editor this is all you have to do webpack does all the rest it knows what to do with each of those files and where to put them which style sheet to include them in all you have to do is a single import statement if you have any that you want to include next we're grabbing some objects some things off of objects that we need on the global wp object Brian mentioned that in his talk so in this case we need this underscore underscore for any translations what we'll do and we need the register block type function to do just that to register a block alright and then here's that example block the one we're just looking at here this is how it works kind of behind the scenes here so you have to give it a title so this one this is the current title you can get a new example block title and that will appear as that in the admin for the icon you can use one of the dash icons if you follow this link all you need to do is provide the slug for that alternatively you can give it an sbg we'll see how to do that in a little bit category determines where it shows up in the admin so when I go here to add a new block see how they're suggested blocks, embeds, shared and so on blocks is just like the common area here see how it says common so that just controls where you want this block to show up in that chooser so in this case we've chosen common search for if anybody search for this or this or this whatever in that chooser our block would pop up those are the things that might be named so all those are pretty straight forward next we'll get into the two functional components that actually power this block so the first one is edit it says this edit function describes the structure of your block in the context of the editor meaning the WordPress admin alright so you see what's happening here it receives this argument called props and then on that object it has something called class name this is something Gutenberg gives you right off the bat you can pass in other props if you want but right off the bat it gives you a few of them one is the class name for the current block so we have this container div with that we're saying hello from the back end and just a link here so this is what you can think of this function as defining what's going to get rendered in the WordPress admin what the editor is going to see here if we go down to the next one though the save function here you can think of this one as what's going to be rendered on the front end of the site publicly for people to actually see this is also what gets saved in the WordPress database so the process is whatever is defined in the save function here when somebody like configures their block and then hits publish what the WordPress will do is it will take everything in the save function and it will save that to the database inside of the post content for this particular post then when this post gets rendered on the front end of the site all that markup is there in the database so that's what will appear on the front end of the site so for this function that's what it's all about and in the style sheets it just defines that one of these should be red, the other should be green so you can kind of see the difference when one is showing up and the other isn't this block is pretty darn simple and it doesn't have any attributes usually right here after keywords you would specify the attributes and we'll see what that's all about next Brian mentioned attributes and what those are used for but since this block is so simple and has like zero nothing to configure it doesn't actually need any attributes alright so that's it for the example block it's a good a good kind of starting point to get a feel for these let's create a new one though we'll dive into creating our static block so this is that call to action we talked about, remember Super Cool Client asked us to create that one so what we'll do first is inside of our blocks folder, we'll create a new folder for our block and then we'll give it an index.js file too let's get started with that so inside of blocks here, I'll close our example one and we'll create a new one a new folder, we'll call it first okay empty try to remember what I named it in my finished example okay and inside of that we'll do a new index.js file alright and to get started here, I have a little boilerplate code that we'll use so I don't waste too much time typing this stuff out alright so what I've typed in here is just pretty bare bones it just calls in those two things we mentioned for translations and then for registering the block type it has these fields but they're all pretty you know pretty much blank as you can see and then an edit and a save function and all it does for us is give us that container div with the class name that's it, it's up to us to fill in the rest here so what should the first step be then if we want to create this block I think we should register it and give it a name fill out this section first and then we'll dive into talking about the rest of the stuff there so give me just a second and I'll find my call to action let's rename it so it matches my final final example here okay so call to action is there and then alright here's the finished version here so what we'll do first is I'll steal these things just so you don't have to watch me retype all of them there we go so we have our name space here as Brian mentioned to group together our blocks is WCDET the block in particular is called call to action giving it a name giving it one of those dash icons so it'll be like a megaphone icon I'm saying it's just a common type of block so that's where it'll appear in the admin and then the other keywords like other things I think people might search for I just said CTA you could choose some other ones if you want there so I've completed all that now we can get into the edit and save functionality as well as the attributes let's start with attributes I think that might be a good one so we'll start with just the message first I think it might be good to go back to what our block actually looks like alright so we'll start with this right here this little rich text there that's what I'm calling the message we'll start with how to build that first and then we'll move on to the image and the URL ones as well alright so first we need this attributes object and then we need this messages object inside of it so I'll put that in our new block that we're building over here these are all low keywords alright and then you might close and break so here we are we're telling WordPress here are our attributes we're going to have one called message this could have been named anything but we're choosing to name it message and then this type source and select are some of the things that Brian went over earlier some of these are kind of hard to understand at first but the more you work with it you do get familiar with it what we're saying here is let me back up a second here well WordPress has to do in the WordPress admin somebody is Ryan Gutenberg what it has to do in order to get things ready for them to start editing is it has to grab the markup from the database and pull some data out of it so what happens is this save functionality function right here let's say we have a rich text area down there like we have a few paragraph tags that exist in there but WordPress will do when the WordPress admin first loads up it will grab this the markup right here from the database and it will try to pull out certain things from that and it will use that to populate our attributes so we're saying we're telling it here's where you should look to get those messages you should look in something that has a class of message right and this is similar if you're used to writing CSS this is similar to just CSS selectors so that would have been pound message if it was an ID or whatever so telling WordPress look at that particular element we're telling it the source the thing we want to capture are its children so like all those paragraph tags inside of that and then type has to be array because we're gathering more than one thing there are other types of other children but we'll get to those for now for this particular one the message this is what it would need to look like and there's documentation for for how to do that online as well our time is running thin so let's talk through I'm going to paste in these other ones and we'll talk through them and then save so here's where I ended up with this particular particular block oh thank you awesome thank you so here's where I ended up with this black the props that come into it that I'm pulling off are these ones so class name attributes are right here WordPress will pass those into you there's this set attributes function it gives you as well that does just that whenever you call that you're telling it I want to set my attributes up here to something new based on some new data the user has entered or whatever else it also gives you this is selected Boolean to tell whether the current block is in focus or not you can choose to show things based on that then I'm taking the attributes and pulling even more things out of that I'm still finding this is like ES6 so I would just read up on writing that but just know that out of this attributes object we're pulling out these three things there's an image ID image URL and image alt so that would be in our called action block that would be this top image right here and then let's see let's go to the render function here or the return function this is what actually should be shown in the WordPress admin here so here's our wrapper so class name in the container right here and then we're saying if there is an image if there's no image ID if the user hasn't chosen that and again I'm skipping ahead so this would be assumed at this point we've already included the attributes for the image if that has not been chosen then we're going to show this so there's this media upload component that Gutenberg has inside of it the core plugin they're saying whenever that's selected whenever an image is selected we're going to call this function right here that will update our attributes you give it a type and the value is whatever the ID is that was chosen for the last time an image was chosen that's we're going to pass in for the value right here so that will get updated anytime there's a new value and then this render you can just look into media upload and kind of see like and pass things into it but just know that this is the standard way to select an image let me paste in all this stuff alright so if there's no image has been selected we're going to show this media upload button right here on the other hand if an image has been chosen then we're going to show that image at the top right here here's my image tag and I'm pulling in the URL for the chosen image the alt text and so on we're going to say if the current block is selected then we want to go ahead and show this button that says remove image so if somebody clicks on the block and there's already an image there we'll look at a button that says remove image so if they click that they'll be able to remove it below that I have a rich text field this is what we started to build a minute ago before we jumped ahead this says enter a call to action message here you can see the value we're saying out of that attributes object pull out the message from that and that's going to be the value of this rich text thing if the user ever changes that if they type in a new message then we're calling that set attributes function that you're going to price to us and you're sending it the new message so it will update the attributes and if you're familiar with React it handles all the re-rendering of things for you all you have to do is make sure the attributes up there are in the state you want them in if that makes sense if something's updated in the attributes React will call this edit function right here it'll re-run everything in there so anything that was true before but now isn't anymore it'll change that to either show or not show whatever you told it to do it'll handle all that logic if you're used to writing jQuery for instance in WordPress context this is kind of a departure from that this is writing things in more of a declarative way so you just tell React hey if at any point this block is selected when it renders, display all this stuff or if at any point there isn't an image display this thing and then all you have to do is make sure that you are updating the image or the rich text or whatever it is, those attributes just update them when they should be updated like when the user enters a new value as long as you've done that it will run through this it'll display the right thing on the screen at any given time alright so if it's selected we're going to show this inspector controls thing in the side bar that says that you can enter a call to action URL let's see what this looks like I'll save that I'll save that really quick and we have to include it alright so here's call to action here's our index that just just a sec here okay we threw it I knew I was in trouble with the live demos let's see I thought I'd just move my finished block there alright I hope this actually works so here's a new post, I'll add a new one so here's that call to action if you're interested but it's all said and done this is what it looks like there's our megaphone, there's our title we gave it so you click on that this is what it looks like so you can click here enter the call to action message let me see I had that saved here field values here we'll grab all this that'll be our message for our upload image we'll grab the logo and for the URL here we'll link to this event alright so that was memory of my code I said everything I was rendering here like the image, the remove button or whatever else but there was one section that said inspector controls what that does is Gutenberg any fields you put inside of the inspector control it puts over here inside of this this side panel right here so this URL I thought would be a good spot for that since there's not really a nice natural place for it to go here so the user would just like paste in their URL right here so if they do all that and they hit publish you can go ahead and view this on the front end and it looks like that so this background right here is just hard coded so you could have yet another image upload field for them to choose a background if you wanted in addition to the foreground image to make it easy I just left that out but here's that which text that we had typed in right here and if you hover over you can see it's linking to the right place so this is our static block right here and then our save function is more simplified as you can see because we don't need all those fields for like adding the image removing the image, the inspector controls all that stuff we don't need any of that so you can see it's a little bit thinner here it's saved to the database Wordpress will say it'll wrap everything and it did first of all but then in that link right so we have the whole thing ends up getting linked we have our image at the top and a message at the bottom here and these values that it plugs in like the URL, the alt text, the message, whatever else those ultimately come from those attributes alright so in your code if you again you can think of it as when when Wordpress like loads this block up for somebody to edit it it's taking all this stuff from the database and it's pulling the attributes out of that so what it'll do it'll look for this class name see how the class name is image right here it'll look for the dot image selector if you told it to do so and it'll pull out the source attribute here and the alt attribute grab those values and put those into the attributes and then it'll only change them if the user sets them to something else likewise it'll look for the message class and it'll pull out the children out of that remember that was the one we set to children because it can be like multiple paragraphs so if you look at our attributes right here it corresponds with that so here's message right you're trying to look in this class for the children and it's an array of those children for the link URL look in the dot link that we just saw a minute ago the attribute is source that we're looking for and it's one of its attributes so that's what's going to pull out and put into link URL and again it's up to you to just update these whenever necessary using that set attributes function like this right so when anybody changes this field we're saying take the new message and call set attributes and pass in that new message so that gets updated then alright cool so we're out of time and we did one out of my two blocks so I apologize for that if you're curious about the other one though um I can show you that real briefly so here's the first one and then the second one was going to be work camp detroit latest post, none of the client wanted a special icon so here's the icon that we've included here that's another file it's just icon.js right there if you choose that because it looks like you get a list of the posts and these you know recognize here that's not from this site this site is workcampdetroit.test it's pulling in the actual post from the workcampdetroit site and then displaying them here the user gets this little range control so watch this on the fly they can change the number you can see in between there's a little like fetching word for moment momentarily while it grabs those posts and then it pops them into view so they can like dial this in to like the number of posts if they're interested and get a live preview of what this really will look like right here and then they hit update they can view this post on the front end and here are those list of posts right here they would link out to the workcampdetroit site right that one if you have more time you can look at the github repo to see how that's done that one because you can't you can imagine for this block because it can look different every time it's loaded up right so this isn't something we can save to the database so we had to do in that what we have to do in that case is it's an index.js remember I said the the edit functionality right here this one's more complex because it has internal state so you can look at this later if you want but inside the edit component here we're doing a lot of stuff but look at the save component there isn't one we're passing null right here and the reason is this is the markup that's saved to the database in our case there's none here all we're doing is saving one single thing to the attributes which is number of posts and the type is number that's it so if you looked in the database you'd see one single little inline comment for this block that you said the user picked a number of posts and it was six that's all it knows it doesn't know anything else and then it's up to us to define a callback in PHP then so what you can do in PHP is say hey for the latest posts it's render callback function that you should use whenever it's being output on the page is this thing it's called render latest posts block and that's this function here right so it will try to get the number of posts add this fetch latest posts function here which will try to fetch them so if you're interested in that it uses wp remote get to like reach out to the word camp site and retrieve those posts back and then it does JSON decode on them to turn them into something that PHP can easily work with if that was successful then if we were able to get those posts that array of posts right here then we're outputting this markup right here so it's saying for each of those posts that we grabbed as post it's outputting a paragraph and then an anchor tag inside with that posts link and then that posts title inside of the link so that's what ultimately results in this right here so if I were to update this and say save now when I reload this you can see that showing up every time so that's the benefit of having that callback method in PHP is you can have this look different on every page load if that's ever necessary for you it was not though you can go ahead and use that save function and save things to the database if you don't need this dynamic function out here alright I'm a little over time so I think that was about it there's a ton to cover with Guru and Guru but hopefully from that you at least got a sense of what tool might be a good one to look at for that plugin that helps you like scaffold out your first block and the difference between a static one like that call to action one we chose you know where a few options to customize and then we're saving that to the database for WordPress to pull those attributes out and then we save them all that difference between that and a dynamic one like the one we showed here right where it gets the render callback is in PHP instead and it can pull in different things every time it gets rendered like that so hopefully that was helpful to you there's lots of resources especially in Brian's slides you have a lot of helpful resources that you can check out if you want to dive into this stuff yourself so thank you so much for listening I really appreciate it everybody