 Good food was good Event is great so far Perfect awesome. Um Hi, I'm Niels And we present how to extend WooCommerce blocks We put up that slide Did all of you follow these instructions already do you have your Setups done. Are you still working on it? Okay, then I would say we give it another five minutes or so It's important that you go through these steps. We need to install that MPM package MPM NPX WordPress grade block which technically is some kind of boilerplate Thomas and me we created that package and it pulls it down. It has all the workshop files And then we're gonna go through all the different steps But that is if you would do that one then we can start jumping right in Then I would say let's give it another five minutes or so Perfect. So hi everyone Yeah nails already introduced us. We're gonna Go over the quick agenda. So we'll introduce ourselves talk about the motivation for this workshop Give a brief outline of what we're going to cover during it and at the end there will be time for questions answers But if anyone does have a question during anything feel free to just raise your hand at any point So to kick off, this is me. I'm Thomas. I Think about site. I think about code while I'm cycling through Merseyside. I'm a JS engineer at WooCommerce I work on the cart and check out blocks I'm from England my side business is coffee roasting So if there's any coffee fans feel free to come speak to me at the end and And I like cats more than dogs So hopefully the same enthusiasm from other people comes for that I can actually fire light aircraft. That's me in an aeroplane Someone said it looks like a car, but I assure you it is a plane and I'm a football and baseball fan Hi, and I'm Niels Also JavaScript engineer together with Robert at WooCommerce team Rubik. We create WooCommerce blocks maintain them I fight bucks between palm trees and rice fields. I live in I lived in Bali now I live in Jakarta Indonesia with my wonderful wife I'm originally from Germany. So I spent the summer usually in Europe and the winter more in where it's warm in Indonesia What else? Yeah, let's partially in Europe mainly in Asia. I develop plugins for fun. So when I'm bored. I Just develop a plug-in and I release it on web.com. I love solving Rubik's cubes the bigger the better The biggest I have is 16 by 16 by 16 which takes roughly nine hours to solve So it's a perfect one for long-haul flights And I love not tying I'm a passion sailor and I probably know around 15 nuts So if you have questions about nuts come talk to me and great to have you here at the workshop so Can't wait to get our online orders, but sometimes they come. We're not at home. So what happens then? Well, we can leave some instructions for the courier what to do if we're not in so When they arrive they can know where to leave the package what to do with it Maybe come back another day and can you quickly go back to the slide? Yeah So what you see here is if you use the checkout block the checkout block has different sections It has the shipping address the billing address the shipping methods So here you can actually see the shipping options We created two default shipping options free shipping and next day and what we gonna do in this workshop now Is the third part? I'm not at home, please and then you have that drop-down box and you can select Leave it with the neighbor place it in the shack Try to deliver it later. So so this is technically the part that we focus in this workshop now so quick outline of the project and the workshop so we'll start off by What are we commerce blocks? So nails you'd like to give a quick? Explanation of what are we commerce blocks? Yeah, so you all know Gutenberg and Gutenberg has blocks WooCommerce blocks Kind of has the same mission what we do with WooCommerce blocks is we convert all the traditional short codes To blocks we have a card block. We have a checkout block. We have a product filter block product search block so technically we create everything that currently exists as a short code and Convert it over into a block that it's that it's seamlessly integrated into the Gutenberg Eco space So what is a WooCommerce blocks extension? So as we saw in the image earlier with the If I'm not at home, it's basically it's a plug-in and it adds stuff to WooCommerce blocks So in that case that adds an inner block to a block area You can extend WooCommerce blocks in lots of ways. I'm I just gonna show you one of them today There are many other different things you can do and The main concept we're gonna cover today. So people might not be familiar with these Which is okay. So when we go through these slides some of the stuff you might think I don't know what that is. Don't worry because in the workshop we will cover it So if it's confusing now, just hold on till we get to it in the workshop and it should hopefully make sense So the first thing is the data store, which is actually part of Gutenberg. It's called WordPress data It's kind of it's built on reduct. It's a way of storing data on the client side Integration interface is a class in WooCommerce blocks and that is a way to Tell WooCommerce blocks what your extension is doing so you can use the integration interface to register your script You can extend the API to add fields add data From API requests and stuff. It's just the interface between blocks and something else and Store API is a rest API in WooCommerce blocks It is The way we interact with the server side so the blocks interact with the server side through the API which we call store API and And the main files involved today gonna go real quick through They're just pretty standard Block files if you've made Gutenberg blocks before you should be familiar with a lot of these Block.js is the main bulk of what we're building block.json defines the metadata configuration settings and stuff Edit.js is what's gonna appear in the editor if you open the checkout block in the editor The edit.js file is what's gonna render there Frontend.js is a file specific to WooCommerce blocks So actually what that does is it replaces a static block on the front end with a interactive react component So instead of just rendering html. It's gonna mount a react component there Index.js is where we register the block type options.js if you have a look at that it's gonna have An object full of options, which will appear in the drop-down menu later and then two PHP files one is for integrating with WooCommerce blocks and one is for dealing with store API. We just separated them out so it's easier to reason with and When it comes to validation so because we're using a form on the checkout We need to make sure it's valid. We have the information we expect. We have three functions. They're from the data store Set validation errors is how you add validation errors. GetValidationError will retrieve that and ClearValidationError will remove them when your form is valid Extending store API we have set extension data. That is how your front-end code can let the The request that's about to happen know what data to send Register endpoint data lets the back-end know what to expect and extend checkout schema Sorry register endpoint data is what we use to tell the store API what data to expect and Extend checkout schema is a function in our project where we actually do that work So The picture we saw earlier with the drop-down menu. We want to save this information in a few different places We want it in the checkout block when the shopper is shopping We want to keep a record of it when they see the confirmation page to know. Oh, yeah, they definitely got my shipping instructions We want it in the confirmation email to reassure the shopper. It's going to be handled and for the merchant as well so they know and We'll keep a log of it in the order page in the back-end and Can you quickly go and what we cover in this workshop is? We show you how to add the extension to the checkout block itself And we also cover the order page for the merchant in WP admin So we won't cover order confirmation page for the shopper Do we don't we know we don't know and not the order confirmation Email for the merchant and a shopper, but the workshop is structured in a way that we kind of have these gold bags So those are extra steps that you can do are they a little bit more advanced a little bit more tricky But we also have a spoiler folder where you can actually find the code snippets. We also have the Starter repo that you've all checked out. We also have the final version We will not reveal the link yet, but after the workshop you get the final version So if someone struggles you see the final outcome and last but not least All the code that you see is gpl. You know what that means Grab it for good sell it. It's your code. You can do whatever what you want to do with it. It's gpl Cool, so yeah, we'll just jump right into the workshop. Like I said any questions anyone struggles that was now we can come around and help So is everyone okay with the steps we had on at the start that everyone get them completed and is ready to ready to go Any anyone struggling? Cool So then we start with the workshop Thomas shows the steps on the computer and I gonna walk around if anyone struggles has a problem Lift your hand. I'm here to assist you to unblock you Yeah, so if everyone Has a week on my store setup. We can start by adding a product to the cart. We have a question at the back Who does sorry do you want me to open the slide again real quick the You got it you got it Feel free to take a photo of this if you if you need all good Yeah, all right cool so yeah, let's start by adding a product into our cart and We will go to the checkout block and We should see if we scroll down to the shipping options. We should see our Checkbox our select box where we can add Well, where we can select an option, but there is actually only one So let's jump in to our code. We should have The source folder the JS folder and inside that is the shipping workshop block folder and I will just quickly run through the files. We did speak about them briefly in the slides But I just want to point out two things in this file. Is it big enough for everyone who wants to go a bit bigger? Is that good? this parent attribute is quite important because When we render a block in the checkout block this parent block describes where it will be So if you notice here, we have WooCommerce checkout shipping methods block and because of that That's how it knows to render in this section So if we change this to something else it would render somewhere else and Underneath we have attributes and the important one is lock the default value of this is an object with removed true and moved true What that does is it stops the merchant from removing that block from the checkout block So what if they install this plug-in? The block is there. They don't have to add it. It gets added automatically by some Function on our end if we see a locked block it gets forcibly inserted. You can't remove it. You can't move it So that's just to remove a step for the merchant. They don't have to do extra work We edit JS everyone should be pretty familiar with this I think it's just a an editor file that's going to show up in the editor if you want to add specific settings here for the Block you can add them here in this workshop. We're not going to cover that but this is the file where you do that and Frontend.js. This is the magic function I mentioned earlier which will replace Static block with a react component Sorry, is there a question and Just one question one one one comment also worth mentioning is when you go to The block Jason you actually see that parent element here and that one tells exactly where that block appears You did that. Yeah, we did that. You also changed it You were busy Okay, sorry, I was busy. He was busy All right, so Does everyone have this in their checkout block they can see it right so we want to add some different options to this we can open options JS and If you notice here, we have a notepad And that means there's a task for you to complete in the workshop so There's a hint above which is try again another day If you want to add your own options, you can add a couple So if everyone wants to try that first they can you know spend a couple of minutes just add a few options Reload the page and they should appear here. So I'll give everyone maybe two three minutes to try this Any questions anyone needs help? Let me know After that time, I'll come up and I will add my own and then we can move on to the next step. So I Give you a little bit of time Did everyone get a chance to try adding some options? Is there anyone need help in red shirt? Do you need help? No good Cool. So yeah, I'll just quickly add some of mine and then we can move on to the next step. So We added ones with a label and then if you didn't do it this way, it's fine but this underscore underscore is a Internationalization function. So if it comes to internationalizing your plug-in, this will help it be picked up If you didn't do it, it's okay So once we've added options and we reload the page, they should appear in the drop-down menu However What if our customer if these options aren't Descriptive enough or they want to specify something else we should let them have some free text to Tell us what to do. So what we can do I actually I already added the logic for this But if we add an option Called other when we switch to that it's going to display a checkbox. So if everyone can take a second To just add one called other and the value needs to just be a string other exactly like that and Once that's in place if you reload your page and switch to other You should get a nice checkbox. So that's where text box and checkbox. So once that's there We can move on to the next step of the workshop Give everyone a couple of seconds to do that on on what story? Mm-hmm. Yeah, you can do that. So if you open block JS, there is some code at the bottom Where it basically says if the value is other then show the text area control. So you can change this if you like Okay, it's not really we just did this because adding inputs on certain criteria is kind of React knowledge. We don't really want to go over repeating that. So We coded the bits that we thought were not super relevant to the workshop, but I mean feel free to play around with stuff absolutely And then I mean after it you can you can play with this or you like So yeah, everyone had a chance to do that we good to move on. Yeah, cool. So When they choose other Well, if they choose any value we need to keep track of it. So earlier in the slides we mentioned store API and With the way the checkout works is it's not just a form that we submit to an endpoint actually the values that we've added in here The block sends an API request an Ajax request to the server So we have to Explicitly add values that we want to send to the API. So if we try to submit this now with this value It wouldn't be sent to the server because we haven't told it that we want to send this extra data So if people have Redux dev tools installed It was mentioned in the prerequisites. So it Hopefully everyone had a chance. If not, you can grab it. You can just Google Redux DevTools And It comes up. There's a Chrome version and Firefox version below So if you need to grab it, it's super quick But I just wanted to show off a Something in the store. So this is a representation of a WordPress data store, which I mentioned earlier and It just stores some data on the client side At the bottom here is something called extension data And the moment it's empty. So extension data is where we are going to add our custom information So if we go back to our code in block.js, which is where the main The main field is Thomas. Can you can you quickly go back to the browser? Yeah, there's something a little bit tricky worth mentioning Can you open this page in the editor while keeping this page open here at the same time? Yep Fantastic and now can you go to Redux again and search for the store? Yeah, that's so now you have two checkouts Super confusing what happened why are there two data stores? Well, one is the front end one is the editor if you have multiple tabs open You see multiple data stores. So that's good to keep in mind when you develop just close all the tabs Keep one tap open and you only see one data store. It's really tricky. We often debug Well, I debug for hours in the wrong data store So closing tabs. So always a good idea Thanks Nils. Yeah, so Like Nils says if you have the editor open it might be a good idea just to close it for now To make sure that we only have the the one data store Yeah, so extension data, let's try and add something to that so We open block JS There is a use effect on line 61 and There is a task in here that explains how to use set extension data To add some values there. So if you want to take some time to follow the instructions here Reload the page after each change and When you change value if you open this checkout data store in Redux DevTools, you should actually see the value update While you do that. So, yeah, I'll give everyone a few minutes to try that Again any questions? Let me know. I'll just walk around and help people Do anyone everyone get a chance to do this and check it was working. Did you see it in Redux DevTools? Yeah, all good so Yeah, this task hopefully was Was easy to follow The set extension data function is Provided to every inner block that you register with with commerce blocks So it actually comes from the props We pass checkout extension data which contains the set extension data function So using that we can use set extension data to Update the of what we actually have the API here. So let's copy that the namespace. I mentioned here is shipping workshop The key is alternate shipping instruction and The value is selected alternate shipping instruction Which is coming from the select box if you see the value here is Is that it's a react use use state? So we'll format that reload the page we see Our extension data is here. It says try again. We change And it updates. So did everyone get that working? Yeah, cool But also if you do other And we change this value It doesn't update. So underneath what we just did is another use effect which fires when you update the text box. So you want to Basically do the same here just update a different key and that is mentioned The key is mentioned in the instructions. So Just to note as well in these there's a couple of extra comments So if you do the code between the comments, that's a good place to do it The extra credit ones with the gold bag We're actually not going to cover them in the workshop due to time, but feel free at the end to Well, feel free to try but I'm not going to go over them. You can try at the end if you like So you give people a couple minutes to try doing that make sure it works in dev tools So we should have two keys. We want the alternate shipping instruction and the Other shipping value. So we should see them update at the In the in the store, they should both be there and Yeah, don't move on to this next code this next task just yet because we're going to get to that in a minute All right, so hope everyone had a chance to do that had a couple of people to help So yeah, it looks pretty similar to what we did earlier except the only thing that has changed is the value we're using and The key that we're updating So this is Other shipping value Just to mention with redux dev tools You should be looking at the state because that is representing what is stored Couple of people had action selected here and it was a little confusing because it looks very similar But an action is just like telling the state what you want to do So state is currently what's represented. So be sure that you're on this tab So if I reload here and type in other Throw it to the dog. We should see our two keys in the days of store So have other and throw it to the dog someone raised a good point if we change back from other to Try again another day We probably should clear the other shipping value. So what you can do is again, we can copy this And because this use effect only runs when the text box changes if we do it in the use effect for the select box we can Just set that to an empty string No, sorry, we want to do that if That's just going to remove other completely If the selected alternate shipping instruction is Not other then we can clear other out Oops, and then they go that's empty So that's great. Everyone okay with this? Should we move on? Oh You're okay there You want me to go up? the one above this one all right, so if they have Selected other and they don't have a value there We shouldn't let them place the order because if they've chosen other we're expecting some extra instruction so what we can use is there's another data store we have called Wc slash door slash validation so if everyone wants to open this and take a look I'll quickly explain it. It's a little confusing at first, but what I will demonstrate is If you have an error in your form, so for example here, it's telling me please enter a valid last name And if I try and proceed if I try and place my order it tells me that's not allowed and The reason it knows this is because In the data store is an entry for the shipping last name that has the message and It says hidden false the the point of this hidden value is If you join the form if you enter the form you haven't filled in your address We should the field is technically invalid because there is no Address there. However, if we just show errors immediately, it looks pretty bad You're just gonna have a screen filled with red. So we we have the errors, but they're hidden So for user experiences, it's better When you place the order This action runs it says show all validation errors that changes hidden to false and that is how They would appear It's actually up to The person displaying the error to honor that hidden value you don't have to Because you don't just get to display your errors for free. You have to explicitly add them So that's what we're gonna do in the next step. If everyone is ready to move on There is a Task below so the extra credit task like I said when I'm gonna cover that during this workshop You can ask me at the end I can give you a hint but the task below is Write some code that will use set validation errors to add an entry to the validation data store If the other shipping value is empty So the API of that function it takes one argument and that's errors and Errors is an object and as you saw here. It's just an object keyed by the field So you see here this I should mention actually validation error ID. I have defined above Just to make it easier for everyone. So you don't have to keep typing this field. So validation error ID is A constant and you can use that So validation error ID is the key The message can be whatever you like and hidden Let's leave it hidden until we submit the form So the hidden value should start off as false There's a light bulb because it's a react use effect. We want to do it when the other value changes and If we add new Things to the use effect we should also reference them in the dependencies. So don't forget to do that and there's a little Little point of finger. So if the value is not other, let's just not add the validation error So I'll give everyone some time to do this It might be a little confusing the error. So if you need help, let me know. I'll come around and and give assistance if people need it so Yeah, let's try this task out and then we can go over it together afterwards. Oh, no one off. Sorry So there's some questions from people about this validation error, so if it displays in the data store That is not enough To get the error to show so the validation data store is just where we store it so because This is a custom block. We're rendering We'll come as blocks can't actually Do anything inside your block because this is just all your code So what you have to do is you have to explicitly Select that error from the data store and render it yourself wherever you like There's nothing in blocks that will pick it out and show it for you So the next step is actually going to be to do that. So is everyone ready to move on? Seems good. Any anyone struggling with the last steps? No, cool So if we scroll up around Because I think everyone codes differently people leave extra line breaks and stuff around line 38 there should be a use select function like this and You select is a hook Offered by WordPress data and what that does is it lets you grab something from a data store And they have things called selectors which are predefined functions, which will pull specific items from a data store so The one we're interested in is on the WC store validation data store and We have a selector mentioned called get validation error. So if you would call The get validation error selector on this store object It will return you a specific validation error and the parameter to that is the ID so Mine because I didn't code it yet actually but because my last name is invalid This is the ID that's this is the value that will be returned if I specifically ask for the shipping last name validation error so I will Quickly add my My set validation errors code. So if anyone struggled with the last step you can follow along here Hopefully we can get it working so set validation errors. This is that called an action. So that's A way we get data into the data store using actions and the API it takes an object and If you some people actually wrote it like this they were a validation error ID like so and The problem with this is because it's this is an object. This is This is a literal property name So what you need to do is put this in square brackets and if that's in square brackets What that will do is it will reference the variable and I added above So when it enters the data store the key will be this Because you can't have hyphens in property names unless you put them in square brackets So that's what this is. That's what that's doing and mention. We will say hidden should be true We oh Yeah, we've got to update the dependencies to so I will ask excellent to do that and The thing it added was set validation errors because that's a new function that we're using in the effect So it's got to be referenced if that function changes. We should rerun the effect if I reload immediately, oh, yeah Yeah, it Depends if that function is defined if that function is what you expect it to be When the effect runs. Yeah, however, if it comes from something like ace like an async function It takes a while for the function to be returned. I don't know. Maybe it depends on something asynchronous That could be a use case for using it in the effect in this case It probably will work because I think it is synchronous, but for good practice. I would add it Yeah, I think so for most cases. There are some cases where you shouldn't Because if you for example update the data store with a new validation error But for some reason you're referencing the validation error When you update it that use effect will kick off again and you'll get to an infinite loop so there are some cases where you shouldn't but for For things like functions coming from data stores, you can add it So what I wanted to show was we have our error here and that's because the The text box is empty The other code was if the The next task to do was to update the code so that it will use clear validation error if We have changed away from other or if we've added a value So I don't know did everyone scroll down and get chance to do this Yeah, I wanted that cool. So what we can do so if the selected alternate shipping instruction is not other We can clear validation error and we will clear the validation error ID and if the other shipping value is not an empty string or actually I saw a better idea was Not Yeah, I think that's good We will clear the validation error and then we should return early because we don't want to run set validation errors If this is true So I reload the page because I haven't selected other. There's no error in the store if I choose other Why are we doing so yeah, that's too bad We're gonna do but live debugging Yeah, you're right. So So yeah, we actually have an excellent rule that will tell you if your dependencies aren't up to date and It will add the ones that are missing. So I Hope now this works. Yeah, brilliant. Thank you for that And if we enter something it gets cleared out. So the next step is going to be to display this error Before I got sidetracked I was talking about you select and There's another task in here. So we can use the get validation error function to pull that specific error out using the validation error ID and That will and we should return that from this function and if you notice here We assign that value to a variable So the instructions mentioned the get validation error selector and that's a function So to that function you pass the ID and you return that value from this you select function So if everyone wants to give that a go, I hope the I hope the instructions for that one to clear I think this can be tricky because it's Something that not many people have worked with so Let me know if anyone gets stuck and I will help Okay, so I'm gonna show you how to grab the error out of the store So again, some people will have noticed like, okay, I've got the error. It still doesn't show and that's gonna be the next step We go on So also, I think we probably won't have time to finish the whole workshop we have Quite a few more bits to do so we might we will have to cut this short However, at the end we are gonna give you a link to the full solution You can go and take a look at that or you can just keep working through this and anywhere. There's a notepad There's a task in there and I Also want to mention the spoilers folder if people get stuck with something they want to see the solution There's a spoiler in there that will Hopefully answer any questions you have about that specific task. Some of them don't have them But a lot of them do so feel free to look in there if you need help So what we would do is on the store object We would use the get validation error Selector and to that you pass the validation error ID And then we want to return this and And All that does is because you're using get validation error. It will go to the data store It will find It will find the validation error based on the ID and it will return the message and the hidden value So we have this in our validation error object Some people notice that clear validation error gets called a whole bunch. You can Now that we've done this step you can use you can check whether validation error is Undefined if it's undefined that means it's not in the data store So you don't have to do clear again. You can use that condition It's it's not a super big deal to do this multiple times But if you can make it more efficient, then why not? But I think that's an extra credit. Yeah, this is an extra credit So we won't cover it, but you can you can try working on it after it or now The next step so we have the error we don't want to display it so at the very bottom of the file there's another task which is to Write some code that will render the error so above remember We got the error and it's now stored in this validation error variable We want to show the message field of our error. So You can just use a div to display that you can use a paragraph, you know, you can use anything Some libraries might have like a custom error component that you can pass a string to that works as well It's really up to you how you display this and that comes back to what I mentioned earlier like blocks won't do this work for you So everyone's to give that a try I will This should be hopefully straightforward. We're just printing a property from an object. So we can We spend a few minutes on this we'll go over at the end and There is actually a spoiler at the top which contains the answer if people get stuck Yeah Did everyone get chance to output the error has everyone tried? Did anyone? Sorry You did nice. You didn't run into any sad ice cream cones a Sad ice cream cone if you have an error in your block It will not render and instead you get an ice cream cone that fell over to show your error. Yeah, you didn't get that. That's good Okay, nice brilliant so Yeah, I'll quickly just show this You can just render a div for example and then output validation error dot message and And that should work, right? We're just gonna output the validation errors message You made it harder. Okay. Okay. Nice so The sad ice cream cone Too bad. So the problem is so the reason the ice cream cone appears is because I just went straight to the message property and because validation error Initially is not set immediately. It's in a use effect, which is running As we render so when it comes down here, it's not so it's like well, I don't know what this message thing is Trips up so we can simply Add a question mark here, and if it's undefined it's not going to show anything however, we could do it a little better and if Validation if validation error is falsely shown no or show our div and That should be fine. I say please enter a value so for extra credit you can Keep this hidden until they've interacted with the test text box and then show it It's kind of a little much to go into for now and not actually blocks related So it's kind of more react thing. So you can you can try and figure that out on your own Again, as I mentioned the hidden property here is a hint to you. So what you can do is You can do all validation error Dot hidden. So if it's hidden, we will just render null So if it's not hidden and there's a validation error, we can show the message and Thomas can you remove one of the other fields? Let's say the zip code or Yeah, take a look what happens then so now you can see there's some styling involved So there's a red border the text is red. Whereas if we go down and we select other Can you do that quickly? Then you see Yeah, sorry But you saw the error message before with black so that might also be something you want to address to make sure to have the same Yeah, there is a class. I'm gonna open the spoiler. There's a class here. If you add this class to your If you add this class to your div It will be red. So feel free to use that class to make it red Yeah I Yeah, so And when you came in one of the commands was npm run start and that will that the suit is webpack Yeah, it's included in the template that you installed So you might have your own build tool. This was just for the workshop, you know, yeah, it's webpack Yeah, so that's kind of That's kind of it for the front end if we enter text here that goes away That's it for the front end. We have like I think 10 minutes left on the talk There's a whole bunch of back-end stuff we need to look at Actually, it's not so complex the back-end stuff. There's two big files to look at We've done the hard work the next steps are to Look at the integration interface that we wrote trying to zoom in there and I was gonna kind of explain how to do these tasks explain How the this integration interface flows? I can I can go over it quickly. I like I say, I don't think we're gonna have time to code it but Essentially what happens is when you register this integration interface you will need to When the checkout block is registered you need to grab our integration registry which is passed to the Callback of the checkout block registration hook. So when we register the checkout block this hook gets fired You can register your integration interface there So basically what happens is all the integration interfaces. So like any plug-in that has something to do with blocks Will use an integration interface They get put into a list and when it comes to render time it will blocks will call the initialized function for each Integration interface so any code you want to write that will happen when the checkout block is rendering on the server side If you go in the initialized function of your integration interface and here Yeah, we've just registered our scripts front-end script editor script and editor styles The main integration is where we register like the block.js stuff. So all the all the code we've just been working on and The one underneath that is the extend store API function and This is a separate file I mentioned we keep it separate because this is kind of like the interface between blocks in the back end but the Extending the store endpoint is it it should be a separate class. You should do it as a class and Well, you don't have to do it as a class. I like to do it as a class because You can statically reference the init function. It means you don't have to instantiate it and keep an instance around So here we have the store API container This is when we've come as blocks is set up the store API container is Set up as well and it has some classes on there Specifically the one that's interesting for adding API calls adding fields to the API is extend schema If people worked with blocks before you might know it as extend rest API, but officially it's now extend schema So what that does? There's a task in extend store which tells you to Basically, it tells you how to extend the API and what we need to add to the API is two fields. We need to add the the value of the select box and the value of the text box There's two fields there. However, one should be optional because if you Don't have the other text the API shouldn't expect that to be filled in so that is Down a little bit in here. It's all commented out because it would break otherwise You can follow the instructions to uncomment this code and Add a description define the type So this is basically the WordPress API at WordPress rest API that we're extending here ultimately under the hood So that's basically these are two Our two fields that we're adding so that means when we submit the checkout form the checkout route Expects of these values to be in the request Give it a lack of time. Should we do it directly? Yeah, just show it. Yeah, we can do that. Yeah, that's okay so the task is to find the Extend checkout scheme method make some changes So that's this one down here. So we can uncomment this code and then we can follow these Steps so the description is just kind of it doesn't actually get used by anything during normal operation But it's just a good practice to like describe what your API fields do So if you come to like right documentation for them, for example, it will be described so we can say and we can set the type to be a string because That's what the user will enter The context is where this API field will be expected. So we can put view and edit in there Read only is whether the value can change Later on in the request if something can come and update this. We don't want it to It should be optional because it's not always present and And this are options the validate callback function is a way for you to check the data submitted is What you will expect it to be? So it's super simple. We can just go value and if If it's a string this passes if it's not a string like someone submit something else That's not what we're expecting the API will error the order won't submit Again down here is The same thing again, but it's a separate field. So we have to go through the description We have to define the type and then Same function and we can come up here and Uncomment this and what that will do now is when the checkout schema is registered So the checkout schema is the description of All of these fields. So Our checkout schema is What's the shipping address? What's the billing address? What's the email? What are the items in the car? We've now added Our two extra fields So when we submit our form And actually the cool thing about this is if you're doing back-end only code You don't actually need to reload the page because each API request is separate. You just get to press place order and It worked Because it got the data it was expecting if I didn't send if we didn't Did something wrong earlier in the workshop and we didn't have the extension data in the data store It would have failed. It would have said we expect the Alternate shipping Instruction to be a string and it wasn't so and now that you added it to the store API you created that that You extended the store API. Yeah, the value is now in the database, right? Not yet We need to add the value today space. So again The API just has the value We now need to hook into some things in order to save this so Down here we have save shipping instructions Which has some tasks and again due to lack of time and I will run through it If you want to try it after the workshop, it's great We're also going to leave you some like contact information. So if anyone After the workshop wants to get in touch that there will be some information on the slides So, yeah, we have this hook We call my store API Check out update order from request and this fires whenever you press place order submits the back end and Then this hook runs with the request past as an argument We also have the order as an argument. So I Everyone is familiar with the way the checkout orders are made in the block We save a draft order when you enter the block and then when you submit and it's successful that draft gets turned into a published a completed order basically So every time the place order button is pressed this hook happens So again the tasks from the shipping workshop request data array. So Here I defined the shipping workshop request data This is the request value that gets passed to the API and in that is a key called extensions and Every other extension that adds stuff Will actually have an entry in here. So if you have like for example with comma subscriptions this extensions Okay, we'll contain a word comma subscription data to because their integration will need it So the request has everything and then we use this get name to access our namespace So from that we can get the alternate shipping instruction and the other shipping value And then we will add them in their own variables So we can use them later And then we can update the metadata on the order. Again, this is not super block specific. This is kind of regular old WooCommerce We can use The order that gets passed to this hook. That is the draft order. I mentioned earlier we can Sorry update Metadata and we can set this key you can you could choose whatever key you like. This is the one I chose And then we will set that to this value and then we'll do the same for the other text and The extra credit is to don't set the other text if it's not submitted But we can we can do that afterwards and then Finally the last thing to do is save the order and now that If we add something to our cart again and check out That will actually be saved in the order So it's actually saved down here in the custom fields There is some tasks to show it in the order There's some tasks to show it in the order confirmation, which is this page at the moment It's not shown so we can we can show it there and Finally the one the final one is to include it in the confirmation email So I don't think we have time to cover them right now. I think we should probably wrap up But yeah, I hope this was useful to everyone The order confirmation page and the email definitely no time but what we can potentially do is The WP admin where you just showed the order if you can go back to the this this Yeah, exactly that one because that's like super. All right. All right, fine. We'll do this real quick So this hook I added is just Underneath maybe if you go back to the to the WP admin to the back end Do not have a pointer, but I'm big enough Yeah, you see the shipping instructions here And they currently empty and it would be nice if we actually have to feel it's not only downstairs where we where you showed them before But if they would be in that section here, so I give you a minute. Okay, cool. Yeah No pressure So this is the hook and that this hook happens underneath the shipping address So I already added the title and the next thing to do will be to print out the shipping workshop Alternate instruction and also if they added other instructions We can also output that so there we go. We have the shipping instruction and the custom value so there's another mini task as well because actually what is saved here is the value of the input field not the nice text so As an extra task if you want to somehow map the values back to the nice nice displays Here might be a good way to decide that you can just add a switch statement for example, but That's pretty much the long and short of it so we Have some time for Questions and answers go through Yeah, we have a Q&A session, but first I want to say thank you to everyone for attending Thank you, and I will leave our Contact information on the screen while we answer any questions that anyone has so feel free to take this down there is also a There's also a package that I wrote in WooCommerce called extend cart checkout block and That contains more examples of extensibility. So if you visit the WooCommerce get hub repo looking packages looking JS Extended cart checkout block You'll find it, but in the final version of this Workshop, I'll add a link to it in the the read me so You'll get it. So is there any questions anyone has? I have a question. Yeah We showed you that you start with the starter package now the question is where can we reach the final package? Yeah If you Go to get hub you go to my username, which is OPR The final workshop is called WC EU 23 shipping workshop final That's our but Maybe people want to take a note of this because I didn't put it in the slides But if you want to take a photo of this feel free to grab that now this has the completed stuff Some of it doesn't have the extra credit stuff, but again feel free to jump into Slack ask a question We have a question at the back A suggestion, okay Yeah, I'll add that Yeah, I don't I don't have slack open right now. I'll do it. I'll do it after the session. Yeah, no worries Good suggestion. Thanks Yeah, so that's the final watch up. Yeah, I will add this to slack Let me go back here. Yeah, I will add this to our slack channel. Can you remind me of the channel name pie? Can you remind me of the channel name? Let me let me open that Where is it? Oh, I don't have it open Sorry Well, yeah Let me open this again right you can take this down. So any other questions? I Have a question to you who of you gonna start extending the commerce blocks now Not so much okay, if you have any questions, please ask reach out Any comments any suggestions? We're always super happy for feedback. Yeah Yeah, we both hang around in this slack a lot and then we're always active on GitHub as well. So We should answer pretty pretty quickly. So Thank you everyone for coming