 But I'm going to try to hold questions. I'm going to have some time for questions, hopefully. But yeah, my talk is about Ember and how my team has been using it for Drupal projects for the last couple of years. About two years ago, my team came to DrupalCon LA. And we came with a sort of a goal in mind. How do we solve this headless thing? We had a client who was really passionate about doing something cutting edge. And we also were kind of hungry to learn something new. And we quickly learned that we were PHP developers in a JavaScript world. And we might have been a little bit in over our heads. But luckily, we found something that came with a lot of stuff out of the box and made our jobs a little easier. And that was Ember. Ember, like most MVC frameworks, it's a web app. And I'm going to go quickly through the lifecycle of a page request just to get us started. And then I'm going to talk about the specific reasons why we love using it. But just like Drupal, Ember starts a URL. And with that URL, it sends it to a router that determines where and what sort of controller should render that data. It's got a route to do that. And that route sends its data to a template. And then that template renders with components. Components are that hot thing that you've probably heard about from React and Angular. Ember's got them too. And that's basically all it is. Done. OK, I'll leave. But not really. At some point, you need to persist your data. So as you click around your single page app, you're going to want that stuff to stay around. You don't want to keep querying your API more than once. So Ember has this idea of a model. And that model drives your data. And it persists using a library called EmberData. EmberData ships with two things, an adapter and a serializer. And these things are actually how your Ember application talks to your back end. So for us, we had an adapter that talked with Drupal. And we had a serializer for translating that data coming from Drupal into something Ember can actually use. By default, Ember has its adapter set up to respect JSON API. And you've probably heard a lot about JSON API at this DrupalCon. It's kind of an ongoing discussion. There's actually a contrib module right now. And it's gotten a lot of traction recently. So I would check it into it. But by default, EmberData is going to assume you're using something that's pretty similar to JSON API. And the models that you have defined in your Ember app, the endpoints for retrieving the information in those models, are based on the plural form of your model's name. So if you have a model called node by default, according to JSON API spec and what Ember data is going to look for, it's going to look for something called nodes. And that's where it's going to find your data. So for term, it'll be terms. And these defaults that Ember ships with respect to JSON API performance, and that was really key for us. JSON API at its core is designed to minimize two things. Number one, the number of requests that your single page app has to make to your API. And number two, the amount of data transmitted between the clients and the servers. And the community that's behind JSON API wants to do that without sacrificing readability. And that's what we found is it's pretty readable. If you look here, you've got your ID and your type. And that's at the core of what JSON API needs. That's what it defines as a resource object. But then you have attributes. These are like static data. So you're thinking like created date, knit, tid, tidal body. And then you've also got this relationships area. And this setup was really great for us because it mapped really easily to Drupal stuff. We were stoked on this, and we finally got it working with Drupal. We built a page, and we started kind of low testing it at scale, adding a bunch of content to our page. And it was working. But then we saw how long it took to render out a huge page with a ton of data. And I'm ashamed to say it was something around six seconds, which isn't very performant at all. It kind of defeated the purpose of what we were trying to do. And this is my most embarrassing slide, I think. But we weren't finished. We knew that there was a way to do it. I mean, at the end of the day, JSON API is designed to minimize those requests. We wanted to get that number 64 out of 89 down. And we also wanted to hopefully get this thing to finish in a time that was respectable. So we looked into how JSON API does minimize requests. And it does it through this extra option that you can pass with your responses called included. This included array, you can pass with a response and include data about your relationships. So in this case, you see I've got an article that's like my main response data. But there's a relationship defined to an author. And by default, it doesn't pull this in. But we can set up our APIs to include that author data with our response. By doing this, we were able to reduce our number of requests on that same page down by half. And we were also able to speed up our requests. And this is before GZIP and stuff. So it's still not a respectable number. It's not where we wanted. And it's not where we ended up. We actually got this down to below two seconds. But this is really powerful. And it did it just by default. The only thing we had to do was set up our API in Drupal to deliver that included data, which was really easy because it's just entity references at the end of the day. So Ember respects these relationships in a way that's performant. But it goes beyond just performance. It just turns out to be really good at handling relationships. And it does a good job with integrating with Drupal on that. And it meant fewer lines of code in our API layer. There were a couple of places where Ember code actually helped us to be more performant than just trying to figure it out on the API side. Now I'm not saying Drupal is bad at doing relationships. It's actually really good. In core, we have this idea in Drupal 8 of entity references. And even in D7, entity references may as well have been a core module because it's one of the first things that a developer would install. But the key characteristic that is limiting about entity references is that by default, they're one way. So if you have a node and you're trying to reference it to a term, that relationship is only going to be from the node, the subject, to a term, the object. But sometimes you need to compute that reverse relationship. In core, you can see an example if you go to see how terms are rendered. And they have a display of all the nodes that are attached or tagged with that term. We wanted to do something similar on the Ember side. But how are we going to solve this? Because this relationship is one way. So we were like, OK. Well, whenever we query for a term, maybe we could add a relationship to our API response from Drupal. Terms don't come with this tagged nodes thing. But we could add that, this idea of tagged nodes. We can do that right before we send the response. And hopefully, that's a little annoying. I'm sorry. But once it gets to Ember, we could then query the API for that relationship data. And we could render that reverse relationship. I'm dogged on it. I'll keep going. Well, Ember comes with a cool way to do this that doesn't require us to send extra data in our payload. And we could have done it with that API way, where anytime we crave for a term, we send that tagged nodes data. But Ember supports this idea of inverses. So when we have our node model in Ember, we can define a property to a term that we get in our response for a node. And we can say it's going to have many tags. It's going to be tagged by a couple of terms. On our term model, we can define an inverse for that. So we can define a property that doesn't exist in an API response for a term. But it can still be tracked by Ember. So in this case, we made a property on our term called nodes. And we told it that there was the inverse to be located on the node model. And it would be called categories. So by setting up this inverse relationship, we were able to render the node data on our term display. This is really powerful. This means that you don't have to make your API request be super large to your responses to be super large to handle that reverse relationship. It can just do that automatically. If you load six nodes, all tagged with the same term, you can get that term. And then using a property defined with that inverse, you can act on that list of six nodes as if they were attached to your term without that being in your payload. That means that you can do things in Ember that Drupal Core might not ship with or might be complicated to do. So in this example, we wanted to see whether or not we could see where a paragraph was attached to a node. And so here I'm defining an inverse to a page. And on the page, we define what the relationship is to our paragraphs. By setting up that inverse relationship, we can see from the perspective of the paragraph what page it's attached to. Normally in Drupal, you only see what a paragraph is attached to by looking at the page it's attached to. You can't look at it the other way. So it can support these inverse relationships. But it can also help with reflexive relationships. So by extending this idea of inverses, you can actually work with entities that relate to its own kind. So like menu links or menu items, rather. If you try to render a tree of menu links in Drupal, you'll see that it comes in the database. You've got a parent ID. And the way that it sends that data to Twig is somewhere in the code it's gonna compute what child elements are underneath that menu item. When we're working directly with our API, we weren't really started doing that Twig stuff. We were just querying our data from the API. So all we really had available to us was that parent relationship. But if you think about rendering parent and children elements, it's nice to be able to do it top down. So by defining a reflexive relationship in Ember, we know we're gonna get the parent from our API response. But what we wanna do is we wanna find all the children that are attached to a certain menu item. So what we did was we loaded all of our menu items whenever our Ember app booted up. And by using this reflexive relationship, we were able to do this. In our template where we can basically just render our children from the top down like you would a normal menu. And the reason we're allowed to do this is because we loaded all of our menu items at once. I mean, Ember's only so smart. It's only gonna know about the data that you're sending to it or that it's requesting. So if you only send it three menu items but you wanna render a whole menu tree and do this reflexive relationship, it's not gonna render all of them. It's gonna render only the ones it knows about. So by having the, we had the requirement to load all of our menu items on every page because our menu showed up on every page. So we got away with this. But it was really nice to be able to do this. In the case where you can't and you still have that relationship to find, it will, Ember is set up to go find that relationship. But that means more API requests which was our intention to not do that. So by using this reflexive relationship and loading all of our menu items at the beginning of the application boot, we actually were able to do this nifty thing without having to add extra stuff to our API responses. But this is great. These are nifty things that Ember comes with just out of the box for handling relationships. But until now we haven't really talked about the attributes, title and link and things like that. These are static data. Ember can cast those to certain primitives like string, number, out of the box. But what about like the odd stuff, right? Like everybody's got this situation where they're gonna say like, well it's not gonna work cause the data's weird. Like I can't use Ember. Or I can't render this the way I want to. How's it gonna handle this weird looking data? Maybe I have a custom field. Or maybe I'm using this third party API and it's just like all boarded up. Well that's okay. Ember's got a way to do transformations of data on the field level. It's called a transform. And it makes it really easy to manage your weird looking data. So here's an example of like a list of attributes that we have. And I'm gonna add some here that are custom. We've got like a phone number. Our clients might not wanna enter the phone number in a certain way. Or maybe they're sort of agnostic about what format they wanna use. Maybe it's just a text field. Well that's okay. We can transform whatever phone number it is, whatever format it is into a standardized format on our front end by using a custom transform. And we can do the same thing with meta tags too. The reason we did meta tags in a custom transform was because we needed to act on the data whenever it got to the client side. Before we actually put them on the page. But what this allows you to do is you don't have to rely on your content managers to enter data in a certain format. Although that would be like really nice. Sometimes that's just not the case. You can use transforms to homogenize that data on the front end rather than having to do it on your app level. So in this case I'm just rendering phone numbers in a certain format. And anytime we need to print out a phone number it's gonna be in that standardized format. But transforms also allows you to change your data based on information that's only available once you're on the client side. And in our case we had a requirement to have meta tags be changed by the situation that they were in. So we wrote a pretty long transform but you can get as complex as you want with these. And all it is is just some JavaScript and you implement two methods, deserialize and serialize to do this. But that's transforms. They became really useful for us and we liked them. There are a bunch of other helpful things. I don't have like a ton of time to talk about everything that Ember can offer you. But I did pick out a few things that I found like really, really useful when building out apps. Especially when coming from like the Drupal side. The first is Ember CLI. React and Angular have these too. But the thing we liked about Ember CLI was that it was really easy to just start an application. So by default it comes with like you just install it as a node package and you can just generate a new Ember app really quickly. It'll also generate scaffold code for you. You can obviously create the files that you need in Ember just by yourself. But being able to just quickly do Ember, generate, controller, something was really easy and it would stick it in the right place for you. And then once it was done, you could then go in and actually start working. But that was nice. It was a nice thing to have. Automated testing was a big one for us. It comes with a test command and what it allows you to do is it comes with like a test application built in. It uses Q unit, excuse me. But it can also support Mocha and CHI if that's your flavor. And you can have it do test runs for you just in your console. It also will abstract your NPM like package management so you can install packages using the Ember CLI tool. And as you're coding, you can serve up your app locally and anytime you make a change, it'll live reload your code. And it'll also lint your code for you. So you can see in this example, like I'm just making a new app and you can see it installed ESLint which is as of like Ember 212, that's what it's gonna ship with by default. But you can use other linting libraries out there if you want. Another big one that we found useful was services. These are different from Angular services. Angular services kind of equate to like the way models work in Ember. Services in Ember are actually really similar to how services work in Drupal. In Drupal 8. They're good for data and methods that aren't really attached to a specific model. We used it in our case for navigation sections and being able to show the user where they are in our app. So in this example, we're just adding that little purple and green triangle underneath our menu items. It's something pretty confectionary but it's nice to be able to give the user like that sort of active menu item state. And it needed to work across multiple routes in our app. So being able to have a service that spanned across all of those routes made it really easy to manage that. Other uses for services could be breadcrumbs, handling third-party API requests, or something like web sockets. Another big one, if you're worried about SEO or if that's a big limiting factor for you before you start to think about MVC frameworks is fastboot. Ember's answer to SEO and pre-rendering is fastboot. It's like isomorphic JavaScript. Basically it's a set of tools that allows you to do some business logic based on whether or not your app is running on a server or on your client. The way SPAs work is by default, when you first load the app, your page source is blank. It only really has like a skeleton of what your app's gonna be. And the JavaScript is what does the work of putting the markup in place. But it happens like as you boot up your app. What fastboot allows you to do is when you hit a page URL, it will kind of pre-render that markup that would have been generated by your JavaScript and put it in the page for you. And then once the page has been delivered to the front end, the Ember app will then start up and all of that markup was already there. So you kind of have this perceived performance gain and it also helps with SEO because that stuff is just automatically rendered for Google or Facebook or Twitter. Some other helpful things we found and I don't have gifts for them, I'm sorry. We're API mocking with Ember CLI Mirage. This was like, excuse me, sorry, there we go. API mocking, this allowed us to do small things like we didn't really know what our API was gonna look like but we wanted to get into Ember and kind of play around. When we had some third-party APIs we needed to integrate with, we could mock them while they were being built by our third-party vendor. We were able to drive our tests without a live API which proved really useful whenever we were trying to do tests as part of our CI. We didn't have to necessarily connect to the internet to do it, we could just kind of give it some data and use that test data. And it also allowed for concurrent front end and back end development. So we didn't have to, as back end developers, provide our front end developers with a Drupal API to point to. We could just give them some mock data and they would be totally fine using that and rendering out their components and building their front end layer without having to have a complete API behind them. And they actually really liked it because it meant they didn't have to have a local version of Drupal installed, which was kind of nifty. The second thing is the accessibility community in Ember is really active and helpful. It's one of the best I've seen. And you'd think accessibility and JavaScript might not pair well together but when you're talking about MVC frameworks you get things like data binding and that actually can be a really big help when you're trying to make something accessible. I mean, think about like ARIA roles and tab indexes and wouldn't it be so great if you could just bind that to data coming from your application state and it becomes a lot easier and a lot more convenient to work accessibility into your app from the beginning. And the third thing, Ember as a community does get a little bit of flack for being one of the more quote bloated frameworks out there. It comes with a lot. So it's not any less performant than any of the others but it does have a larger kilobyte size. If that really matters to you, looking at Ember engines these allowed you to basically divide and conquer your app into smaller sections and lazy load them even based on what part of an app you need to load at a certain time. And basically it's just like several apps that work together. So that's not the full story. At the end of the day we still had a lot of things we wanted to do and we're working on them currently like we're not done. The first is we wanna figure out how to do image styles better. Right now we have a model for them in Ember and we're loading data through an API endpoint but that might not be the most performant thing. It means one more API request before we even get a URL for our image. Wouldn't it be nice if we could just deliver that with our node? That means we have to tell Ember about what image styles each node would need throughout the life of its state in the app. So there's some nuances there, we just haven't fully figured out yet but we have some ideas. Redirects too. Right now we're using, like we're doing redirects on the server level which is fine but it's not really robust and it doesn't allow the client to customize their redirects. They have to kinda come to us or they have to use their server. They have to manage the server and add those redirects routinely. So if with a new launch they're fine because you know those redirects but if you have a page you wanna change it's a little cumbersome to have to go to the HD access file or your engine X map and change them. We would like something more robust but we haven't figured it out yet. And the third is a synchronized path structure. At the end of the day Ember and Drupal both need that URL, right? That's like the only thing that they really have to work on because they're web apps. Drupal's got this nifty thing called Path Auto and it allows you to make pretty URLs and you can customize them to your leisure. What we wanted to do was give that flexibility to the front end. We have a solution for it but I'm gonna confess it's a little hacky and it's not something that's fully, fully fledged out but it works for us. And I'm gonna explain it just in a little bit here. Basically we had the, we didn't have something like JSON API that can trip Mauser to work with when we built this but we have this idea of, and it's the last line there, alias path. What we're doing is when we construct our routes for our API we have this idea of an alias path and what that is used by is our parameter converter that we just called title converter and what it does is that alias path allows us to per route, tell us what path auto stream we're working with. Now if we pair that with an ID that we send to Ember for all of our nodes, that's the last part of the path auto alias. Instead of using like knit or a unique ID we just use the like pretty path, just the dasherized version of it. What we're able to do on the controller in Drupal for that parameter converter is turn it into a path that we can just query for in the database. So you can see here we're just selecting from the path auto alias table. This would be really great if path auto was just field on the node because then we could use something a little bit more robust to query for. Right now we're having to do it through a separate table situation but it does work and we can rely on path auto to generate unique IDs still for us. And because of Ember it respects the ID so if you have a term and a node name the same thing because they have different types you're gonna be all right. My team's pain doesn't have to be yours. There's some things to look forward to when we're talking about integrating Ember in Drupal. The first is the contrib module JSON API. It's being considered for a core module and there's a lot of traction behind it and I highly recommend you talk to Matteo and Wim. They're here and they have a lot of great ideas and it's gaining a lot of popularity as being sort of like the de facto API thing to use whenever you're making Drupal be your API. Beyond that if you do end up using JSON API as a contrib module to use Drupal in that way there is a set of data adapters that you can download. I really wanna meet this person. They just wrote these like small adapters that allow you really easily to plug in to what JSON API is gonna give you from Drupal by default. You don't have to do a lot of customization with it. There's a little bit of configuration before that it'll start working but Ember data Drupal is a great GitHub repo that I recommend you check out if you just wanna kinda toy around. And the last is if you were here for the previous talk Ed Faulkner talked a lot about the card stack project. This sort of goes beyond what I'm discussing. I'm just discussing about Ember and Drupal but he wants to take this, he and the card stack team want to take something that's decoupled, this idea of decoupled CMS with its front end and make them seem like they're seamless. Right now the way that my team's been doing it they're a little bit separated by definition decoupled but they don't necessarily have to feel like two different applications and that's something that the card stack team has been working on for a while so I suggest you check that out too. And that's the end. If you guys have any questions I'd be happy to take them. What problem were you guys solving that made you choose Ember JS and why did you choose Ember JS versus the other apps like Angular or React? Sure, so the question was like why did we choose Ember and what problem were we trying to solve? The main problem we were actually trying to solve was a client who wanted something new and innovative which was like the greatest thing, right? When you have a client who's willing to do it it's like I'm getting paid to learn. That's like the best situation. We also did want to learn so coupled with a client that wanted cutting edge we just wanted to try something. The reason we picked Ember started because someone had used it on a personal project so it started just that like seed of like we've heard it before but as we researched it we wanted something that was opinionated at the end of the day. We didn't really have a lot of opinions to begin with. And actually that's something I did cut out of my talk was this idea of opinions. Everybody's got one about JavaScript front end MVC frameworks and they're all like you're all entitled to have them and I'm entitled to have one about Ember. Ember itself is opinionated about the things that it ships but I hope that as you've seen it allows you to do things that are very different and it's not necessarily opinionated as it is and it just gives you some defaults and then enables you to work the way you want. And that's what we liked about it. We wanted something that was opinionated enough for us to ship quick but not opinionated enough to where we were fighting it a lot the whole way. And so that's why we picked it. Thanks. First of all I want to say that you did an awesome job up there especially with the guys working around you. Good job. You said that one of the benefits was that it abstracts the package JSON from what do you mean by that? Oh all I mean is that it comes with a package.json file to manage your dependencies. The way that Ember does like contrib modules is through these things that just calls add-ons. At the end of the day there are NPM packages that you can install and because you're in a sort of a client side scenario you're able to install like other node packages like one that we like to use at my company is the Fetch protocol. There's a polyfill for it. And it's