 Hi, I'm Mina and I'm going to share with you today our experience at XWP of customizing Gutenberg core blocks to add AMP features. So, Gutenberg, well, Gutenberg is definitely new editing and also development experience and I read through a bunch of plug-in reviews out of interest in the WordPress repo and it seems to be kind of love-hating going on there with Gutenberg and one of the notes that I've seen also is that people mentioning that it's not very developer friendly and I've also seen a few notes about unsuccessful attempts to customize the editor, so I can imagine yeah it can be definitely quite frustrating or at least challenging to having to learn a completely new thing when you have already gotten so used to something else and This talk is going to be quite developer-focused I'm going to show some code examples And I hope that at least some of you who are interested in developing on Gutenberg will get some useful information So at XWP, we were also facing a challenge when developing the official AMP for WordPress plugin to build in AMP support and Well, we wanted to build in Gutenberg support from as early as possible So that once Gutenberg actually gets merged to core which happened yesterday Then the plugin would work right away and a few notes here So first of all, I'd like to mention that The presentation that I'm making today is just a tiny part of the AMP for WordPress plugin there's a lot more to it than just adding AMP features to Gutenberg and second point that since, well Gutenberg still seems to be evolving then this is not necessarily Final or ultimate truth of how to extend Gutenberg blocks I also had to redo a few slides a few times after updates But it is a practical example of how we managed at XWP to add custom features to core blocks So a few words about AMP, probably most of you are familiar with AMP as As it stated on the AMP website, then AMP is an open-source initiative the goal to make the web better for everyone and AMP basically consists of three core components the optional AMP cache, AMP JavaScript and AMP HTML and the most relevant part for Gutenberg blocks is AMP HTML So a little bit about AMP HTML to give you some background of What we needed to change and what we wanted to achieve with extending the blocks So what's the difference between HTML and AMP HTML? AMP HTML, it is basically HTML But it has some restrictions meaning that some of the tags are not allowed and it also has some Custom elements, some of them to add new features and some of them to replace the restricted elements So here are a few examples For example, the default image tag is not allowed, but this is replaced with AMP image Exactly the same goes for video, video tag is not allowed, but it is there is a custom element AMP video So here are two examples of New custom elements by AMP, AMP feed text I'm going to talk a little bit more about this later as well because one of the code examples is based on that The other is AMP Facebook. There are tens of more of AMP elements, these are just a few examples and Also related AMP has also custom attributes Some of them are meant for using specifically with AMP components But some of them can be used with almost any default HTML tag as well So The goal of the AMP for WordPress plugin is to help making the WordPress website AMP compatible And also provide AMP specific features for the editor and a brief overview of what we needed to achieve with a plugin So first of all in case of the forbidden HTML elements We either need it to remove them or if possible replace by allowed elements For example, a good example is the image tag. It's not allowed So we would replace that with AMP image and this part is actually Mostly automatically done by the plugin already. So this is not so much user-facing in Gutenberg editor The next part is to add new AMP features and this is now the place where the editor becomes relevant since That's where the user can actually choose if they do want AMP features or if they don't want to So we wouldn't just randomly add AMP features to website where we think that it would be awesome And so the editor gets to decide if they do want to use them or don't want to use and also Related to the previous two points. We also wanted to add Controls to the editor so that they could modify the AMP attributes So why go through the trouble of extending core blocks at all like in theory We could basically just create new blocks for absolutely everything We found that it makes more sense to actually reuse and extend existing editor blocks for example in our case what we actually wanted was to Have sort of say customized or enhanced versions of the existing blocks with optional AMP settings And from a user experience perspective, it's very important not to overload the inserter and duplicating blocks So for example Let's say there is an AMP component for Lightbox, it's called AMP lightbox and this is basically an image with lightbox effect. So let's say that If you extend the blocks, then you could just use the already existing image block and just tag a control So the editor can choose. Okay, I do want the lightbox effect or I don't want if you would create a new block Then the user would have to remove the image block Add the AMP lightbox block and configure it. If they would think that actually I don't want it I just want to link my image then they would have to go through all this switching back blocks again So now to the code part So the code examples that I'm going to show you they are simplified examples for example if if we actually added five settings to block then I'm just going to show you one because Well, all the settings are added quite in a similar way and I'm also going to repeat quite a lot of stuff At first when I was creating the slides, I was thinking that okay I'm just going to show the so to say unique parts not to for the people to get to board but fortunately my colleagues at the XWP were willing to listen to that talk a few weeks ago and I actually received the feedback and it's great if there are repetitions because you can actually see That we are extending all the blocks kind of with the same base logic So a little bit about the filters that we mostly used for extending the core blocks in AMP for WordPress plugin Filters are basically a great way to sort of say hook your own code into someone else's code Well in case the developer has thought that maybe someone wants to do it and add filters for it And this is fortunately case for WordPress and also the Gutenberg editor. So we mainly used four filters the first one is called blocks register block type and this allows you to hook into the moment where the block type is getting registered so you can configure all the settings there and What you do here is not going to be Directly visible to the user by the way the second filter is blocks get save element and this is now for Filtering what gets saved into the post content for this for a specific block So this obviously means that whatever change you make here. Yes, the user is going to see that The third block editor block edit this is for filtering all the visual part of the Gutenberg editor So using this we would add the controls. We would change the behavior controls and we would also Filter how the block is actually displayed inside the editor And the fourth one that we use this get save content extra props And this is also for filtering what gets saved into the post content But this is now not filtering the whole block. It's just filtering the attributes So let's say we would want to add. I don't know inline style for a paragraph Whatever, then this is a filter we could use And let's now get to the actual code examples as well so the first example is about the amp component called amp fit text and What it does is just basically Shrinks or expands its text content to match the space that it has so you can assign Minimum font size to it. You can assign maximum font size to it and it's going to respect those font sizes But take as much room as possible in the container that it has and Here is an example of how the amp fit text looks like so here We have set minimum font size maximum font size and height and we have wrapped this around a heading 3 and This now is how it actually looks like in the source code after amp has done its magic So for example, we set the maximum font size to 80 But the actual font size is going to be a side 68 This is how it looks like in the front end. So this is 2017 theme above there's heading 1 and Below there's heading 3 as you can see the heading 3 is much larger Original it's not much larger, but we wrapped it inside amp fit text and we gave it a lot of space and now that's the font size So here what we wanted to do was to add the controls for the user to opt-in for using the amp fit text those are for modifying all the relevant attributes and then we would want to wrap the original content inside the amp fit text and This is What we want to achieve. So this is the block sidebar as you can see we have added amp settings For amp fit text and I'm going to show you this example based on a heading. All right so the first thing we need to do is to register the settings and For that we use the filter register block type that I mentioned before Here we have available the original settings and the block type name So first thing we do we check if this is actually a Heading block These filters are going to go through all the blocks So if you don't do is check we are going to add some random controls and settings for all the blocks and Well, if it's not heading even they just returned the original settings. Otherwise, we start adding our attributes So here we add an attribute for amp fit text We're going to create a token for that and we see set it to false by default and We add all the other settings that we want the same way. So the minimum font size maximum font size and height So now we have the settings configured now We also want to actually show those to the editor and for this we use the editor block edit filter Here we have available the original block edit component and the properties Again, we check here. Okay. This is not a heading. We're just going to return the original block edit Otherwise, we start putting together our controls that we're going to show to the editor So the first one that we create here is a toggle This is going to be for the amp fit text They're going to set the label the current value the behavior and Now we add the other attribute other controls But this case we do this only if the editor is actually chosen to opt-in for using amp fit text If if the user doesn't want to use this and there's no reason to show all the controls to the user so if The editor has chosen amp fit text, then we add all the other controls the same way once that's done we return all these controls together with the original block edit and That's quite important to add the original block edit because that includes all the previously existing controls plus How the block is actually displayed? Okay, and Now we have the settings. We have the visual controls and now we actually we also want to modify what gets saved in the post content So for that we use the get save element Here we have available the original element the block type object and the attributes as the editor has saved them So now in addition to checking if this is actually a heading block We also want to make sure that we modify the content only if the user actually has Opted in for using amp fit text. Otherwise, there's no need to make any changes at all And if the user had opted in then we start putting together our attributes for the amp fit text element that we are creating so The first thing we do here is that we add the original element as the child of the amp fit text because We're gonna wrap amp fit text around it And after that we add all the other attributes exactly as we expect them to show up in the post content because this is Actually going filtering what gets saved into post content and then we Create the new amp fit text element with all the attributes that we assigned to it So that's it with the amp fit text and I'm now going to show you a short video about how it actually works in action I hope it plays as well So this is now a heading and this does not have amp fit text assigned to it This is just heading without any settings So now when we go to the heading block we can see that there's the amp fit text control And this is the only control that shows up at the foot when we toggle it We can see all the other attributes that we added as well So we're gonna set the height what we want and adjust the sizes and Then we are going to save the post and see how it looks like now and this is how it looks like now So it used to be smaller than a heading one, but now you can see it's much larger so The next example is going to be based on gallery shortcode there is actually no specific block for gallery shortcode, but there is a block for shortcode and You can well use gallery shortcode with that as well so here what we wanted to do was to Allow the user to use amp carousel Instead of displaying the default word for scullery and this would display a carousel instead of default word for scullery Here we would want to add just one toggle so the user can choose if they want to use the carousel or not Again the first thing we register settings Here we have now we use the same filter register block type Again, first of all we check if this is a shortcode block Then we add the amp carousel toggle which is going to be well a boolean again Meaning it can be only false or true. Then we return the settings So now when we have the settings, you also want to add a visible control for that again Use the same filter editor block edit Then we check if this is not a shortcode. We're not doing anything. Just return the original component and otherwise We add the control, but what we do now here is that since we only want to add this control In case it's a gallery shortcode, so we actually check Did the editor actually type in gallery and if they did not then we just return the original component otherwise We add the inspector controls with carousel toggle exactly the same way as we added in a previous example And then we return the original together with the custom inspector controls So now we again have a register settings. We have added visual toggle to the editor Now we want to modify what gets saved into the post content and for that again, we use the blocks get save element filter Again, we check if this is not a shortcode then we just return the original Otherwise we add our custom handling and Here again, we check first. Okay. Is this a gallery shortcode at all has user typed in gallery and if they actually chose to use amp carousel Then we check if the amp carousel was previously set to false Then we'll remove this. So how we set it up was so that if there is no attribute for amp carousel set in a shortcode This means that it's true and well probably most of you have used shortcode So you know that the attributes just get typed into the shortcode as text So this is what we are processing here as well And otherwise we check, okay, if you are not using amp carousel, but if it's not set to false Then we add this as false and the last thing we do here is we check, okay Did we actually make any changes to the original text that was saved and Only if we did then we create the new text element So here is also a fourth part But I'm briefly going to show is the processing from PHP side because we did add this attribute But this is not a default attribute for for the gallery show So we also want to make sure that it actually gets used And for this we use the post gallery filter to add a function maybe overwrites a gallery and We have available the HTML parameter which includes the original output And the shortcode attributes. So here we check that okay if the amp carousel was not set Or it was set to false Then return the original output And otherwise we add our own logic to use amp carousel and return this instead And that's it again. So I'm going to show you the video again All right, so here I'm adding a shortcode block as you can see it doesn't have any settings by default and When I type in gallery, then the settings appear added by the amp for WordPress plugin so at first I'm just going to show the Default word press gallery. I'm going to add some images We're gonna save the post and see how it looks like So this is now the default purpose gallery. Just three images in a row Now we go back and choose to display as amp carousel And now as you can see this displays as carousel instead leveraging the amp carousel component so the third and the last example is going to be about amp lightbox and here what we wanted to do was to add option to display an image as lightbox and for all the image blocks so this would mean the image block the gallery block and also the gallery shortcode block and I'm going to show you this example based on image block So here it's how it's going to look like Once we're done. So we are again going to add just one toggle or optionally show us with lightbox effect And again, the first thing we need to do is register the settings So here again, we use exactly the same filter blocks register block type Again, we check if this this is actually an image block only then we add the amp lightbox attribute And this is going to be a toggle again So this means type pooling only true or false and then return the settings So now we have settings registered now. We also want to add the visible controls For that again, we use the editor block edit filter Again, we check if this is not an image. We just return the original block edit component And then we add our custom control I'm not going to show you this in detail because this is exactly the same as in case of previous examples and now we also want to modify what gets saved into the post content and how we set up this is By adding a custom attribute to the block that we would later process in PHP so this time we we don't need to filter everything that gets saved into the block content We just want to add one attribute and for that we use the get save content extra props filter so here we have available the Properties the block type object object and the attributes that the editor has Say it for this specific block and then we start putting together our attributes We check that if the amp lightbox is set then we add this attribute exactly as it's supposed to show up in the post content and then we return the Custom attributes plus the already previously existing properties. This is also important because otherwise we would lose everything else and The fourth part here is also To actually process this attribute in PHP I'm not going to show you this right now because this is not at all Gutenberg related and We are ready again. So I'm going to show you a video again So this is now an image Block it doesn't have any settings at all. It's just added image doesn't link to anywhere Nothing happens when we click on it Now we go to the image block and we can see the amp settings added by the plug-in And we are going to choose to use the lightbox effect So this is the same post now with the image and now when we click on it actually displays as lightbox This is not completely centered. I can see that just right because I recorded the video not completely centered Okay, so that's it with the examples I guess if you have never developed with the Gutenberg before then this might have been confusing or too many details to remember but I'm sure that you notice that there is a lot of repetition meaning that actually the The base logic for extending the blocks is generally kind of the same So a few words about the challenges that we had so well first first challenge was definitely to figure out how all this works at all because when we started developing it it was quite early this year and that that moment there was kind of Almost no documentation about how to do it and they're also Well didn't exist real-life examples of how this actually works So it took us some time to figure it out but once we did understood how the filters for blocks work and which to use and then to use then it was quite straightforward and Now I believe that the documentation for filters. It's Quite detailed so if you're interested then go check it out and another thing to consider when extending Gutenberg blocks is that Well, basically how we wanted to Implement the plug-in was so that if the plug-in is activated and if you do changes and then if you would deactivate the plug-in Then nothing would change for the user or nothing would break for the user so to say But every time when you load the editor, there's a background check happening Which is checking if there are inconsistencies between what's currently saved into the post content Compared to what would get saved by the currently existing logic for save saving so since we filter the what gets saved into post content then if if you after doing that if you Deactivate the plug-in then this is what you're gonna see and this is the same heading Exactly the same example that I just showed you with the amphi text Set to true so if we do that and then we go and deactivate the plug-in Then this is what going to happen. So at first we were figuring out all kind of ways of how to get around this Or how not to have this but then we actually receive the information that this is completely okay and If you just click convert the blocks then the default block is going to be restored and this works for the core blocks So but that's just something to be aware of and well for me by far the most frustrating thing is Has been the weekly updates by Gutenberg which More than wished to break the plug-in so it's It's unbelievable how many times we had to re-go some things is a method changed or a class name changed or something wasn't there anymore Was removed or replaced or I don't know. I think the Pretty is four weeks. Absolutely every single week after update. There was something wrong. So It's Well, it's definitely good to test everything all the time But if you're working on large projects and multiple projects, then you can't stand It's hard to spend like half a day every day. Just testing if the latest update now broke something or not So the the good news is that if something breaks, then it's fortunately usually just the back end because well The post content already is what it is So the front end experience is going to stay the same, but it's still super frustrating for a developer to go to after update go to the Post-editing page and then you just see a white screen and you're gonna start thinking out. Okay I'm gonna go through all the github Last release to see what kind of changes were made to figure out how to make this work again Fortunately or at least I hope so now when Gutenberg is actually part of WordPress and Then it should be more stable Yeah, I hope so at least So a few thoughts to Thoughts and conclusions so well first of all as you probably saw then The logic for extending the blocks is quite similar. There are actually More filters available, but these were the ones that we mostly needed for extending the blocks And of course, although this presentation specifically is based on the adding and features then actually All this is applicable for anything else you might want to add And the last thought is that yes, although it can be super frustrating sometimes with Gutenberg, but The more I worked with it the more I actually see that it does It does offer like really cool opportunities for a developer to add really awesome features and by this also enhance the experience for editors and That was it Here are a few links as well. So the first row here is just a sample plugin Stabilna production ready and I hope it hasn't broken meanwhile, but you can check it out just to see how to extend a block so the second line here is link to the plugin and If you're interested then you can go to the plugin site and there should be link to GitHub repo So if you go there if you're interested you can see all these examples in real life and actually functional That's it. Thank you Do you have to do something? So I have a plug-in on my website that's already an amp plug-in Do I need to remove that plug-in and start using your plug-in instead or could I find another way to keep one? Or what how does this plug-in kind of like apply to? Like a WordPress site without Gutenberg or does it? It works very well with Gutenberg without Gutenberg. I mean what I As I mentioned before as well then the Gutenberg part is just a tiny part of the plug-in So probably if you already have an amp plug-in, then it would be better to remove this and Add amp for WordPress plug-in instead because it's yeah, the plug-in I have now is amp supremacy So I was just wondering if it was like gonna affect it or anything. I'm not familiar with plug-in Are you familiar? Thank you, Alberta So the image block with amp settings Is there a way to make that so that that's going to always be the default like lightbox's default toggled on and Amp is toggled on when you try to use it. Can you ask it again? I'm sorry. I'm so sorry Forgive my ignorance too. Is there so the point you were showing with the image Is there a way to make it so that let's say the Lightbox has always toggled on when you try to create a new block with that No, it's not that this month Yeah, as I heard from a pilot that you could create an extension Plug-in yourself and do that