 Good afternoon, everyone. Elaine Schlescher is a freelance software engineer and WordPress consultant living in Germany. He is the maintainer of WPCLI and is sponsored by host to work on WordPress Core where he maintains a bootstrap slash load component and tries to tackle their architectural pain points of this popular CMS. Passionate about software architecture and code quality, he never misses an opportunity to share best practices and tries to develop his educational aspirations through public speaking and blogging. You can read his thoughts on code and other things at www.alainschlescher.com or say hello on Twitter under the handle at Schlescher. And please help me welcome Elaine, a lot of Elaine, a lot of Elaine Schlescher. Before I start, a quick word on the planned target audience for this talk. So it's mainly a developer talk that focuses on people that might have their own plugins or their own custom code that ties into the admin backend of WordPress and that might be affected by the changes that Gutenberg introduces. So this is not about how end users will deal with Gutenberg, this is how about how plugin developers and site developers will be affected by Gutenberg and how they can handle it. So first of all, Gutenberg will not only give us a new shiny editing experience, it will drastically change some of the architectural decisions that the editing experience is placed on. So there's a few rather major shifts that are happening with Gutenberg and they will force you to adapt to this with any custom development that might directly coincide with the areas that Gutenberg touches from now. As you might know, the editing experience is the first phase of what Gutenberg changes but it's planned to go beyond that and in later phases also add this block-based approach to other areas in the admin backend. So for now we're only concerned by the editing page. So if you edit a post, that's the only area where Gutenberg right now changes things but it will expand beyond that. So these architectural changes, the first one and the very obvious one is that everything all of a sudden moves from server to client. So right now if you go to the post editing screen and you make changes to the post editor and you click update, you will see that the browser tries to reload the page because the changes you made are sent to the server and then the server will process these changes of a system to the database and then send you a new version of the post editing page that contains these changes that you wanted to store. This conceptually, if you want to visualize this, you can see as I shown here in the diagram that the general state is served on the server side and the server always sends output to the client. The client displays that output and if you click on a link on that output, the link you clicked will request a new version of that page or another page from the server. So the server gets the request and generates new output to show you. This is how the old traditional way of WordPress works. And with Gutenberg, we will now move this to the client side and this basically means that the server sends logic and data to the client. In case that's not clear, the client here is your browser as a practical result. So the server sends logic and data to the client and then you stay within that client. The client manages its state all on its own while you're making the changes, while you click around, while you move blocks around and create new ones, delete old ones. And only when you go outside of that post editing screen will you get back to the server context and the server will send you a new page to load. So while you're in the post editor with Gutenberg, you are exclusively working inside of the client side of things and the client only sporadically makes data exchanges with the server. But the server is not responsible for generating the output that you see. That is all handled on the client side. So this is a very fundamental change which has a lot of implications down the road and we will touch upon some of them. The most impactful one is the next architectural change which is the cause of that is that if you work on the client side, your code runs in the browser on someone's laptop. So you cannot just make a request to the database because the database does not exist in the client's context. There is no database because you're not on your server. So if you want to do data requests, if you want to query something, if you want to store something to the database, you need to pass through the REST API which is a protocol that allows the client and the server to communicate and to exchange data. So you cannot do a SQL query to directly grab something from the database. You can only make a request to the REST API and then process the response that you got from the REST. However, with this REST API, there's a few caveats that you need to be aware of when you're actually building your solutions around this. So first of all, requests are expensive in terms of their processing execution. So where, for example, if you do a direct database request, it will usually land on the same server or a server that's geographically very, very close to your web server and the request will be handled in a matter of milliseconds. All of a sudden, these simple requests turn into network ROM scripts. And these network ROM scripts, given that the one executing these is the client, so the browser, that client might actually be on a completely different continent than where your server is located at. So this network ROM script is much, much slower at several orders of magnitude than a direct database request. So this means that you really need to reduce the number of requests because they are very, very costly in terms of time. Then another effect is that these requests are also expensive in terms of bandwidth, which might actually be the type of expensive that you can express in dollars. Not everyone has cheap, reliable flat rates for data access. So if you do REST API request and you get a huge response back, the consumers spent with that might be very expensive for the people that are running your code. So if someone is on a smartphone in a third world country where they might be able to barely pay their telephone fees, if you just waste their bandwidth with random requests to the REST API and big responses, that is the type of expensive that actually costs real money to real people. So that's not only should you reduce the number of requests, but you should also try to only ever grab the things that you really need and not much more. Another issue you might face when you try to now use this REST API is that the REST API, in terms of its expressiveness, is purposefully limited. So it is based on the HTTP verbs. So there's a get, there's a post, there's a delete, a delete. And the REST API is meant to deal with resources. So you have a given set of resources and for any resources you have the basic operations like read, write, delete, etc. If you compare this to the type of expressiveness you can do with the database or with the HTTP code, you will see that this is much more difficult to then actually design your interactions, your data requests and so on in a meaningful way and often means that you'll have trouble properly mapping old behavior to this new REST API paradigm. It might require you to rethink some of the assumptions because they're not an immediate fit to how the web works and how the REST API works. The next big change with good work is that it is built on top of React components. So good work uses React as its base framework for displaying the user interface. It is a type of reactive programming where you modify the state and any time the state changes the visual representation of that change is automatically updated because it is reactive. So these React components, they are very modular and it basically means that you build code where instead of having one big piece of logic that deals with all the different interactions, you will split this up into self-contained components and each component only takes only this responsible for one small part of the interaction and then the art is to properly assemble these components and pick the granularity of these components so that the entirety of it creates this new type of interaction that you want. With these components, you can think a bit the change that you need to do. You can think a bit as of when you pass from procedural code to object-oriented code. This is the same as here from your normal linear HTML to React components that are self-contained objects and you assemble these objects. So it's a bit of a similar transition you need to do. But you don't need to start from scratch because WordPress will shift with a lot of base components that you can use to build them. So you can extend them, you can combine them in new ways. So you don't need to build something from scratch. You can start with the base building blocks that WordPress offers. There's a list of reference documentation for these components at the Gutenberg Handbook. So you find it under WordPress.org slash Gutenberg slash Handbook and there's a section on components where we'll see a list of the available components that you can build upon. The next big thing that you need to wrap your head around is the kind of data flow that will be included with Gutenberg. So Gutenberg uses Redux as its data flow underpinning. Redux means that the state and the state changes. They only ever flow in one direction. This sounds very ominous and does not tell you much, probably. It basically means that whenever you've got a given state into your code, you can rely on that state not changing. So you can make the assumption that whatever you've got, it stays that way and you don't need to add any checks, don't need to fear any concurrency issues or similar things. This works by creating a type of circular data flow by having the state always be injected onto the top of the tree of the object hierarchy and the state then traverses this entire object hierarchy and at the end it goes back to Redux. Redux looks at what was requested as changes to the state, applies the changes and then re-injects the changed state in a new iteration into the object tree again. So to make changes, you don't actually modify the state that you get but you create a change request that you pass on to Redux. So this change request will cause the state to be different the next time around you get the state. So it's an intuitive circular approach and you don't ever make direct changes, you request changes and you'll get the modified state the next time around. So to do this, there's a bit of a vocabulary vocabulary that React and Redux use to make a change request, it's called an action. Don't confuse this with the term action that you use in WordPress space. We're talking about a different type of action here. The naming is a bit unfortunate. In most other areas you would actually call this either an event or a command. Most frameworks actually work with a term command because you give an order to the surrounding framework to make a change. Here it's called action in Redux. So we just need to live with the fact that we now have two elements that are called actions in WordPress but keep in mind that this is a different one than one you know from the PHP side of things. And these actions, they are collected while the state passes through your object hierarchy and at the end Redux uses a concept called reducers. So reducer is a piece of code you can provide that knows how to turn a given action and an existing state into a modified state that takes the action into account. So it's called reducer because it takes two elements current state, it requests a change and it reduces it to the modified state. So the state that is ready for the next situation. There's an abstraction that WordPress uses which you can find on the JavaScript package WordPress slash data and this abstraction is basically Redux but with a few changes so that you can use it across plug-in boundaries. Because typically JavaScript is language that you normally bundle so you have one application and one collection of code and that's it and with WordPress that's not the case because you have multiple bundles you will compile with JavaScript. You have a core bundle and you have a bundle for each plug-in and so this abstraction that WordPress provides allows you to combine these multiple bundles so that they can all collaborate on the same Redux. This all sounds very complicated if you've never dealt with JavaScript before. I just wanted to let you know what the paradigm shift is that the state is immutable in the current execution context and we can only request changes for the next iteration and for the details if you happen to be in the situation where you need to implement this yourself there is lots of good documentation you can find on Redux and associated concepts I don't want to go too much into depth. So don't be too much afraid about this complicated way of how state is handled it basically means that you can rely on a few given factors that make it easier to build code that doesn't break at scale when stuff becomes complicated. So this is all very new concepts it looks all very interesting but when you have the current plug-in or the current custom side how do you get from here to there? The obvious choice might be to just rewrite the entire thing with these new concepts but this causes a few issues mainly if you have a business for example while you're rebuilding this your old code is outdated and your new code is not ready yet so you don't want to put yourself into a position where you just bet on being able to make a working product even one year's time because you won't rewrite everything from scratch in terms of business process in terms of cash flow that's just not a good solution so usually you don't want to you want to go at this in a gradual way and be able to always gather feedback all the time always have a working product all the time so we look now at how you can split the rewriting process of your existing code up into several granular steps that build one on top of each other and that always leave you with the working usable result that keeps your cash flow going so first of all the most basic changes you can make is to use server-side rendering server-side rendering is also called dynamic blocks in the Gutenberg terminology and it basically means that yes you create a Gutenberg block but that block doesn't know how to render itself it just requests the output from the server so basically back at what I've shown you in the beginning where the server sends the output instead of the data and the logic server-side render is an existing component that makes this possible it basically works by creating by providing a base block that you can just attach a server-side callback to so a piece of PHP code that will render HTML and every time the block is asked to update itself it will through the REST API trigger a callback on the PHP side PHP will render the HTML that you requested and will send this as response through the REST API back to this block so you only deal with the PHP side of things and you can reuse your existing PHP code so if you have a short code for example that already does its job by making direct database requests and then generating HTML out of it you can just turn this into server-side render component and wrap it into a Gutenberg block and all of a sudden you're already making use of Gutenberg while still reusing your old existing PHP code with direct database access keep in mind that this is meant to provide a legacy opportunity for people to create blocks and it comes with some performance implications because every time your block is rendered it will trigger this callback and you must ensure that this callback is not too slow to have everything grind to a halt this can be done by clever caching for example of the callback so that it does not always render from scratch but only every 5 minutes or similar functionality here's an example of how such a server-side render a block can look so you can see on the top left side that I register a block with a given set of attributes and this block has a render callback attached to it the render callback the value that I put into it it's basically just a PHP callable so here it's a function it could also be a class method or whatever else you want to use at the lower bottom we see a template that renders some basic HTML and in the top right we see our callback that uses output buffering to render this template into HTML and return it to the code that was requesting it and when you now add this code you will see that you will have a new block what did we call it WCSEA and anywhere you put this block into it will request HTML from the server and it will render the template you see at the bottom so I've stated several times now that normally with PHP code you do direct database access and that doesn't work with Gutenberg anymore so this is the main issue you will be facing when you have existing code because it does not only mean that you need to completely overhaul your user interface it does mean that all your logic that you have on the server side is basically useless because it could not possibly run on the client side even if it translated it to JavaScript it would not work because it just assumes that it would have database access that's why a next logical step to be able to move gradually would be to start creating an abstraction for your own code so an abstraction of the data layer basically means that you put a piece of code in between your regular logic and whatever it is that you use to read and write data from this allows you to decouple these two and would allow you to keep the logic going no matter what current storage mechanism you're currently using which is what we have to actually so once you have this abstraction in place and your logic is adapted to only ever work with this abstraction it creates a protective layer beneath this abstraction you can make changes freely and rapidly without needing to fear that you will break some of the logic from the other side of the abstraction I wanted to visually represent this so just assume that your existing code will directly query the database usually by using WPDB it could be worse though that you even directly do MySQL calls or so but usually people should use WPDB when you want to add REST API access to this there's no obvious way to just slide it in somewhere to have part of the code the direct database access and part of the code already be translated to REST API so it's an all or nothing approach basically if you want to use REST API instead it means breaking all the code and replacing everything by a REST API based approach and depending on what code you have that might be a matter of six months of one year of two years maybe of rewriting and testing everything until you have a working product again so if you put an abstraction layer in place all of a sudden the code is decoupled from the database and this allows you to randomly change whatever you want below this abstraction layer and you can even have partial changes so you can have from your 20 requests you can have 10 requests that go to the database still because that's the part of the code that you haven't yet adapted to wouldn't work and the other 10 go to REST API instead because that's the part that you had already modernized so it allows you to move gradually and keep it working all the time here's a bit of a code example how that could look this is of course extremely simplified it's meant to illustrate base principle so instead of doing direct requests for something here we have we have custom post type books and instead of directly using this custom post type instead of directly making requests to the database we create an interface and this interface just states the methods that we need so for example we have a method find all that allows us to retrieve all the books and while designing this interface at first we don't care how this is implemented and then in the first step we can provide an implementation that is based on WPDB and basically fulfills this contract that we set up by using WP query to retrieve all the books and all of a sudden if our logic only ever deals with the book repository interface instead of with WPDB we can make immediate changes to the way we retrieve the actual data in a transparent way without the logic breaking anymore but why use the REST API on the server side now because this abstraction basically means that you haven't used REST API already but you haven't yet written the JavaScript code so what's the point in using REST API on the server side the point again is to allow you to make gradual changes and for example you can already use REST API exclusively on the server side which allows you to model everything to design everything to test everything while keeping everything working and the REST API once it is in place it doesn't care anymore whether you're on the server or on the client so instead of starting with client code and then building everything in a very risky way to make the client code work we go the other way around the way the things on the server that make it server only and by doing that we will end up with code that already uses the REST API it still runs on the server but then it's just a matter of translating it into JavaScript and it will immediately work because we've set the ground work to make it work already here we have another implementation of our book repository interface and this time we call it REST full book repository because we're already using the REST API but still in PHP on the server side and this uses the fact that the REST API the way it is building in WordPress is just by running a lot of objects that collaborate together you can directly use these objects on the server side to make requests to the REST API so instead of making an external request through a URL to the server we can actually directly create the objects we need from the REST API and use the REST API endpoints without needing it to make a network launcher so we get direct immediate REST API access, we can test everything we can model everything, we have a lot of time of our REST API endpoints but all the time this keeps working and it does not even slow down our code because right now we're not even doing network round trips so now we have an abstract data layer we are ready to make the REST API work for us the next step is a bit of a special one because for most of you you will not be able to just say my product from now on will only work with Gutenberg because not everyone will have Gutenberg in every single combination of their site but everyone is able to immediately use it and you don't want to just exclude half of your customer base because they happen to not yet be migrated over to Gutenberg so ideally you want to make your code work with or without Gutenberg so this is what this next step is about if you're now starting to build your new Reactbase Chinese JavaScript front-end magic to make everything work inside of Gutenberg you should think about building it in such a way that you can use this independently of Gutenberg it just happens to use React but it doesn't require Gutenberg to work what does this mean? so with Gutenberg we can imagine at least three scenarios pre-50 sites post-50 sites with Gutenberg active and post-50 sites with the classic editor active and if we manage to reuse our components across these three different scenarios we can reduce a lot of the maintenance overhead because it's always preferable to build something that is slightly more complex and reusable across everything than to have a branching in our codebase where we basically need to maintain two different code bases that target two different platforms this is always much more costly in terms of maintenance and we want to avoid that so an example that already does that is the WordPress SEO plugin by Yoast they did a lot of work to create their integrations in the editing screen so that it's all based on React if you look at how it is implemented you can see for example here in the screenshot this is with Gutenberg active you can see on the right side in the sidebar there's the stuff that the plugin does to help you make decisions and you can see in the developer tools at the bottom that these are React components but if you have the same plugin and you disable Gutenberg you can see that you have the same component in a meta box below your traditional old school editing screen and if you look into the developer tools you can see that it's still the same React components and they are doing this by creating a meta box that provides a container that mirrors the Gutenberg environment it's a very basic abstraction of what real Gutenberg does but it allows the existing React component to just hook into that meta box instead of the Gutenberg sidebar so the component is exactly the same it doesn't need to be adapted to multiple platforms it's just that they spend a bit of time to create a meta box and accept these React components in the same way that Gutenberg does here's a basic piece of code that shows how this is done so WordPress provides packages that you can just pull in through NPM that are the same packages that Core will use starting with version 5.0 but you can already pull them in with other versions inside of Gutenberg and we use the exact same packages and with these packages you can set up an environment that mirrors what you would have in Gutenberg so here it includes this snippet editor for example inside of the meta box basically provides the fill mechanism and the sidebar implementation that Gutenberg normally provides now for the final integration in the long run you want to control the fragmentation of your code so make sure that you try to avoid just splitting up your codebase into Gutenberg and not Gutenberg you want to get rid of anything that is not reusable across all the environments you should keep your codebase flexible because Gutenberg is moving fast we're not yet sure what phase 2, 3 or 10 will bring so you should put yourself into a position where you can easily adapt to change that is probably the most valuable approach you can take and finally once you've covered all the bases think about how to properly embrace Gutenberg make the most out of the different user interface that Gutenberg provides because the user experience that you designed for the old editor might have been the best one you could come up for the old editor but it's probably not the best one you can come up for the new one so the key takeaways re-use existing code through the server-side render component abstract away your data model move it to the REST API build React containers with reusable React components finalize a tight user interface and user experience integration and most importantly stay flexible and adapt to change that's it for me so all the components are based on React to Bases so if it is React to Bases so will it be accessible for using the standard to develop a plugin on using Gutenberg? you mean like using jQuery for example jQuery like JavaScript functions yeah so that will be problematic because the paradigm is a different one so for very basic things you might still be able to pull it off to use something like jQuery for example based JavaScript functions but these generally in your the state model that React uses if you build everything so that it has immutable state and then use jQuery to go in there and make changes nevertheless that would probably need to allow difficult to diagnose bugs later on so it's not a good approach ideally you would work with components they might not necessarily use React but at least you should be aware of how the state flows inside a Gutenberg editor and make sure you're not disrupting that state flow what does this mean for people who are non coders? so for non coders it generally means that if all the plugin authors and the theme authors now do all of this then you need to worry too much about things if you have websites for example that you run it might mean that you need to hire developers to make changes once Gutenberg comes because not everything just works out of the box and depending on what you're using that makes deeper integrations into the editing backend you might need to replace plugins or change some of the custom code so it might mean that you need to spend some time and money maybe hire a developer to adapt your slides to this new way of working for everything you're talking about does that affect mainly just the editing mode or would a page view by a normal person on the internet cause these REST APIs to be called in React components to render for something as simple as a paragraph so for normal Gutenberg components it works that way that the JavaScript logic of the component is only executed on the data side in the editing backend and when you save your page it generates the output for that component and stores the output of the component into the post-content field in the database so on the front end normally you just read the end result so no JavaScript code is being executed it should just work that's how it should behave this doesn't mean that plugins will now do other things that might cause JavaScript to execute or something and it also is different for dynamic blocks so dynamic blocks like I showed in the server side render component they don't store their result in the database they only store the reference to the block they are the block ID and it attributes how it was configured and every time the dynamic block is meant to be displayed it will actually be paused out of the component and this render callback will be triggered to retrieve the real HTML content that will be pasted here so for dynamic blocks they actually incur at least one REST API request because that REST API request is the one that triggers the render callback on the server side interesting talk I'm also not on the developer but could you describe the intent of these structural changes other than the benefits of being able to not have errors that propagate so easily is this more efficient in terms of it's not requiring these websites will not require some bandwidth in the future because so much is happening now on the user end or could you describe the intent of the structural change do you mean structural changes that Gutenberg introduces correct so Gutenberg is mainly focused on changing the editing experience and it's not so much about how it will behave on the frontend actually right now they're still working on optimizing the frontend output so that it doesn't incur performance when Gutenberg is being used so it's all about making a shiny new editing experience that allows you to stay in that editor and have everything be very interactive but that means that while they designed it the topmost priority was the admin backend not how it behaves on frontend of course this was considered as well what it means for the frontend but there's still some things that need to be figured out to optimize it properly because right now it will be slightly less performant than the old way of having a frontend is this going to change the file structure it's really used to like going in and FTPing in and looking at the PHP files and such is this going to be a whole new paradigm of what we'll be looking at on the backend yes absolutely this is one of the main criticisms of Gutenberg actually because it will change from PHP files that you can just modify and neatly see the results more than javascript code that needs to be compiled and bundled before it can be executed so we need to have a build pipeline that always compiles the javascript code if you just make a change in a file it does not do anything because you're not executing the source files, you're executing the result that was generated by your build pipeline so you not only need to learn javascript but you also need to learn how to set up the build tools and build a proper build pipeline that compiles and bundles the javascript code it's certainly a big change from PHP and it is a big change away from what has traditionally been one of the strong points of WordPress that anyone can just tinker with it and learn while building with this new React-based javascript approach there's a lot more steps involved and it's a much steeper learning curve to just get started Time for one more question your basic kind of question but let's say you want to extend an existing block and you just want to have to say button and you want it to have a border or a hover state I saw how you do that but you would have to go through the same with the same build process you don't compile a separate javascript you can just add attributes is that correct? So for basic use cases you can use an older syntax or javascript that so let me step back so with javascript, javascript is in a constant state of flux the language is being reinvented all the time and there's older versions of the syntax that the browsers can directly execute because the browsers have caught on to that syntax and there's more newer versions of the syntax that are not yet directly executable by the browsers because they didn't have the time yet to implement everything so these new types of syntax versions they are transpiled into older versions so that they can be executed in the browser and for simpler use cases you can actually use an older type of the syntax without any bundling and just have a basic javascript file that can directly be executed in the browser and you can then just enqueue this javascript file and then that will work but as soon as you start doing more complex changes this will quickly fall apart because you need to pull in all sorts of dependencies to make this work and in a non-bundled, non-compiled version of javascript you cannot pull in these dependencies if you want to do something very simple if you want to start from scratch then absolutely start with a basic javascript file but there's also another option there's a few ways of creating a block where everything already works in terms of scaffolding the entire setup and you can just put your logic in and the entire build pipeline is already set up there's one called create good and block by amador-wise WPCLi provides a way to scaffold so depending on what it is it might make sense to just use that kind of scaffolding to get you set up with the proper flow and you can already do a minor change and it works and then later on slowly learn what it's actually doing what you've built great talk, thank you Amon