 Thank you. As she said, my name is Dennis Nell, work at automatic and I do a lot of different random software development jobs But I've had the privilege of working on the Gutenberg project this grand vision to modernize WordPress and Rethink how we author content on the web What I'm talking about today Is going to be focused on the user interface of Gutenberg Even though I work a lot more with the underlying data flow that builds that and Gives us a reliable model So I appreciate the invitation to come talk to y'all. I thank you for being here the after lunch shift is Is the hard shift to be on I understand it so I'll take whatever attention you're able to provide As we begin we have to ask what does it mean to extend Gutenberg? I hope you're all here for this talk. It is going to be more dev centric So I apologize if code scares you We need to look at WordPress as we've traditionally built it in order to understand Where Gutenberg is taking us For over a decade. We've had a post editor that has this box this tiny mce editor that has a HTML document inside of it. Well, it's kind of HTML. It's actually HTML and short codes Which means that it's not exactly HTML Tiny mce is pluggable So there's notable extensions that augment it add more buttons add some inline styling But for the most part when we augment the editing experience in WordPress, we do it in the surrounds We add boxes meta boxes. We add fields. We had panels and We add a bunch of stuff That is like metadata stuff that is properties or plain text or Shuffled around bits of information and So there's a really sharp distinction between the HTML and Everything else and as many of you are probably aware Sometimes that anything else is the entirety of the post in fact We have a number of Builders that have come around in the WordPress world to try and alleviate this problem of authoring content and They give users the power to lay out a site pages and bullets and asides and all these things and That HTML block is empty With Gutenberg what we're looking at what we're doing is we're unifying that editing experience We're no longer saying there's an HTML ish document and there's everything else What we're saying is how can we harmonize the different aspects of what make up a post and Edit it in a way that's intuitive and native and visually representative of how the result will be How can we map it to the way that? Authors using WordPress think about their site So we're going to look at some of those things today to work towards that goal How can we unify the editing experience and enhance it in a way that? prevents building division between HTML and everything else To give a quick little roadmap. We're going to talk about some of the What's how's wise when's where's and then we're going to actually live code We're going to build a few things together and look and what I hope to leave you with when you Finish today is an understanding or at least an inspiration that a Gutenberg provides some really Cool new ways of thinking about augmenting the editing experience and be that It's not that hard that any of us can get started And that the future possibilities here are going to hopefully end up speeding up making easier and Making better our extensions So from a show of hands who in here has built the WordPress plug-in excellent of those who has built a Plug-in that augments the editor or the editing page At about half and of those who has built a tiny mce plug-in excellent Quick shout-outs. How was it? How did you enjoy it? Okay, we won't we won't walk through building a tiny mce plug-in I've done it personally myself too and it it's not so bad, but it wasn't designed for it Came from a time of the internet when this stuff wasn't done So what can we edit in Gutenberg? When we're looking at extending Gutenberg, we're not just talking about adding other things The most obvious thing that we can extend are adding new blocks Gutenberg is a block-based editor It's a way of thinking about authoring content centered on rich media types Abstractions on top of HTML Things like the gallery things like shortcuts short codes do already for us, but more specified more formal and more relatable so We can start extending Gutenberg by adding new media types The most basic ones are like paragraphs simple plain text But Gutenberg is built-in JavaScript in the browser and the sky's the limit like you can put anything you want into a block We could add a new block Attach a WebAssembly script that sets up a WebGL context and plays doom in the editor I don't know why but It's there Another one that may seem peculiar at first is Gutenberg has this first-class support for adding auto-completers We've come across the use case that are things like adding a mention a username mention or a Twitter handle or a hashtag Or anything where we want to autocomplete stock market prices a Company directory a list of posts So we have a very succinct API for extending the things that appear in these autocomplete boxes when we type The big one that should alleviate some of the pains we've had in the past is we can edit the editor Chrome and by Chrome I mean the toolbars the inspector panels the things that appear as we navigate around the editor There's editor Chrome for Document-level stuff so like things like analyzing the writing in a document and reporting on it Things like showing a list of images or a gallery that you can search through and find pictures related to a theme or a search keyword And that that kind of global concern We also have block-level Inspector controls where when we're inside of a block maybe we want to control how many columns it renders or how many Characters in the post excerpt we want it to show so we can we can augment the editor with UI for the global document for the block-level things and pretty granular things even hovering on top of blocks and one thing that I think is really quite neat and very fundamentally different is We can extend Gutenberg through augmenting old blocks and What I mean by old blocks or blocks that are already in the system And this is probably the type of edit that is most different than what we've worked with You see because when we're Adding code and PHP to that post up PHP page and its hooks and filters we tend to think about a very linear process of Users on the page writing in their boxes and then they hit update and when it updates It sends all this stuff in html through a list of transforms and then it's stored in the database And sure we can read from post meta or site options and save any way we want to But with Gutenberg The data flow is different the fundamental interaction mode is different With Gutenberg we think about attaching our own code into a live running application And that application is designed to be malleable to be flexible to be welcoming of change So with Gutenberg we can actually start to think about how can I take existing behaviors and existing tools? Add new extensions to that change the way they look enhance their functionality combine them compose them and Interact back and forth not not an arc from start to finish But a back-and-forth process as we dialogue with the customer in real time How does this all occur? well one of the most fundamental things to Reflect on when we're talking about extensibility is a concept of shared vocabulary shared vocabulary kind of makes or breaks Extendability and most of us are probably familiar with hooks and actions and PHP or I'm sorry in WordPress WordPress has the benefit of over a decade of filling out this codex of terms and of meanings We have a filter called the title and The meaning is every time we grab a post title it runs through that filter Well, we've Started by porting hooks and filters the the idiom into Gutenberg So yes, you can actually access add filter add action in the Gutenberg editor But beyond things like plain simple strings with Gutenberg We start passing parts of that application through these filters There's some pretty cool ones like block edit that we're going to take a look at in a few minutes Which is anytime that somebody gets in and edits inside of a block There's a filter for that with the data model of that block being edited There's filters for registering blocks We can use these filters to prevent blocks from appearing Maybe you decide that you don't want your users to be able to add in images or maybe you want them to Only have a few specific kinds of blocks that you've made We can actually interact through the the filters Dynamically add them and take them out and change the experience in ways We never really had the ability to without going way out of our way and that dynamicity or dynamism or whatever is Controlled through these kind of registrations unlike Unlike most of what we deal with in WordPress where we just run PHP code and it goes in the JavaScript side We actually ask the application to inject our own code. We register a new block type. We register a new plug-in It's not the presence of the file, but the action that we take to ask it to Ask it to insert it Where can we learn this stuff it's a great place to start is in the field book or the hand guide Which I had up earlier here it comes Same place you'd always find it before We've got a lot of documentation describing things like the data model and the API of how to interact with this But also and it's a work in progress, but also we have this section on extensibility Where we have the names of the filters and we have description of what they pass and sometimes we have examples Further inside of the github repository that hosts the project itself You'll find in a lot of sub directories a read me that has quite an elaborate explanation of that subsystem and how to use it we Are shifting into this JavaScript first mentality We're shifting into this idea of interacting with a running application and a lot of things are different so these guides can be Can be critical for understanding how to accomplish our goals and Finally the the code in the github project itself is a is a really good place to look and learn Because a lot of the development that's going on is actually using the extensibility APIs that We're developing so for example There's a cool plug-in that comes pre bundled with Gutenberg that will look at each block And if you're able to put an HTML anchor on that block so I think about headings that you might want to jump down to within a page It will add into the block inspector tools The ability to add that anchor for you and what I mean is if we add a heading here It comes down in this box here Vienna word camp That's not part of the block. That's actually an extension that operates on every block. It augments the default behavior Where is this all going? Well, I hope it's not going to doom in the editor That's a really good way to procrastinate, but it's really wherever you want to take it We're at the very beginning of This process of building up the Gutenberg experience and everything is still kind of low-level We're building out the terminology. We're building out the vocabulary We're figuring out and iterating on the APIs to extend to augment to change We need your feedback and we also need people to be building things and learning where those pains are Working in JavaScript gives us a lot of tools that we've never had before tools to abstract tools to enhance and tools to build Libraries to make our job as developers easier and we don't even know what we're going to need yet. We have some ideas But we're not You know, we're we're one year into something compared to ten let's pause and Do some coding who in this room has already built a block in Gutenberg? Awesome two people three people This is all brand new Can everybody see the screen okay has the font size Bit larger, okay We're gonna be playing a fight between text size and screen space When we went through talking about what we can edit in the editor right now What I'm gonna do is I'm gonna run through an example of each one of those so The first way we augment Gutenberg is by adding a new block You may recognize this PHP file the header that defines the the plug-in for WordPress Important point Gutenberg is Extended the same way the wordpress is through a PHP plug-in we in queue a JavaScript file and We register a blog type a block type Everything is connected through a name. We have a system of namespacing by like your plug-in name and then something else For the purposes of this talk. We're gonna be building the extender Berg extension Now we give it a script name and it'll use the standard WordPress method of linking in scripts and dependencies This is all in the documentation. So the fact that you need these script dependence can be can be read We don't need to go through it here If we look at this JavaScript We see the fundamental Smallest block possible That's way too small every block is built from two basic components These reflect the fact that the Gutenberg editor is a modal editor There's a display mode and there's an edit mode Every block that we build therefore has two functions one is called edit and one is called save They both produce Component output that's like HTML. It's like react Under the hood it's react now, but it may not always be it's it's abstracted inside of Gutenberg's own API So you don't have to worry about spending a month learning react and then three months later moving to something else Interacts with a number of built-in libraries to the editor through the WP variable WP blocks WP dot data WP element We register our block type just by calling that API method and we give it some basic properties You know that the name the icons When we insert a new block that information gets merged into Things like these block inserters and Additionally it gets merged into things like this sidebar, which we call the inspector. Of course we can also Use keyboard shortcuts to insert new blocks the edit function gets called whenever we're In the post dot PHP side and The output of that function goes in here There's this concept of like a selected state and a non-selected state Which is just whether or not that's the current block So when I'm clicking on it here, and you see the outline well, maybe it's not so clear on the projector This block is selected, but when I click up here, this block is no longer selected. You'll notice that these Tools up here change and they're dependent on the block the save function is what takes all of our editing attributes content and produces the HTML that gets serialized into the database Under the hood we have this serialization format That takes the concept of short codes, but removes all the headache This is this is something we don't have to think too much about when we're building blocks. Thankfully it just kind of works But the point is we we we still spit out HTML and that gets rendered into the browser. So if we look at this we can see in the editor It says extend a blur, but when we go to preview it it actually says something different there's a couple of Really helpful built-in constructs for interacting with things like those block inspectors The inspector controls and the block controls are predefined components and They hook into what we call portals or slots around the app These are those aspects of the editor Chrome that we talked about editing And all we have to do is create that item Just like we would creating a div or an unordered list and whatever children we send to it End up getting rendered in the appropriate spot So now I hear when we click and we select that block up here We have the block controls, which by the way aren't stuck at the top if we don't want them to But also this block inspector over here Again, it's JavaScript. We can put whatever we want over here We can interact with it it can interact with the block and Lastly with adding new blocks What we've been looking at is called a static block. It's all generated in JavaScript the edit function spits out Components or HTML for the editor view the save function spits out HTML for the rendered page view that visitors see but we can add what we call a PHP render callback and that will Take that block on the server every time a visitor visits that page and it will produce its own HTML instead This is kind of like add shortcode There's a pre-built block called recent posts that uses this and the point is When we're working with static blocks the content of the output is whatever it is when we hit save in the editor But with a dynamic block it can change on every page load So actually if we come in here and add recent posts latest posts It's making an API call back to the WordPress core. It's grabbing the latest posts. It gives us these options I don't have many. I don't have any so it it would dynamically change this but Every time someone visits this page. It actually grabs the most recent posts from the server if we re-examine our output we can see here how We use that render callback function to print out the PHP version Wasn't a lot wasn't a lot of code Auto completers up next are kind of fun What they allow us to do as I said before is to write autocomplete and It looks a lot like registering a block We're actually using this filter which gives us the power to remove autocompleters and they mainly stem from a trigger prefix and A list of options to choose from I think it's easiest to see this behavior than to describe it We can say I feel and our trigger was a colon. It should have been There we go. I Feel and you can see from our code. We added Names and unicode values and Whenever we type that trigger it automatically creates the box for us. I type sm It autocompletes to smile If you look at how little code I actually wrote to get that to work it it surprised me It's handling all of the Letters and searching for us. It's handling the display of the box. It's handling the case where I don't actually want it to so I could say a Just want a colon and it disappears But even cooler than this we can actually add Autocompleters that are asynchronous So instead of providing a list of these autocomplete terms we can provide a function that returns a promise in this case, I'm connecting to the Star Wars API and Making a network request whenever somebody types that trigger prefix and returning a list of Terms that matches the search for a planet or a starship in the Star Wars universe Did you know that Chibaca was from I Use the star P for planet. I know it starts with K There it is because she and Just as instantly I've got an autocompleter that can go grab any resource on my server or any server on the internet Start s for ships. You can see before I typed it even started pulling them up. Let's look for a star destroyer Doesn't have it pretty cool again, I hope what What this communicates is that we have a lot of flexibility with a very small amount of code to add in a lot of custom behaviors that Required a lot of custom JavaScript or a lot of page refreshes in the past in this demo I want to take a look at augmenting the editor with a plug-in a sidebar plug-in over here We have the ability to add items to this menu. I added clippy Now this panel we can add again anything we want to and we can also take over the whole screen if we want to This panel gives us the ability to do a lot more interactivity like think about creating a product for a will-commerce site You need to move through several different steps that all interact with the server or Maybe you want to provide the ability for somebody to look at the places on the earth that are mentioned in that post in this case I I really really miss my paper clip and He's going to take me through this guided tour I Hope you are well and at the end of that it inserts a block for me that it created dynamically I Can go back in here and interact with the contents of those block that block I can keep it up to date I can set a timer an interval and have something constantly changing Come back clippy and again. Let's take a look at how little code this took We register the plug-in and We print some HTML like code if you've used or at least seen jsx with react you'll recognize Stuff that looks like this and we escape into JavaScript and we save props dot name But I'm not doing that here because Every bit of code that I'm showing you has no build step I'm just typing it loading it. There's nothing going on behind the scenes to generate it It's literally just enqueuing a script through WordPress And so that's why I'm using actual function calls instead of jsx, but the structure is the same I've got a lot here, but it's just it's just static HTML and then Basic JavaScript click handlers Now since we're integrating into this running application again, there's complexities You know JavaScript will let you do anything So the Gutenberg project has added some constraints so that it makes it harder for us to do things that we don't want to do Like shoot ourselves in the foot Gutenberg has a baked-in data system That you can request that it manage your application state for you manage all the render cycles for you Sometimes we get into an application and rather quickly we realize that things are changing and we don't know why Well, the Gutenberg data store is based on the Redux library The principles from that where we can track everything that's changing and centralize all this state management to remove that complexity So if you haven't worked with it worked with JavaScript apps that much it may not sound that wonderful to you, but It really is especially when we start building on these interactions doing network calls adding custom business logic We work through three basic components to the data system We create Functions that request a change We create a handler that updates data based on that change and we create functions to compute Parts of that data that we need again Please swing by the happiness booth or check out the docs if you want to learn more. We just don't have time to go through it I just wanted to Present it to say that all of these things are being taken care of at the core editor level So that we don't all have to write our own code in each plug-in So in this clippy I've got basically a number of steps as a list and I just ask Gutenberg to render whatever step is present and Update the step as I go through it. It manages the inputs the interaction and inserting the block I Created that block through an API call called insert block When I put this together, I didn't know that I didn't know how to do that I just knew there was probably some way to insert a block So again running application. I open up Chrome developer tools and I start typing WP dot And now I have an auto-completed list. I'm sorry that's small But I got an auto-completed list of everything that populates that WP object and in this case I'm gonna look Deeper and see what functions are available to me. I can even interact with the system. I'm sorry Thank you. Oh, well you get the idea It's live coding So I can interact with it through the console. I can inspect it through the console I can get auto-complete to kind of help guide me where the documentation is lacking and finally we can interact With other blocks in this last plug-in I'm adding a filter to that block edit action that we spoke or filter. We spoke of earlier And I'm doing some analysis inside the content of that block and I'm going to change the appearance of the block in the editor Based on that. So let's just jump into a paragraph and say I love This is a normal paragraph block by the way. I haven't created a custom block here. I love. Oh I love WordPress It pointed that out to me even though I didn't realize it so I can come in here and fix this and it's happy but Again come back. Oh So this this guy's the limit again when we think about augmenting existing blocks in the application What if you could just go ahead and write a plug-in that would underline any spelling error? Or hopefully we have spelling taken care of but any grammatical error What if you want to add some meta information to the side of each block and say this is the reading level of the content They're in or if you wanted to augment image blocks and say This image does not seem to match the content that you have Side comments like we see in some other online content platforms We can use the sidebar for Adding connections to external services like there's a screenshot and Floating around on the Gutenberg discussions about putting wool from alpha in there Almost like a split-screen mode in your editor or a plug-in to connect to Zotero For all your citations and you can click on the citation you want and it'll sort it insert it into the block This stuff is all pretty cool all pretty Like pretty much at the beginning so Yeah, I see the time here So please get started. Please play around with the code Please interact and actually tomorrow at contributor day We're gonna have a Gutenberg workshop where you can ask questions and get going with everyone else who's learning Thank you for your time Think that'll be the end of the presentation