 So, let's get started building a theme with the WordPress REST API. Why would you ever want to build a theme with the REST API? You know, WordPress has had basically the same theme structure more or less for a long period of time. I'm sure everyone in this room has come to kind of know and understand its template hierarchy and the structure and how queries work. And what I'm going to talk about is kind of a completely different way to do that. So what are the use cases for this? First one is that you actually can do this. The WordPress theme repository does allow themes that are powered by the REST API. The second one is that you're working on a site where the contents has a need to be dynamic and needs to be refreshed without doing a full page refresh, something like news, breaking news, stock information, sports scores, that kind of stuff, or single page web application things. The other one is you want to build a theme that's kind of a reverse mullet where you have your business in back and your party in the front. You don't like writing PHP, but for some reason like writing JavaScript. Or like myself, you just spent the past two years of your life wasting away working on the REST API project and want to be able to show something you can do with it. The requirements to do this are you need to be running WordPress 4.4, which will be out sometime next week or so, where the infrastructure for the REST API is included in WordPress 4.4, and then you're going to need the WP REST API plug-in, any of the version twos, where with that you get the custom endpoints. And in this demonstration, I'm using a few JavaScript libraries. One of them is jQuery. First of all, none of these are actually specifically required to do this. There's a myriad of ways you can do this. This is just the approach I took. jQuery simply because it's easier to show code snippets with jQuery on screen, since it's less verbose than pure JavaScript. Underscore.js I'm using to do the templates, the JavaScript templates to show the view logic and director, which I'm using for client-side routing. So let's see what we're going to build here. This is my theme. And if I scroll all the way down, I have a little next button here to do some pagination, and it loads pretty quickly. I can click on the image in the header and go back to the home page, or if I click on one of these titles, I then get routed to a single page view. Also, if I enter in a URL here, my client-side router actually handles all of this and detects it, this actually isn't WordPress or PHP. So let's get back to this line. So that's kind of just an example of what it is that we're going to build. So let's set up our theme. Again, with the idea of trying to use as little PHP as possible, I have a function to PHP file where all I'm really going to do is enqueue my scripts and styles. I have a logo image. I have an index PHP, which is my only template file, and a JavaScript file to hold all of my routing and callback logic, and then a CSS file. So this is my theme. And in my index file, in my index PHP, I'm going to use the PHP tags, WP head and WP footer, which then allow scripts or styles that I'm enqueuing to then display as well as WP head allows all the document title and additional meta tags to display there. But as you get kind of farther down, in the header, I'm displaying my logo. And then if you see the highlighted area, I have a div that has the ID.js hyphen data. And that's where I'm going to add all of the view content that I'm going to determine based on the routes. I'm using the aria live tag here, which then tells screen readers that as the DOM content there changes, like then read it out to the individual with the screen reader. So that way they know to watch that and then anything that changes, any of the content that changes there, then they know to read that out. So in my function's PHP file, all I have is, as I said, I'm just using it to enqueue my scripts and styles, enqueuing my CSS style, and then registering the director script because that's not bundled as part of WordPress. And my main JS file for my theme, I'm just enqueuing that and declaring the dependency of jQuery underscore. And then the director script, I enqueued just before that. So that's all that's in my function's PHP file. And so let's start scaffolding our JS. Here, if you can kind of, starting at the highlighted area in director, the way it works is there's a route object and you set up each key to the callback you want to use that you want to say if a browser, a window location is detected for here, then use this callback and you can pass in a river parameter from the URL you would like to that callback. So I have, I'm declaring three routes here. One is just straight root or home and thus the root with a page where then that's like the paged parameter. And I'm sending both those to a callback function list posts with pagination that I don't have any logic to find in yet. But then my other one is just slash news and then slash post name as a parameter. So like the post slug with your like the pretty permalinks we're used to. And I'm gonna pass that to another function that's a view post that doesn't have its logic filled in yet either. But this kind of gives me the idea of this is what we're gonna do. And here are the three routes we're gonna handle. This is where we're gonna send versus where we're gonna send people when they hit those routes. So kind of continuing in my main JS file, I'm just gonna declare a few global variables here. One is API URL and I'm gonna set that to slash WP hyphen JSON, which is the, which is the index for any site that has the rest API available and enabled. If you visit that page on a WordPress site with the API, it'll then list out all the routes and all the information there. So I'm gonna store that because I'm gonna use that in all my Ajax requests in a bit. But for here, I'm just going to do a simple click event on the logo where I say if you're clicking on the logo instead of, instead of actually performing the href, instead just let's use our client router and set the route to the root, which then passes us to list posts with pagination. And also does a history push date, so it will update the URL and the browser for them. So it's kind of a shorthand for doing those two things. So just to recap, what I've done here, I've created a theme directory with the file, with some files. I filled in the header and footer logic in our single template file. I enqueued our JavaScript and CSS files in the functions PHP file. And then in our JS, we started getting dirty by defining our routes and initializing our client side router. And add an event handler just on for visitors to click our logo to make sure they can go back to the homepage. So let's start having some fun with some JSON endpoints. And to do that, in the bottom of my index.php template, I'm going to create a JavaScript template. And I'm going to use the script ID here, post-tmpl. And in here, in a bit, I will add all the logic that we need. But first, let's go back to that list, post with pagination, call back, and start filling in the logic. So what I want to do here is I'm passing in a page parameter. And if it's undefined, I'm just going to set it to one, which is the same as my homepage, so there is no pagination, there's no page variable there. And then I'm going to pass that to the API. And we defined the API URL variable earlier, where that's slash wp-json. And the post's resource is wp-v2-posts. Again, if you were to just visit wp-json on a site, you'd be able to get this information. But for the sake of moving along, that's where this is. And then I'm going to pass the page parameter so that way I can use the same function if we're on page two or page three and reuse it. In my AJAX request to the rest API endpoint, this post endpoint, the response, I'm going to put that in an object called output and pass that to my underscore template. That's the post-tmpl with that ID and have it fill in the HTML inside that template. And then I'm going to append the contents of that underscore template and append it to that JS data div ID inside in the middle of my index PHP file there. So in going back to now I need to take that output object that I've now passed to my underscore template and I need to make it so I can display the actual posts that are inside of it inside my JavaScript underscore template. And so going back to the little template, we scaffolded it out a few steps ago and go in. And I'm just going to put an each statement, which is kind of the same as it's like a JavaScript version of the loop. And for each of the posts that I'm passing in from the API response object, I'm saying let's put the post ID on a div so we can uniquely identify information. And then let's put the post slug in a data name so I can do kind of the in-app routing somewhere. Let's set an href so people can get to the individual link of this post as well as display the post title and the post excerpt. And it'll loop through all those and then it would display what I end up with is those displayed. So to recap again, we just created an underscores JS template with the post slash TMPL ID. We then filled in our logic in our list post pagination callback and then we sent a get request to the WP REST API post endpoint and passed the response data back to our underscores template. And in the underscores template, we then added the presentation logic to loop through the posts and the response and then display the title, excerpt, and URL for each post. So what you end up with in the homepage is something that looks like this. So now we need to add some pagination and we're gonna go back to that list post of pagination callback because we're not quite done yet. The way in the API we passed you information such as how many max pages you should expect from something that lists out, something like post or a custom post type is we set a header that's like X dash WP dash total pages. So I'm gonna go ahead and get that as part of the response data from my request to the post endpoint here and I'm adding two variables. I'm gonna get the current page and make sure it's an integer and I'm gonna get the max pages from the response header and then just a few lines down I'm just gonna check and say like, okay, if the current page is greater than one, then on the output data that we're passing to our underscore template from our last step, let's set the previous variable to be the current page minus one and then if the current page is less than the max number of pages, let's also add the data for a next value and we're gonna, just as we did before, still pass that output variable to our underscore template and then just at the bottom of it underneath the each logic that we did before, we're just gonna add a div ID for pagination and then just check and see if the previous value was defined. If so, let's create an anchor link that says previous and links people back, links people back one page and do the same for next. So again, just a recap, added logic to our list post of pagination to determine if the pagination value is relevant and if so, let's just include them in the data that we're passing to our underscore template and then add the presentation logic to our underscore template. And what you end up, there is, so if I go to slash two, then I get the next page in the pagination list and then at the bottom, I get the previous and next links and text there to show. So just one more route here to handle. So let's do the single post display and routing. Let's create another underscores template called post dash TMPL. And in this, I'm gonna display the single post response, but I'm also gonna pass in a parameter that's called that's underscore embed. And what that allows me to do is it includes in the response all of the related post data. So if you've ever like doing WordPress templating, if you're in your single post, you tend to do things like display author information, you know, like an image and their name or you can do things like get the comments, right? And you tend to do that all within your single post template. Well, those are actually different objects in WordPress, like the author data is actually a user object, the comments or comment objects. And WordPress right now and the way we're used to it kind of muddies that all together. And it's in an API, you have to keep your resources a little separate. So when you're displaying a single post, you wanna be able to show all of that instead of making a bunch of requests to the API, you can pass this embed parameter and you'll get all the related data back in the response object. So because I'm doing routing here based on the post name, I'm gonna keep using the post, just slash post with some parameters instead of doing post slash ID, which also would work and then just give you just the one single post object and you could also pass like embed to that. But again, just for this example, because most commonly people wanna get a single post by the post name and not actually by the ID, just showing here how you can do that where in my view post callback, I'm gonna send a get request via Ajax using that same API URL prefix, but then sending the request to WP slash V2 slash post again, but I'm adding this filter name equals and then I'm passing in the post name and I'm also including the and underscore embed parameter, which is that's what tells the API to embed all related data. And then in the response, I'm going to take the first response object in the response, I guess, because we're using posts and not the single one, it actually will return an array of posts, but I only am looking for one post, so I only need the first one, so that's why I'm just using like data zero. And then I'm gonna pass that to my post dash TMPL underscore template. And then again, I'm gonna append that to the JS data container there in the middle of my index PHP template. And this will handle anything that goes slash news and then has a post name. So in my single post template here now, filling in the logic, I just wanna use the featured image and to do that, I'm gonna check if the embedded featured media isn't undefined, then I know that I can display the featured image there and then I'm gonna display the title and then a little farther down, I'm gonna say written by and within the embedded data, I'm gonna use the author URL. The first author I'm gonna use their avatar URL with the key of 24, which is the size of the 24 pixels and then I'm gonna display their name and then I'm gonna end the template and that to recap that just, we're just kind of repeating pretty close to the steps we did for the post one, but just one just for a single post where we're gonna create our underscore template post dash TMPL, we're gonna fill in the logic of our view post callback and send a get request to the WPAPI, the WREST API post endpoint, but we're gonna set query parameters for the post slug and embedding related data and then we're gonna pass all that response data to the underscore template and then add the presentation logic to our underscore JS template that displays the featured image, title, author avatar, author name and content. What you end up with is something that looks like this. So that is it. I have some resources here, so the WPAPI REST API to get the endpoints, there's the link for director on GitHub, as well as I put all the theme files that I took to make this up on GitHub and as well as linked to my slides. I did actually tweet out my slides before we started, so you should see them under the WCUS hashtag and thank you, I'd like to take some questions. If anyone has any? Yes, hi. Hi, so building a theme this way sounds really good, but in terms of using an API, what's the practice for plugins that you would have to add like PHP code on the front end such as ACF or maybe like a social media bar? Sure, so you're asking about ACF as an advanced custom fields? Yeah, plugins like that where you have to add PHP stuff in the front end. Sure, so the way the API endpoints are set up in the plugin is very extensible just like WordPress itself, so we actually give you a function that's like register API field I believe is what it's called and what you have to do is, so ACF uses post meta, right? The problem with post meta is like it's not actually part of the post object and the way people use it is really different. You know, the way you might use it for the site for dry cleaners would be completely different than an e-commerce site would use it and so by default we don't show it, but if you use the register API field function you can add it to the response of your post response so then you could use it. Does that make sense? Yeah, it does, thank you. You're welcome. So using this way to create a theme, what issues would it have with SEO and you know, since it's all AJAX, one call. Oh, it's fantastic for SEO. You get the best link juice this way? Yeah, really? Yeah. No joke. Tweet that please. Tweet? We need people to use the version too. Please, if I bet you if I, if you tweet that I get like, you know, honor people using it, no problem. No, in all seriousness, I would say ask Yoast. I don't know. I'm not an SEO expert and I don't play one on TV. So if your content is your content is there so in the DOM there might be some things you're gonna wanna do like provide, honestly if you provide like no JavaScript fallbacks you'd be covering yourself on the SEO and doing dynamic content for places where you need it and it supports it. People's browsers support it. That really honestly makes sense, thanks. Hey, Rachel. Hi. Thanks, that was great. I can see the appeal of this for doing your own website, building your own themes. I'm a little bit unsure about distributed themes in the short term at least because one of the things that has got WordPress to where it is at the moment is the fact that there are millions of articles telling you how to do things. Right. And when people go and Google something and they find an article saying just edit single.php and it's not there, that could cause problems. What's your take on that whole issue? Yeah, so it's a very valid point that's, I don't know. I could argue that there's a lot of theme frameworks out there right now that kind of do this with magical name their own hooks already. I think one of the coolest things about this is it makes it so the traditional theme structure of using PHP can still exist. And building a theme this way for a distributed, something you're gonna distribute and fully support. I think it's a little early for that right now, but I think all of this starts with people getting familiar and starting to have an idea on how this could and should work where we're always gonna have the education problem and hopefully soon enough the amount of people that are telling you how to do this and what to do if you look and there's no single PHP file, like where then to look instead, hopefully soon that starts catching up and then we won't have to worry about it. Cool, thanks for your answer. Thanks. Hey, Rachel, great job. Come find me, I'll gladly buy you a Diet Coke for your two years of hard work. We appreciate it. So you mentioned the routing stuff. Yeah. And I think that's something like your average steamer might not think like, oh gosh, I have to handle routing now because I'm theming in this new way. So what are some other additional kind of gotchas that you might have to handle whereas if you're just theming in pure PHP that you might not even think about? Sure, so the other one honestly is, and I didn't touch on this necessarily, it's document title, like you're gonna wanna make sure you switch out the document title and all that header information as you change your routes. The other one is just is because there's hooks like the content, right? The way the API works is we run the content on the content.rendered for you. So if you have plugins that are hooking in something like social sharing buttons and that kind of stuff, that all will include that, but if people are hooking somewhere else, I can't really think of a great example off the top of my head, I don't know, maybe like in widget areas or something like that, those are things that by default won't be there. So you kind of have to then figure out, okay, how can I take this information and make it something that's available that I can display in my theme. The other one actually that I can think of is menu navigation, where right now WordPress handles this for you, right? Like on a new page request, it then figures out what the current page is and then like changes that to your, to be like, you know, have like the current CSS class, right? You're gonna have to do that yourself too. Those are the two biggest ones I can think of. Thanks again. Yeah. I'm curious about the embed param and how much stuff gets in there. Considering like the amount of processing to query all that stuff and also the payload size, can you limit what's in there or is that even a concern? Yes, it is a concern. Actually, Joe Hoyle and I were just talking about this yesterday and he actually has a plugin that allows you to like limit what actually gets embedded there. I think as the end points evolve, we're gonna, if you've ever looked like our version two, I'm sorry, if you've ever looked at our version one, the way our post response was, we actually included some author information, category tag information, like that already in our post response. The WordPress.com API does this as well. If you look at our version two, we don't include a lot of, like we'll include author ID, which isn't really useful. Like you kind of, you're not gonna explain like your single post view, just their ID, right? You want like their name and their avatar like I showed. So passing the embed param just for that seems a little wonky to me to get all, like when you pass it, you get like all comments. If you're logged in, you'll get revisions, the categories, tags, et cetera. So I think in the end, at some point, we'll find a happy medium between the two with the end points. In the meantime, as I said, Joe has a way to limit that and I think that's something we're gonna look into supporting directly in the API in the very, very, very near future. Thank you. Hi, when it comes to scaling, does this methodology scale the same way? You can scale WordPress by caching, using varnish and things like that. Well, so you can, you're hitting an endpoint and getting back a response and you can cache this. You can very well cache this with varnish and it would pretty much work the same way. In fact, I would actually say, if you, there's certain things you, with varnish you can't cache, right? Like you can't cache every admin Ajax request and those are really heavy from our performance standpoint because you're kind of loading in most of WordPress admin when you hit admin Ajax and our API doesn't do that. So actually from a pure performance query standpoint, this is a lot lighter on servers and the, since the end points are just on there, you can, you can set cache headers on them and make them cacheable. What's up Anthony? Hey Rachel. I have a two part question. So the first part is, I learned best by taking a theme that's in the theme library and disassembling it to figure out how to work on it. So with- We call that breaking it. Yep. So with 4.4, will we see any of these in the library? And then part two is this a model that will ever see a default WordPress theme that ships with WordPress? Well, sure. So you can create a theme and submit it to the review team that relies on the WordPress REST API. That's allowed in the theme repo right now. I don't think anyone's done it yet. You should do it first. And then I can't speak to what the next upcoming default themes in WordPress are gonna do, but I think this would be very cool. This question just kind of goes on that same line of thinking. Like in a looking down the road for WordPress, does this make sense? The theme that you created here as an example, does that really seem like a future way to use the REST API from a theme perspective? Or does like the way that I've done it before is like building like node apps or something like that that are completely separate from WordPress and just using it as an API for building the view layer for a site? Well, probably the way you did it. Well, so there are two different things, right? Like this is using WordPress, a theme within WordPress and actually not using WP use theme and setting that to false and having your view layer be a completely different location. One of the cool things about the REST API, honestly, is like there's so many things we can do with it, there's like mobile apps, there's viewing information from WordPress in a completely separate app, which is what you're talking about, or using it within the same site and to pull and display data. I think from a popularity standpoint, at a Word camp, I think more people will start maybe possibly here or with some sort of like custom endpoint that they create from like a plugin or something and then display it. I mean, think about like if gravity forms or event calendars kind of things, like they all have APIs, if you can use their, they use our endpoints, if you use them, you can start, submit a form and then immediately show like, thank you, we'll send you an email with when we read this or something. We can do, you can do all that kind of stuff. So I think that's the best place if people are gonna start, but I mean, the cool thing is there's no limits. Guys limit, Jake. Thanks. All right, well, thank you guys very much.