 Thank you, and I think we need it. It's that time of the afternoon when you're ready to just relax and have a nice, slow talk that doesn't have too much hard stuff, and that's not my talk, so wake up. Hi, I'm Ed. This is my first DrupalCon. I actually kind of worked with Drupal for the first time about seven months ago and have worked on it fairly continuously since then on several different projects, using it integrated with some fully decoupled Ember apps, some progressively decoupled apps. And so I'm a newbie in this community and have been really interested to learn the history and the culture and the software archaeology of a project like Drupal that has been so successful for so long. It's definitely, I got interested in Drupal and got involved with Drupal because I can see that this is a community that's kind of like the community that I spend most of my time in, which is the Ember community, in the sense that it's true community open source with long-term vision and a willingness to come together and hammer out agreements and conventions so that we can all stand on the shoulders of giants, help each other go further. So that's the big commonality that I saw that got me interested in Drupal. And I want to talk about the second thing that's clearly dear to the hearts of the Drupal community and the Ember community, which is that the open web platform is like the coolest software delivery platform we've ever gotten. We probably only get one shot at this. The web has no gatekeepers. Nobody owns it. You can throw an app up there and everybody gets to see it and nobody takes your revenue. Nobody pulls it out of the app store when they don't like you. The web has URLs, which are amazing and give us such a rich capability to deep link from one place to another and form what is the deep interlocking of the web. That's the metaphor. URLs are really special. And it's actually kind of an amazing social hack that we convinced pretty much everybody in the world that they can see a URL on an advertisement and understand what it is and go there. That's pretty cool. And the other thing, I'm about to switch into contrasting this with native apps some more. And when you compare the web to native, one of the ways that the web really shines is when you sit down and you think about the first run experience of getting introduced to a new application on the web. Because you just go there. You follow a link and you get it. And if it takes two seconds to load, we say, no, that's kind of bad. It should really be a lot faster than that. But of course, on a native app, what's the experience, the first run experience? First is the interstitial saying, would you please install my app? Then it's, OK, let's go over to the App Store. Let's say, install. Let's say, OK, let's put in my password. Let's wait for it to download. It's probably 40 or 100 megabytes or a gigabyte. And then it will finally boot. And even the boot there is on the first run, slow for what you would get for a fast web app. It's a very bad experience, a very high friction. But people put up with it because on the second run, they've got reliability and speed and performance and a really rich user experience. And so people keep making premature statements about the web being dead and apps taking over. And that's not true. The web is going to live on. And the web is actually rapidly catching up in the areas where it was behind and staying far ahead in the areas where it was ahead. And the areas of where it was ahead, I already kind of talked about it. That first run experience, the no gatekeepers, the rich interlocking of it all. So the areas where the web has been behind is this idea that we have to have extremely tiny, lightweight experiences with very lowest common denominator assumptions about the technology and the hardware because otherwise you can't reach everybody and you can't be fast. And those constraints are important to think about, but the ground is rapidly shifting under those constraints. And if you insist that your website is never gonna have more than 800K of payload, you will lose the native apps because they don't have that constraint. They ship hundreds of megs. And they're built on SDKs that are hundreds and hundreds of megs. And they have all kinds of capability built in there. Let the developer go further faster and deliver better experiences. So the point of what the web platform is trying to do to be that good is to build technologies that let us ship ambitious applications on the web platform to everybody. And so that means you shouldn't have to worry about keeping your app super tiny. If you have great technologies, like the ability to do a fast server side render of an application that might take a second to boot in the browser. So the user gets their stuff instantly on the first run. We keep that first run win. And then by the time the second run comes around, they've already in the background pre downloaded everything that you could possibly want using ServiceWorker or even AppCache, which gets a bad rap but is widely deployed today and lets you get that reliable fast second run experience that native apps have. So that's the big picture pitch about why you need to care about ambitious applications. So that's the story. You're competing with native apps, native mobile apps in particular. And so I'm here to talk about Ember today because that's the community I've been deeply involved with and we're actively working on this problem. The way I would describe what the Ember community is trying to build is that Ember is an SDK for ambitious applications. In the same sense that you would use Cocoa to make an iOS app and you would use the Android SDK, you would use Ember to build that kind of application. So we're not comparing it to websites, we're comparing it to applications. And there's lots of things that truly are websites and are good as websites and you keep doing the website thing on those. That's really, really valuable. But I suspect many, many of you are writing things that are actually apps or have apps embedded in them and you struggle with that dichotomy sometimes because it's hard to run, to walk the line. If you kind of pretend you're not really an app, you're just a webpage with some parasitic JavaScript floating around, that rapidly grows. And any long lived successful, traditionally server rendered website I see has tons and tons and tons of JavaScript. Many, much of it redundant because there's no holistic picture of controlling it all. So I wanna take an example here. So I have a lot of screencast here of some demos. I wanna take you through a demo. It's gonna go into some depth. My goal here is to show you two things. One is that I'm starting with, this is a completely stock Drupal 8 website. This is thedrupal.com website. I got a copy of it. I asked to see if I could demo it. So it was written by other people, not knowing I would do this with it. It's just, it's obviously it's modern, which is great. That's why I was the main one constraint was I wanted Drupal 8. This was started at 8.0. I upgraded it to 8.1 and did just some minor tweaks to make it all work. So the point is there's nothing up my sleeve. So how do we evolve this site into something that can support those kind of rich application experiences I was talking about, right? We want a steady evolution so we can keep shipping value and features to the users without a big bang rewrite the world situation, right? I think everybody knows why that's not the best strategy when you have the opportunity to evolve instead. Particularly on the open web because the web itself has to evolve. You can't, you could come up with a, you would come up with a much different set of standards if you were reinventing HTML, CSS, JavaScript, all from scratch to do what we want to do with them today. You can come up with something much nicer but nobody would use it. And by the time you implemented it, the rest of the world would have moved on for the five or 10 years it would have taken you. So we're all in this evolution together. So first step of my evolution here is I'm gonna install a module. Let's see, am I just playing? Do I need to click them? There we go, okay. So I'm installing a module, it's called Ember and it does very, very little. Really it's just adding the libraries and in development mode, how I have it here, all it's doing is pointing at a conventional Ember server, Ember development server that expects to find. So if we go and look at what happens when we render our site now after I turn it on that module, it looks exactly the same except it's got some broken links to the, it's looking for an Ember server. And the Ember server is the Ember CLI, the Ember command line tool, the standard conventional way to do development on an Ember app. You'll rapidly find, to throw out all the constraints of a really rich client-side application, you need build time support. There's a bunch of different competing standards in the ecosystem, a lot of them have their own strengths. The nice thing about when you're writing an Ember app working with Ember CLI is that we've got the whole community to agree and so the way everything's packaged, the way everything's installed is all very standard. So there's not a lot of gluing things together. So we're gonna stick with conventions and we're gonna, is it playing? I can't actually see it on my screen, okay. So what you see here is this is how every Ember app starts. You say Ember new, the name of the app, optionally where you want it to go. And so I'm putting it in a directory alongside doc group. They live in one repo, but I actually tend to suggest to teams when they're doing this the first time, you might actually just, it might be even more conceptually clear to everybody if it's two repos because you truly are writing an app. If you were writing an iOS app, you would probably treat it as a separate thing than your triple site. Now the deep integration of the two is very important and this is a progressive decoupling story. This is not a fully decoupled story, but the reason I'm stressing the idea that you have a full application from the beginning is because that lets you take advantage of all the standard conventions of having a standard number application. So we're gonna, so that we've got our standard number application there and let's see, is that it? It's funny, I can't actually see the videos on my screen. Okay, so we stick with conventions. So now when we run our application, we can see in the console that Ember in debug mode is telling us it's present. It's booting, it's ready to do stuff. It's not doing anything yet. And if we start to navigate around, there's two things going on here. One is that every time we navigate the page, of course, it's loading again, it's booting again. And the second is that you'll see when I go to a URL other than the homepage, Ember doesn't know what to do with it. Ember is very sensitive to the URL. That's the whole point of being on the web, right? The state your application is gonna boot in has to be tied to the URL. So next, we're gonna install an add-on that I just shipped called Ember handoff. Good, and I would describe Ember handoff here as analogous to what a UI web view does on iOS. Right, it's the idea that you can embed some existing web things inside your app. And we have an app and we can embed our existing web things in it. So the point of the handoff here is that we're going to, within this browser application, render the stuff coming from Drupal, right? So this is basically like turbo links, basically like refresh lists, with a bit of a different philosophical flavor in the sense that you're not just sending commands from the server and driving things from there, you're really driving flow from the client side application and getting data from the server. So the next thing we're gonna do, this is, and I know I'm going fast and I'm showing some code, the point isn't to memorize it all, the point is to get a feel for the total scope of how much code we have to write to go through this whole little exercise is gonna be very small and then you're gonna see how far we get. So this is a standard Ember router map and what I just did there is put in, this is referring to the add-on we just added. I'm basically saying for a wild card, all URLs, I don't know anything about them here, I want to delegate them to the hand-off add-on. So we'll hand them off to the server. And there's one Drupal-specific thing I did here, which is that there's this hook that says, hey, we've appended some new server content and there I get to call Drupal attached behaviors and this was wonderful discovering all this because Drupal has very nice clean abstractions for doing this stuff because it was already written for the AJAX support and all that. It puts you way ahead of most of what I find out there in terms of server-rendered stuff that has the wild west for how all their assets are handled and this is great because it means everything works. So when we go and boot the app up now and we can open up the network console and we can navigate around and we can see that we're not doing full page refreshes anymore. We're loading everything over AJAX but all the JavaScript still works on all the pages, all the widgets still work and so we didn't have to do much to get here, right? Because, and the reason we could do this because the hard work is pushed into these add-ons and these add-ons are very, very standard and they could be shared by the community so that we could do the hard work once and then you could just be up and running. So this is an inversion of control, right? We're starting our project. This is a progressive project. We're not throwing away our website and making a whole new thing. It's very progressive from where we are with Baby Steps but the Baby Steps have to be going somewhere, right? And the goal is to be able to shift richer, user experiences, better performance. Maybe we wanna make our app work offline. Maybe we want to add rich animations and transitions, things like that. So you're gonna eventually hit the point where you need to have the control happening on the client and so it's actually, as long as you can make that step in the very beginning like this at low cost, there's no reason not to because now you have the option of very piecemeal choosing what parts of your application are gonna be handled where. So that's the idea, you know, progressing toward where. It's toward, it's basically moving toward fully decoupled with the understanding that you might never choose to go all the way there but you always have the option to take tiny steps any place in your application that you need to. So let's take some more tiny steps into letting Ember understand more about this application and have some opinions about how it should behave. So in this, I'm adding two new routes to the Ember router map. Before we had one wild card route that would just delegate it to handoff and it has, you know, this catch all path. The star there literally just means, you know, match everything. But the two new routes we're adding are just much more conventional Ember routes. One for showcases, one for case studies. Those are two content types that are already on this site. They're URLs that already existed. And the only difference between the two is that one of them is basically static and one has a dynamic piece that you can see there's an ID in there. But they're basically gonna, they're fully conventional Ember routes and so you could just go read the standard Ember guides and understand exactly how all this works. Which is a really big benefit when you think about teaching teams how to do these things. Next I'm taking advantage of Ember to generate some of the files that are gonna back up these routes. This whole step is basically just making sure each of these routes knows how they load data, right? And so you'll see that we're basically gonna tell the Ember data system, hey, please go get me this server page. So there's not a lot of complexity here. And you'll find that what you're typically doing is you're adding a line of code here or there to express the behavior you want. This step also gets nicer once we ship a new feature called Ember engines, which will let you just, the first step I did where I just edited the router map, there you would basically just say mount Drupal wherever in many places in the tree where you want it. That's a really nice feature that's coming down the pipe pretty soon. All right, this is my other route, very similar. So I'm gonna keep moving so I don't run out of time. So now here's our application. It still looks the same because the point was that we did the same thing except that we now taught Ember about the routing a little bit so that it has the option to do different things on these different pages now. And to show that I opened up the Ember Inspector which is a browser extension that works in Chrome, Firefox, IE, can remotely debug mobile apps. And it gives you a really rich interactive debugging capability of your running application. But what I'm using it for here is to show what route we're currently in as far as Ember's concerned. And you can see that it's actually changing. So that Inspector is a great example of the kind of stuff you get when everything's standardized because you weren't gonna find the time, and I wasn't gonna find the time to write a whole browser extension just for debugging your site. But of course, if it's very standard, the community can pull it off. The other big piece of finding things in the community is the EmberObserver.com is a really wonderful resource that you can go find what you need. In this case here, we're gonna go just search about animations because that's what we're gonna do next with these two routes. Find the thing we want. It's actually all curated and there's actually a hand review by Katie Gangler who runs this website. She's amazing and goes through the whole add-on ecosystem. It's a huge resource. So we went and decided we're gonna add an animation library. And so you're just seeing the steps that required to do that. So we're writing some animation rules. Can you guys actually see any of that? I know we're mostly just trying to get the flavor. You don't have to follow every character. The point here is that it was very declarative and that we're able to say these kind of things about our application. We haven't changed a single template. We haven't touched the DOM to make anything different. We just expressed an intention. So let's see it run. So keep in mind that the two routes that are animating are from here to there. There's the fade, right? And that's the only thing that's animating on this pass. So let's make it cooler, right? You'll see the fade again right there, okay? So that's nice, right? That's kind of cool. That's not something you can normally do. Let's take it up a little bit. So let's change it so that it alternates. The reason that it's such a thing as use and reverse here is because there's a directionality to the constraints we put on this row. We said from to. So that's how we're able to know which way it goes. And let's see that one. Okay, yeah, so thank you. So this is a very rough level of animation, right? This is just kind of the very first draft. And if you sat down with a designer and a developer together and put their heads together for an hour or two, you can make this really, really nice. And the kind of things, the reason this kind of behavior is important is because of the way our human brains work, right? Computers are very abstract. You're navigating through a very abstract space when you're moving through a rich application. It really, really helps to have spatial metaphors, right? So things in the physical world don't just appear and disappear, they go somewhere. And if you can feel like you're going somewhere on a journey, that's a real mnemonic help to your mind. It really helps users not get lost. So let's take it up one more level. What do we got here? Oh yeah, okay, actually I was supposed to point out a bug on the last slide. That's why we're adding memory scroll. So I don't know if you noticed, but we're losing our scroll position. And yeah, let's watch that again. Who do I talk to me not looking at the screen? So watch when we go to the lower one here, when we do red hat. It's nice when we go over, but when we come back and notice the back and forward buttons are making the animations work correctly, but we lost our scroll position, right? That's the bug. So that's why we're gonna say, okay, let's jump, let's go to the add on ecosystem again and get an add on that knows how to fix that problem for us. It is the kind of thing that you get for free when every page is a hard refresh. Now you kind of have to manage it. That's the blessing and the curse of having this level of control. So we're gonna go and add this memory scroll add on. It's gonna give us a new component. We're gonna drop it in our template. And let's see. I will definitely be posting all these videos so people can follow them at their own pace too. I realize it's a little fast and disjoint. So now we still keep our position. Okay, great. Okay, so that's a kind of nice illustration of the power you get once you have a client-side application running. All without having, we didn't change anything at all in Drupal. I installed one module, right? That just added some JavaScript. So next step, I am gonna go touch Drupal a little more and I'm gonna add some stuff to some templates. Just some data attributes. A little, a small thing that's gonna make it easy to do the next animation, which is we really wanna be able to target specific things semantically. We wanna be able to express a rule that content on one page and content on another are semantically related. That's why I added those data attributes. So this is the most complex, this is the most complex animation I'm gonna show you. I won't go further than the sign you. But the intent is that we're gonna find, whenever we're transitioning between these routes, things that match each other. And that's what the explode rule here does. It explodes out the pages and tries to find pieces that go together. And then it's gonna delegate any matches it finds to another rule called fly to. So, and this final step here is what happens to the things that don't get matched. So basically the background. So let's see that one. All right, so this is how we beat native mobile apps, right? Because they get this stuff in their SDKs. That's what we need to build. That's why we need these kind of things. So, and we might as well, for completeness, we're gonna just copy that block and do the reverse too, so it goes back. And that just basically means flipping two bits here. The moving side thing, by the way, is just basically we have an old and a new state that we're comparing, which one flies across is what we're deciding there. So in this case, you really want the bigger image because that's gonna look nicer. So now it goes both ways. And notice I can do it with the forward and back buttons or with the links. It's all actually driven by the URL. There's not like click handlers here, right? It's all driven by the URL. So this is one kind of progressively enhancing an existing application. Let's go more baby steps. How would you choose to start implementing chunks of the actual DOM here within Ember if you wanted to get, to move some of that functionality to the client for some kind of rich behavior? So here I'm adding one element to a Twig template and this is probably not how we wanna do it. I think what we really wanna do is use the progressively decoupled blocks module to drop a block here, right? That says, here's where I wanna put this Ember app. And it sounds like I just need to integrate those guys because they've already done all the work for that piece of it. But in this case, I'm just dropping some stuff into a Twig template and I'm binding in some state. I'm naming which Ember component I wanna use and I can pass arguments to it. And then I'm adding one extra thing. So what we're looking at right here is actually the top level template for my Ember application. This is basically just my one hook for that handoff add-on to have an opportunity to stick things places. So far I hadn't really been, I hadn't stuck it in any templates anywhere and so this is a fairly clean public API way to be able to inject content. You need to be in a template somewhere. So we're putting essentially what looks like a tag at the very top level template or application. It doesn't generate any DOM right there. It's more of a behavior. But I'm showing all of these little details just because I actually wanted to show all the steps. I'm not hiding steps here. I mean, I'm hiding like CSS, that's it. Well, yeah, that's it, right, yes, yes, yes. It's not a small thing, but it's very small amounts of CSS. It's not like key frame animations or anything like that. That's all in the JavaScript. So it worked because it made us get an error. So now when we render this page, we see an error that Ember says there's no such component, right? So it's good that it found it, that was the point. So now we're gonna generate that component. We'll say Ember generate component case study editor. And I called it that because it could conceptually evolve to replace the thing that's already on the page there. That's running the case study. So we'll give it a template and we'll bind in some of the actual argument it got to show that it's there and it's there. So that's good. So now this is a case where it's gonna render on the client after that HTML has come across. And, but I wanna point out it that doesn't have to be that way. All of this works nicely with fastboot or any kind of server-side rendering. The idea being that if you want to run node infrastructure in front of your Drupal infrastructure, that HTML could already be in the page when it hits the client. So that even somebody with JavaScript off still gets that chunk of content. It can be a fairly transparent process as far as Drupal's concerned because, conceptually, the browser has everything it needs to know to take the JavaScript and the data to put it together and get that DOM. You can just do that, move that step one step closer into the cloud. So let's, but let's make this thing actually get data and really talk to Drupal in a meaningful way. So I'm gonna install another Drupal module. This is the second one we added. The first was just adding the libraries. This was actually a JCNAPI implementation I'm working on. I want to make it an official project. I heard there might be, I don't know if I'm floating around and I'd be very happy to collaborate. Come talk to me if you've got one. JCNAPI is a standard, relatively young, younger than HAL, which is often compared to, and tried to build off of some of the things learned by HAL. It's a bit, it's more opinionated in the sense that it specifies more things and it talks a lot about the kinds of, both read and write operations that are allowed and how they should happen. And by standardizing on that, you get really nice properties in terms of the, plug and play ability of code on the browser and code on the server to talk to each other. So that's JSON API. Now that we've got it, I can't actually see what's we're cutting. Okay, so I'm adding another add on here. This one's called cardstackcms and I was, as soon as I named it, my collaborator pointed out it's a terrible name because it's not a CMS. It's more of a tool for talking to CMSs. It's called cardstack editor. I wrote it along with a group of great people where we are cardstack syndicate. We're all really independent developers, designers, strategists who come together to do big projects together and often try to work on kind of stuff that will push forward open source ecosystems. So we tend to do take on projects where the client is happy to get their product built and generate a whole bunch of open sources as a side effect. So this is an example of that. So yeah, so we've got nice toolbars and stuff now. Now we're gonna mark up. This is, so this is, I'm gonna just drop this template on you. It's the most complex one you'll see. This is where I'm actually using that library to do, to say I have a CMS editing capability here and I'm gonna pull fields from the CMS and bind them into the DOM. A cool feature of this, well two, two cool features. One is that you can, at compile time, take out all of these annotations so that the DOM is perfectly clean. But the other is that even for an editor, the DOM itself is perfectly clean. All of these, this markup is purely behavioral. The running, because you've got the running JavaScript on the page, you can keep references into the DOM without having, there's no container divs, right? There's no extra markup just to support editing. So you don't break your CSS because the editor view and the non-editor view are different, they're all the same DOM. And so once you have that, now the editing tools are aware of that content and they can interact with it. And so we can actually go and if we flip editor mode on, we can actually touch the page itself and get those fields and edit them. And when I hit update here, it's really going all the way back to Drupal. That's a JSON API patch. I'm gonna switch over quick to another piece of demo which is that I have a full, an actual application that we've shipped on this kind of technology. I'm gonna see if I've got enough internet to make you look nice. So this was the client, the American Institute of Architects was willing to take a chance on us building all this crazy stuff for their reinvention of their online experience for their members. And so what this is, you could go to this URL, it's a real site. It is all fast boot rendered. So if you hit it with JavaScript off, you get all this content. But it's a full, this is a fully decoupled umbrella because we're starting Greenfield. But if I go to the logged in experience, so here's a case where I'm already logged in. I can go there here and activate those tools again. And you can see much more richly. These are all the fields coming off the content types in Drupal. The fields on the right here discover dynamically based on what's in the template. So they're not necessarily 100% of what's on the content type. The UX strategy here is that some things you always need, and they go under editorial if they're something that doesn't go in the template. So I can choose to, like if I go to an editing on here. Remember not to save this because this is their actual website. I've got things here like, this is actually talking to, these are actual, this is a real taxonomy coming out of Drupal. I can add and remove things. I could search for things. All that stuff. That's all powered by JSON API talking, fetching taxonomy terms and vocabularies and all. These also are basically all driven by taxonomy. So a site builder can go and change taxonomy and change these controls. Certainly this is not the end of the end game for where I think Drupal can go with this because this doesn't give the level of flexibility to a site builder that you'd have if you were purely server rendered. The pitch here is that to go and do something, to go and make ambitious changes, you do end up writing templates, handlebars templates. You shouldn't have to write code. You just need to do handlebars markup which is pretty comfortable for a designer if they get somebody to help them get started. That's an area I'm really excited to push further. You have really dead simple out-of-the-box setups so that somebody who's comfortable with HTML and CSS should be able to jump into an application like this and do anything to it. And I think with things like decoupled blocks and all that stuff, much, much further in terms of plug-and-play. This can also be viewed in all the other formats that it comes in, the cards and different devices and stuff. Here's my content library. It's gonna, I don't know if the Wi-Fi here is fast enough. Oh, here it's finding me. This is all the recent stuff that's unpublished. We can go find it. And I can create, these are all my content types that I can create new ones from here. So it was a pretty cool project. We were really grateful to the organization for taking a chance on this technology, really is paying off. And as I said, it generated all this great open source because the underlying tools are now, we're open sourcing them. So I have links here on my last slide to the things that are already open source here. Oh, now I'm playing again. Going forward. So handoff is the thing I tell, is basically what's implementing all of the turbo linkious refresh-ish behavior here. I really wanted to actually just build it off to the existing refresh-ish module, but we need to do a little integration work to make that work. I think we'll still get there. Cause we can get a little more efficient than we are now. It's right now completely agnostic about Drupal, which is actually kind of a positive from the perspective of it actually you can, the module encodes some things that are specific about Drupal today, but it's very small amounts. And it's actually just speaking HTTP. Hey, great, we have standards. You know, HTML is pretty standard. You can actually fetch it, fetch a blob of it from the server. And the semantics are well-defined enough to pull out the scripts, do the right thing with them, pull out the style sheets, figure out if you need to insert some, take some away. So it's pretty cool. Cardstack CMS here, as I said, it's kind of a bad name. We'll probably call it Cardstack Editor instead. That's all those toolbars you saw and the overlays that highlight where your content is. And last of course, EmberJS, because it's all a very stock Ember app, very much by design. So I think that leaves me some time for questions. Yeah, if somebody wanted to just hit the mic. Thanks. So if you wanted to play with the version of Drupal that you had just demoed, is that available someplace? Can I ship that code? It's not my, it wasn't my kite, but yeah, okay, I will absolutely post it. Sure, I just didn't know, because I just think, hey, here's a dump of the site. Oh, that one. Drupal.com. Oh, I gotta check. So we gotta check. I can certainly, all the stuff I wrote, I will certainly can share. I will rip out and share, because that's the interesting part anyway, right? I didn't do much with the Drupal site. Absolutely. You're just using stuff. I did, yeah, I upgraded Drupal.com to 8.1 for that. And not even like I needed any features, it was just, well, I was trying to use refresh lists and refresh lists needed it. Oh well, but it wasn't that hard. So I definitely have more code to share than I shared here. But I don't have a link to the JSON API module and I really want that. So I know I just wanna work with actual Drupal.org to get it on there. We should just do that. Yes. I was wondering if you could comment about versioning in Ember. And just like how that works. I think that's one of the biggest cultural differences for Drupal developers and it might be useful for people to hear you over the chat. Yeah, so you said versioning, right? Yes. So Ember took a key from the way projects like Chrome release where they've got channels and a very fixed schedule. So there's canary releases of Ember basically all the time, weekly at least. And then we do, we'll branch a beta basically every six weeks. And then that would go through a beta cycle where there are weekly updates to the beta cycle. And then after the sixth week, we've ironed out enough of the bugs that it goes to stable. And so there's a stable release basically every six weeks. Now that said, we know that's a really fast cadence for a lot of people. And so we also have long-term support releases which are spaced out much more and you basically end up with, and these are even firm, these are basically semver minor releases. So they don't actually break anything but we still support them at least 18 months. And the ones that break things, the actual major releases, we've really only done that once so far and we don't really want to do it again if we can avoid it. There will probably be an Ember 3.0 but we don't have to rush. We have a lot of, we've built on a lot of capability for ourselves to strip out the things we don't need. That's really our goal so that you can pick and choose. So compatibility-wise, we're very, very serious about not breaking people's apps and we're really proud that most of the ecosystem has been able to keep up with us. We just did a community survey and like 70% of the people who responded were up into the 2x series, which was just great, especially since we all feel like we could have done even better at the 2.0 boundary but it worked out. So versioning is very serious. I encourage you to check out the builds and release pages on emberjs.com because there's all kinds of docs about the process and how things happen. Yes. Hi. Just wondering if you think there's any possibility for template system agnosticism in emberjs future. Handlebars looks like a very friendly templating system. It looks pretty similar to Twig. I'd be a little bit concerned with two templating systems that are very close but not quite the same. Right, exactly. Where it could be confusing. So the syntactic differences are very small and people have at various times supported alternate syntaxes with ember. There's none that are really kind of live and active right now because the people who cared about them didn't have the time. So today it's an upstream struggle to try to have your own syntax but it's getting a little easier because Glimmer 2 is the name of the new rendering engine that's currently in Canary and we're working on. Having caught the, listen to mostly just to the end of the last talk, it was very much the same themes. Everybody cares a lot about performance on front end rendering and there's only the constraints of performance are pushing everybody to a convergent solution. We have a very aggressive pre-compiler that happens at build time. We have a JIT that runs at runtime to optimize templates. Templates are actually, there's an opcode VM that actually emits the code that alters your DOM in the minimum possible way and while it's emitting that, it's emitting the update code so that it knows what could possibly change in the future. There's, if you're curious about Glimmer 2, there's some extremely in-depth head spinning talk from Emercont this past year with Godfrey and Yehuda, you can check it out. I brought that up though because Glimmer 2 is a much cleaner low level abstraction than its predecessor and I think it's gonna stay that way because we've learned enough like this one is really actually good. Good enough to expose this public API so the goal is that there's a lower level API to use for expressing Ember templates that is lower level than handlebars which would make it much easier to support an alternative syntax. All that said, the syntax isn't really the hard part, it's the semantics, right? So the hard part today of making twig stuff work on the Ember side is actually the semantics of the data and the helpers and the functions and all that stuff. So that will be work for sure. Overall, I think it's very, very clear that you will either always have nothing but twig or you will have twig and something else for a long, long period of time because a cutover's not possible, like that's the evolution story, right? So as we think about how to, we need to think about what would be a wonderful, perfect vision but also what would be step one. And I think step one probably involves two templating systems, that's my guess. Yes. I just had a question about the card stack CMS. The live editing is really awesome. Does that take into account any kind of revisioning system within the CMS? So today, I guess it is actually, yes, the revisions are visible in Drupal. So it's using, it's very similar to the kind of way the rest, existing restful services module would manipulate entities. And somebody who knows those way better than me can correct me if I'm wrong but you get revision history out of that, right? Like a new revision for each field edit? Well, that's actually why we chose not to auto sync every single thing, every single keystroke. Cause that's an option here. We can do that. But then your revision history is insane. That's why you have the big blue button for update. And so that would create a checkpoint and you would get revision out of it. But you absolutely should. There's no reason it can't. I don't know off the top of my head if the existing one does. That JCNN technology definitely needs work to be production quality. Like there's no configuration capabilities yet. You have to go and tweak stuff to set it up where you want it. Thanks. All right. Wow, nobody asked me anything like in Cindiary. Like why aren't you as good as React? And mostly that comes down, mostly that comes more down to like the structure of communities. I put my weight in with Ember community because of the philosophy in the community, more than the technology at one point in time, which six years ago when I was going to start it was very different technology. So I put my bets on people and shared values and philosophies and that's why I'm happy where I am.