 Wow. This is a long day, and there's been a lot of really good Gutenberg talks, which is exciting, because we get to build this stuff. And I've been talking a lot with people about, like, hey, what happens when we can say your content just updated and the sentiment doesn't match the style guide? We can check what people are saying, and are they using words that we had specifically said, don't say, or are people making choices that are going to violate the style guide? How can we rearrange content? So that's been a really fun thing to think about today and, like, with the other WordPress nerds. And this is kind of scraping the surface of how we might do those kind of things. That title that I wrote, this is entirely my original art, this is wrong. This is more than fairly. This is the stuff that I'm currently working on right now in my real life that I wanted to share, not so much about, you know, I'm gonna give you an example that you can copy from, but also just start thinking about how we can, on a code level, reuse parts of Gutenberg, so that way our user interface is consistent with WordPress for our plugins, for our custom site development code, and just kind of what that looks like with other requirements that we have. So I'm Josh Pollock, I'm the lead developer for a plugin called Caldera Forms, and we're currently working through this process of React is cool, Gutenberg is cool, how do we reuse that stuff? So I'm not maintaining as much code as a plugin developer, which is great. And also my user interface feels more WordPress. That's kind of my goal right now in what I'm doing in this talk is sharing where we're at. I thought this was gonna be basically what I did in work at Miami in March. Totally different, it just, things have changed and gotten better since then. The slides are here, there's a lot of pictures of code, which is not useful if you wanna take it with you, and may or may not be easy to read on the screen, but in the slide that the speakers notes, there's a link to a file where you can see the actual code and cut and paste, and we'll get at it on your screen. So everybody's welcome, but this was written with people who are PHP JavaScript developers, and I'm not gonna show you how to in queue scripts for a block. The handbook demonstrates that and other talks have talked about that. So everybody's welcome to be here, but we're kinda talking about, well, short codes type stuff. I'm not gonna get into meta boxes, but how do one block start to get more complex? What's the beginning of that? So how do we use sort of the modern JavaScript build tools? How do we construct interfaces out of smaller components? Everything is a block is one of our new guiding principles, but when we're building blocks, that's not the smallest unit a lot of the time. And then sharing those between WordPress in other places where we might use React, which I'll generally say single page web applications. That could be something totally different from WordPress. That could be a small section of your site that has a little bit of dynamic JavaScript in it. This is a photo of my dog and she's very happy and it's been animated in a GIF. And I miss her, so I wanted to have a picture of this, but also like, this is me kinda right now, like, oh my God, I get to play with the cool stuff that as a WordPress developer sometimes there's a reason I use like View and Laravel and React and those sort of things because they're more fun sometimes. And I'm excited about using this stuff in WordPress. So this is kinda like, we don't have to use NPM and YAR in a webpack. I think if you are doing anything beyond simple blocks, this stuff is tricky to learn. Once you systematize it in your company, in your process, it solves so many struggles for you, right, like dependency management, that I'm hitting one command. I remember cutting it, we still do it in lots of things, cutting and pasting the right version from GitHub of some distributed JavaScript or CSS framework, right? The first theme I ever built was, hey, what if I use foundation to build a WordPress starter theme, right? And so I was cutting and pasting code from what I was downloading from there. Now that's all automatic and lets us reuse other people's code. It allows for consistency, developer environments, both you and the future when you go back to a project or somebody else working on it. It gives us automation. Systems like NPM and YARN or Composer on the PHP side. Let us say this one command does these three things that means testing, right? So I can have NPM test in a YARN test and that does three or four different things that I can configure in one place. So it's sort of a sanity is restored, right? It's a new thing to learn, it's a new thing to track, it's a new thing to debug. But it's important. Webpack is a system that takes and makes it into browser safe. And in general, in this context, we're talking about React with JSX. We're talking about new JavaScript syntaxes that might not be supported by browsers and I can't remember because Webpack solves this problem for me by automating Babel and write the other people think about this stuff for me. I'm targeting the browsers that WordPress doesn't go to birth. That's as far as I've thought about. These systems can solve it for me. And so we can use these new syntaxes and you can also use other languages that are used to write JavaScript, like Flow or TypeScript or for CSS world, SCSS and other systems like that. And we use it for optimization of CSS and images that kind of stuff. I will say, it is not easy to learn at all for me. And the fast moving ecosystem is confusing. Webpack four just came out so Webpack three is pretty ubiquitous. For the most part backwards compatibility but not totally that's tricky. You'll still see plenty of stuff for Webpack two. As WordPress developers where we're committed to backwards compatibility, that can be jarring. The new JavaScript, right? Like I can't remember if I'm supposed to call it ES next or ES six or ES seven or whatever. It's going to require compiling. You can't just use async and await keywords which are the brand, you know, these new keywords that make working with API requests and other types of asynchronous functions easy. Chrome doesn't support that I don't think but you can with Babel. And you get things like faction, async, await, new syntaxes that are just nice. And all my code here is written using modern, the latest JavaScript. One of the benefits that you get about that is you start to be able to use WordPress modules. One of the cool things about Gutenberg that's a meta version of everything is a block is that everything in Gutenberg is becoming and this is very, this is a work in progress that's come a long way recently. Becoming individual packages that you can do NPM install WordPress element. You also can do WP and Qscript, WP element. Right, this is another way they can use it but WP and Qscript doesn't exist outside of WordPress. NPM exists outside of WordPress. And WordPress is currently shipping with React underneath. So if you see, this is a screen cap from Gutenberg itself. That this is importing all of the stuff from React and then exporting create element which came in from React. Why? Because it's WordPress and we're concerned about backwards compatibility. So what happens in the future here? Who knows, but this is an opportunity for future proofing, this dependency. But as we talk about using WordPress components in other systems, keep in mind that right here, this is where we're at. And as long as we use this export, we should expect this thing to behave the way that WordPress doesn't behave. Whereas React is a totally different ecosystem that may or may not move in certain directions. So this is cool. This is a good design decision but it also makes what we're about to talk about makes sense. Is that when we're in WordPress, all of this stuff is getting put on WP. So WP.element, this is component. So this is functionally no different right now than React component. But it's using the WordPress one so that way everybody's sharing the same one. Select control comes from the components package. That's if you wanted to reuse the select control for form fields that Gutenberg uses. Why make your own anymore? Because now I can just have Gutenbergs. It looks the same way, functions the same way. Somebody else has put a ton more thought into the usability of it. If it develops an accessibility problem for new accessibility APIs that don't exist yet, the WordPress project I trust will work on that. So here's the translation functions on I18n with data with select from the data module. So you can do that on WP admin if you've enqueued these things. WP and script WP elements. But I can also MPM install all of these packages. And your goal is, if you're in WordPress you don't want to load the same thing twice on the page. You want to let core do that. So you will need to set up MPM and webpack not to bundle these dependencies. So that way you have two copies of them on the screen. But if you were wanting to say, what does it take to use this outside of WordPress? Just install it as a regular dependency, not a dev dependency, which is what the capital D is. So this is how in any JavaScript application I can have WordPress's translation system. WordPress's components, which is like select control, text control, URL control. I mean, there's some really neat stuff in there. Element, which is the DOM abstraction and data, which is the Redux abstraction. So that's really cool. This is the same slide functionally as this one. Right, this is WP element, WP dot element. And then this is import component from WordPress slash element. And if you look in Gutenberg source code, which I strongly recommend, I mean it's just really readable and I've learned a ton from. You'll see that this is the syntax that they're using because this is a webpack alias. I mean you can get the same syntax, which means that like your IDE autocomplete and such will know where the code is coming from, which is useful. This is out of scope of this conversation, but when you follow this pattern, it makes it very easy to use just an enzyme. Just is a unit testing framework in test runner for JavaScript developed by Facebook. And then enzyme is a minimal DOM testing tool that Airbnb created that can run inside a jest. So you can give jest the inputs to your components and then they will snapshot them, which means that they'll store a representation of how they work at that point and you say, yep, that's how they work. And if that ever changes, your test fits. And then you can say, yes, I intentionally made that change, update the snapshot, or you can say, nope, that's bad, better not commit that, we're not done here. Or you can say that tests invalid, whatever, right? But you know these changes are happening. So this stuff is great and you can also automate accessibility testing while you're at it, which is important that gives you these things. And when you follow these patterns, this becomes easy, different work, can't talk. JSX, all my code is written in JSX because I think it's the easiest way to get into React because it's very much HTML-like. There are some cool tools because I could not set up all of this stuff myself. Like maybe if I cut and paste if I was lucky, but that's not what I do, right? I like to write JavaScript and PHP code. So there are tools that can set this up for you and people who really enjoy building these sorts of things can set it up for you. Right? I'm convinced that I don't need the word webpack anymore than understanding the concepts, knowing how to make entry point updates and use somebody else's scaffolding because this is not what I do. I don't make webpack scaffolding. Systems. WPCLI with the WordPress command line interface has a scaffold package that does things like plugins and themes. So you can, with that first line, you just make a plugin. And then with that second line, you add a block. This is the most minimal one out there. This doesn't require webpack. This doesn't have any build. You're just writing plain old JavaScript and that's a great way to get started. And for simple blocks, it's probably all unique. So if you've never done a block, I would recommend that you use this tool to make one for you and then take it apart. Create Guden block is a cool one from a mod. It's based on Create React app. If anybody's here is a React developer who's familiar with React, how you solve problems, you say Create React app. This is sort of the one take on making a Gudenberg version. This will create a WordPress plugin with that slug that has everything you need and start up the server. I've only used this once or twice. I don't have a lot of experience with it, but I wanted to highlight it. It's a little newer and a different approach to the same basic ideas create Guden block. This creates the scaffolding. It also starts a Docker container for local development and has a couple of things, highly opinionated tools for building with Gudenberg. React WP Scripts is from Human Made. It actually has nothing to do with blocks, but it's a good example of using Create React app, and then it has a WP and Q Scripts integration that's really useful. When you're working with React in other like View Angular, you're probably used to seeing hot module replacement, where every time you make a change, it will either replace just that module or the whole page. This is a little difficult to set up in WordPress sometimes. WP React Scripts just has a separate dev server that's separate from WordPress, which is jarring but works. I find that the more that I'm relying on tests, the less I'm loading the refreshing the browser anyway, so I actually live without it. It's a challenge worth thinking about. But once you have that stuff set up and I wanna, it's a lot, it's a hard thing to learn sometimes. Once you get it, it becomes automatic. You can start to make blocks out of components that are reusable, so it's like another level down from blocks being reusable, right? We have this sort of modular building blocks. Read the article in the docs, Thinking in React, where they talk about how to break up into components. It makes the code more reusable, it makes the code more testable. And the key point here is they should have one concern. This is a fundamental principle of software development. Every function, every unit that we're looking at should have one reason to change. So if you have a component that is for the post editor, everything, you know, there are hundreds of things that can change. If you have one for post permalink settings, if ever you need to change how post permalink settings have, there's one place to change that. So React and other systems like this allowed us to think in terms of this user interface is one thing. And we can use these inside of, this is coming out from our, you know, block configuration that we would send a register block. This is just the edit callback. We can start to use them. And I'm going to show you here how we get, you know, we're gonna zoom into the small sections of this, how we got to this component of our settings, which you'll notice is wrapped in another component called Inspector Controls. Now that's WordPress' component, that everything inside of there goes over on the right in the additional information area. And because that is WordPress specific, that is content that only happens when we're looking at it in Gutenberg, that I am doing here in the edit block because the edit callback for the block's responsibility is interfacing my components with WordPress. It's getting the current state, it's handling updating the state, and it's laying it out. What's happening inside of that layout? That's a different concern. So let's zoom in on parts of that. We can take things into it, right? We can take post attributes, we can take our block attributes into our components. That's a thing that's very well documented, and if we want to mix in, as I'm about to do, things that are not the post title when it was loaded, but the post title right now, and it'll update every single time somebody changes what they're typing in the post title, or the post excerpt, or the post categories. All this kind of stuff, how many blocks are there? We can use WordPress's data module. And so that was a super tricky bit of code. What's the current post title updated every time it changes, plus the first three categories? If anybody's ever hacked that with jQuery into the current post editor, this slide of code should be really exciting to you because this is just saying, hey, from core editor, get me get document title, get permalink. And then I'm mixing it in with my block attributes to make what I'm gonna pass in in a second. So that is a ton of complexity that I've hacked in with jQuery before that's now like that line of code because I'm just kind of using what WordPress has. All right, and so this is going inside of that component. When we were looking at here, there at the bottom, social share, and we're passing in that object that I just showed you. This has no relation to WordPress now. This could be any React component you ever see. It's super simple. I have a preference against using classes in React for my components. This pattern of just using a function that gets past props, there are certain places where React literally won't let you do this and that's why I like peer component. But this is just a peer function. Properties go in, HTML or React's reaction over it comes out and then you can snapshot test it. Because it's a function that has one possible output and no side effects, snapshot tests can cover this entire thing just by giving it the different types of props that can come in. And then I can be sure that at any point some wiring falls off or some API changes that causes an error, my tests will generate that. I've written in a lot of PHP that looks a lot like this. This is what I like about JSX is that I was looking at some old code of mine and I had a PHP HTML generation function that was double quotes with the curly brackets and then the dollar sign for strings, which is now a syntax in JavaScript as well. This is like that except for it updates all on its own. For me. So I like this a lot. WordPress has controls that you can reuse. So if you wanna have a checkbox that looks in functions like a WordPress checkbox, A, check out the readme's in the code base, they're always really helpful. This is, you can see at the top and that's going into the render method, import checkbox control and import text control from WordPress components. And now I am, this is the settings module for this. It's kinda hard to see the whole class up there. But we are injecting just our data to this. So this knows nothing about the source of data. The fact that WordPress is generally where the data comes from is irrelevant to this code. It is that much decoupled that again, we can snapshot test it, we can mount it in a regular React app. But what we're wrapping again is this text control and this checkbox control that work whatever way Gutenberg says they work. And as long as I play nicely with them, then I can benefit from a single interface system that right now is going to be post editor and then the future of WordPress will figure it out. I wanna benefit from that as a plugin developer and the rest of site developer because the less changes to how the system works, the easier it is for people to understand it. It's about as sophisticated as I understand user interface design and I'd like to take WordPress's better experience than me. I always say that a React view these frameworks, they start, you know, they're a struggle to get started with because it's a new concept and then they feel easy all of a sudden and then you need to get data backup. You need to get data out of your component, right? We were looking at how do we get data from the block attributes back down into our components. Well, now we need to tell WordPress that that text control updated. Somebody typed something new in it, right? And tell WordPress to update it. WordPress in the edit callback passes this function set attributes that you then give it the new data that you want to update. I mean, I sort of understand what it's doing because I read it once, but it doesn't matter. How that works is irrelevant to me. I'm going to trust core to keep set attributes functioning the way it's always worked and everything inside of that is my problem. So it's a slightly different boundary because these are actually post meta fields that I'm working with in this example code. What it's copied from. But because that's happening via the REST API now I just specified what those fields were, show and REST true and added some sanitization which register meta has the capability for. So this is actually just creating the callback function which I can give to my components so they can call it and do this update that this is happening inside of my Gutenberg block but this function on change is going to get dropped into. We had seen this before in the zoomed out but now we're kind of coming right into inspector controls and then social share settings come underneath inside of those. And so it gets that same settings object that the actual display component had but it also takes an additional argument of on change settings. What does that do? When settings change call that function. React takes for like text inputs what happens when it changes the on change callback goes, right? That's a standard HTML in JavaScript convention but if we're doing anything different we want to be semantic. So on change settings that function that we saw here we pass that in a reference to that and then if you look this is inside of that component where we're using the WordPress text control it has an on change argument where we tell it what we're changing, right? We call from the same class this dot on settings change and we tell it share header as the header for social share message is now the new value. So text control somehow WordPress does it and I haven't read it so I don't know. Passes up new value. Oh I have checked there that's a mistake that's from the check box control. But the help text, right? That gets the proper aria at display described by attribute that label will get used and it'll figure out the foreign ID relationship for me that's important. But what I'm concerned with is this on change. So when it happens I want to call my class method on settings change and tell it share header is now this new value. And so this is the rest of my component except for the render method just because we gotta fit it on one page. This is extends component, react component or WP dot element dot component. So you can read all of the react docs to learn more about this. This is the first time you're looking at a react component. Cool. If they're fun to learn about check out the react documentation. It's super well readable. And now that you know that WP dot element dot component and react dot component are the same thing there's a whole world of information about it. So one thing that caught me up when I started on react is this function on settings change does nothing that you think it does if you don't have that line where you tell it to bind this. Because I'm saying this dot on settings change equals this dot on settings change bind this. Then react behaves as I expect inside of this closure on settings change. And then I miss UJS which doesn't make me do this. But in this function which is going to get called whenever it changes and pass in that update right there I'm just gonna merge it in using object spread with what I had before and pass it back up a lot. So it's this idea of Gutenberg has the source state it passed it down it came in at props dot settings. And then right here it updated share header to new title to new value. And then that goes here where we merge it back with everything else and we call whatever the component when it was instantiated was that we were told would be the function to call that in this example happens to be Gutenberg's set attributes function. But it could be anything we could reuse it we could write a test that calls this directly. We could just instantiate this class sort of a pain to do but enzyme has a helper method for it and call on settings change directly. Just to see what happened to mock the result we can get a ton of control over the stability of our code by writing this way where every single thing has one little change one little thing. So now that this shows that we can repeat this pattern right you saw it for text control now this has checkbox control where all I'm doing is updating is it we're just gonna whatever it was if it was true or false make it the opposite. There's just an exclamation point in front of the same that again if you know in my slides you'll be able to like click these through to get up. I don't want to talk a ton about blocks in the front end A because it's just not my world but also I feel like it gets whenever anybody asks these questions at word camps it becomes a very complex question where it should start at what's the HTML that's already in post-contact. Right how did we do this before we use the post editor to save HTML and then we added CSS and JavaScript in the front end. Right. There's no set like there are themes that have Gutenberg additional stuff there's no theme that doesn't Gutenberg. So I don't want to spend a ton of time on this A because it's just not where I'm at but don't overthink it do as little as you can so that way if JavaScript disappears if image loading disappears the page will still make sense because it's semantic HTML if you use Gutenberg to create HTML that you can enhance later and that's when this gets really cool. So if we are rendering static blocks the save callback uses React and Gutenberg to generate HTML that's all I need if all it's gonna do is say hey share this content why go anything fancier than that just save the HTML and let the browser render it put some CSS on it add classes to it so it can be styled it's just HTML that's new things what's the new API for Gutenberg in the front end? We don't need that yet to reverse a big change all this stuff one less good new thing is good I think dynamic blocks get a little trickier so when we say dynamic blocks that's like recent posts changes so it has to be done with a database, of course also one strategy is you can use the render callback this is great if you're replacing a shortcode because you just write a PHP function for it for example the one you already have for your shortcode you can also save it in post meta and then query for it with the REST API with getPostMeta and PHP whatever you can mount a React app in the front end the same thing that you're putting in the edit callback when it's not focused you know that's your representation you know you're trying to achieve what you see is what you get a really easy way to do what you see is what you get is use exactly the same thing not always possible but if you can and you can only build one thing and show it in both places you've achieved what you see is what you get if you can just use the HTML and load the same CSS so it looks the same you're getting closer to what you see is what you get without having to build multiple things which is beautiful so if you're using a PHP render function for your block you generally just need to return null and save a block won't validate without a save callback just don't do anything and then do a good side this is in caldera forms where we register our block one thing if function exists register block type is an important thing that developers should be doing because that's a great way to know if Gunnberg the plug-in or WordPress 5.0 is active because then I'm going to use it to register this block tell it the form ID attribute exists and to call this function and then this function says is this data valid for Gunnberg? cool call our, sanitize it and use render form keep in mind that this is coming from the post editor so I don't trust the database so I'm going to sanitize it and then that was basically the same function that our short code already has so this is my hey get ready for Gunnberg use a Gunnberg block that took a lot of JavaScript and then just call the same function that the short code always did and that brings me to the end of time and also the end of my slides if this seems fun we're building a ton of Gunnberg stuff that also is going to live outside of Gunnberg and react in other platforms so if you're like hey this is great I want to know more like work on this stuff but let's talk because I need somebody to help me build this stuff my name is Josh Pollock it means a ton to me that at the end of the day people like stuck around to hear me talk about this weird nerd stuff I do you can find me around the rest of the weekend or at me on twitter or calderraforms.com if you want to get in touch thank you so much we're out of time right? four minutes, do we have any questions? so I was just wondering so when you create something on it and you have to make some html wrap up or something like that all of that could save you some post-content and then as you're applying your it going forward people in the future maybe you need to change typically today I thought we would do that in a DAP template and then you change the template and update everything instantly so I'm just wondering how we want to go about solving that sort of problem well, so what's cool about this style is that you can do things like I like to have one effectively global object in my javascript that has all of the class names that I would put on things right so that object has the single responsibility of dictating that and as long as that's followed then the CSS should you know continue to line up and so using this kind of well structured code to make it so there's only one place to make that change when it has to happen inevitably if that's your guiding principle you'll be well prepared for that but you also have to think in advance about where you're going to store your block attributes remember that by default they use the html comment string that several speakers have shown today but they can also come from the html content itself you can say you know pull the paragraph tags inside of the block that have this class put them into this block center so that's an option post meta is an option post meta is a great block storage option because you can query it with the data but if you look on Michael Wood's blog Michael Wood is from Atlanta but is WP Scholar he wrote a post on like creating a REST API endpoint that prints out all the blocks that are on the page Roy C. Vaughn has a plug-in that like puts them into custom tables and so this is kind of a long rambling answer because there are six answers and I would consider how can you best prepare yourself in terms of following single responsibility principle which was always a struggle right in WordPress and this is like good reading code that like you know from the last couple years where these things were done right and the you have that opportunity to have that one place that changes and just what your decision of what you use for block attribute storage you have like you know the html comment the actual html the post meta or the like roll your own at save post so I guess like in a very simple format let's say h4 is the yeah and now it's been h5 okay so that kind of thing you can detect all of if you go into the core data module WP.data there's WP.data and then that select gives you core and core editor and what I would do if I were you because I did it like two days ago is literally console on that and see everything that those two objects will return I had an example that was WP.data.selectCore slash editors that I pull out get permalink right those two things return a kind of information including what are all the box and what are their types right so if you wanted to find every h4 on the page and then transform them into you know you change their settings to heading box h3 or change them into some other block you can discover that and also there is a PHP parser for block content that's why I was saying check out that blog post that Michael wrote about creating your REST API endpoint that shows all your box because the first thing that does is figure out what all the blocks are and what their types are so that could help you isolate on the page you know on the html where all of your h heading blocks were then you can look at their attribute that defines a 3H1H2H3H4 I'm around end of the day thank you so much