 I'm Kevin Triplett, and this is Nick Sutterer from Germany. I'm from Austin, these brothers. We're going to be tag teaming today. And this is a ruby test case, a case study on if you have something written in ruby and you don't like the features of it, go make a library that makes it much better, make your life simpler. So that's what Nick did. And I found it, fell in love with it and wanted to share it with you all. But this is really a good strength of ruby. So I know a few people out there probably do web applications. And you probably recognize MVC. And of course, we love MVC. Any time you can organize your code, it's good, do it. And so that gives us skinny controllers, fat models. We don't have anything for views. But maybe we hate me. We just like MC. It seems like, well, I want to change that. I wanted to kind of share with, I found this super exciting because I'm writing a pretty complicated web app. And I wanted to use Ajax and Webby 2.0 and all that good stuff because it just makes the user's experience much better. It gives you sexy views when I'm about to present to you. And that's really not only sexy for the users who are using your application, but sexy for y'all because it makes your views very organized. You'll see in just a second that what we do is with components. Oh, I forgot components are dead. Starting in Rails 2.0, they killed render component because according to the Rails docs, you don't want to use components as a way of separating concerns inside of an application. I mean, you don't want to have reusable components inside your application. That's just not a good way to do it. Components are a special purpose approach that can be replaced with better use of partials and filters. And I'll get that all the time. I said, why aren't views better? Well, just use partials and filters. It's no big deal. We do it all the time, right? Wrong. At least in my opinion, just opinionated. So let's take Rails, for instance. Rails gives you a nice organization. It has controllers, models, views. And inside the views are different controller directories. For instance, users, it's pretty. You've got one file per action. Maybe you have a partial for handling the forms. Or maybe you're smart where you put the forms, edit, and new all in one file. It's really nice and organized. I love that. Oh, but then I've got this complicated application that schedules resources. It has users, equipment, product. This is the administration interface. I have tabs. In the tabs, there's forms and forms and forms. Oh, crap. And this is where I ran into the wall. I said, this is not going to work, because it's just me doing this. I've got all these partials. And I tried to organize it by putting tab as the first word so that they would all show up in one place. But then I had to have stuff for the tabs in other places, because there are things nested within those partials. And this is just one controller. For instance, in my application, I have today's tasks. And that's not associated with that controller. It's on every page of my web app, because I want to be able to see what I'm supposed to be doing today, or what somebody's supposed to be doing. And so, OK. Somebody said, we just put in a partial. That's fine. You can do that. But then I got looking at the way you write a partial statement. And it's ugly. It's just ugly. We're passing in a hash and a nested hash. And only that. Render is fine. Render is understandable. OK. Passing in a partial, there's the partial name. And then if we have local variables, we pass to the end in another hash. But this doesn't look like the Ruby that I love in models or controllers even. So somebody said, well, just wrap it in a partial wrapper. If you don't like looking at a partial render statement, then just wrap it in a wrapper. And this is what somebody gave to me. It's kind of nice. And so you use it this way. It's still ugly because now we've got this non-standard way of calling a partial. It's just still, I don't like it. It's better. It's a little better. OK, what about variables like that task panel? There's a variable associated with that. It's not static. I get that from the database. So every controller has to be able to initialize that variable. Or if you want to do it, you can put in an application controller in Rails and have it before a filter so that when the application runs, it runs this filter, initializes that variable, and makes it available for all of your controller views. Oh, yeah, but if we don't like globals, that's the good reason because where is that global? Where does it exist? Is it going to be mucked with in some other way? It's just not a good solution. It is a solution. So the idea for Ruby, and I'm sorry, making this a Trojan horse is kind of like we're talking about Rails. But it's really a good example of how Nick took Ruby and made something very simple because he didn't like views. He didn't like the way that Rails implemented views. And so he created this library called Cells. And it's your first step toward widgets, which is what Nick will talk about in the second half. It's a gym, which is really nice. That's the current standard. And not only Rails, but it works in Sinatra and soon Padrino. And this is the nice part. It actually has a test suite. A lot of Rails plug-ins and gyms don't have good test suites, but it's being currently developed and added to. And that's a really good sign. So what does Cells do? It gives you a new directory called Cells. So again, back to that organization, you know exactly where all your widgets are. It's in one directory, in the app directory. And not only that, but each one of your Cells has a Ruby file plus a folder that you can put all of your view files in there for each one of the actions. So for instance, how that works is originally we had this render partial thing, let's say today's task list. So you go to the console to generate your cell. It creates this directory unless it's already there. That's where all your cells reside. Nice organization. It creates the Ruby file. And we'll see that in just a second. And then it creates this other directory. And that's where all your view code resides. Again, really nice organization. There's the action or the state that I wanted to make a view for. I specified that on the console line. And also like Hamel, so I pass in the Hamel keyword. It works with almost all the different display engines. All the engines that are supported by Rails. And nice, it gives you tests. And you're going to love that part. We'll get to that at the end of the presentation, because tests are very important. OK, so now you call render cell. You pass it the cell family or whatever. And the action or the state that you want to display. Now, what does that cell look like? It kind of looks like a controller. You can use your standard helpers. And there's the state. You can have multiple states in there, so that you can draw different states for your cell, depending on what it is. For this real simple case, we want to keep it real simple. You initialize a couple of variables that are going to be used in the view. And then this is nice. You call render. How many people get the double render error in Rails? You can render as many cells as you want to go crazy. Cells within cells, you call render, and don't worry about double render error. And that's one of the magical, beautiful things that Nick did in using Ruby. So back to the cell that I've got on all my webpages. There's the view code, and it's real nice. It's real contained. You can do everything you want to right there. It's not mixed in with a bunch of other junk. It's kind of like a partial, but it's in a nice directory organization structure. And by the way, cells can also be namespaced. So if you have a complicated web app, like mine is going to be by the time I'm finished with it, it'll have nested directories and namespaced directories so that they keep things nice and organized. And then, of course, the Hamel. This is the Hamel code for generating HTML. And you can see what I'm doing to create that little widget there on the side. So this, I like it very much, and that's why I wanted to kind of present it to you all. Hopefully, this may be worth the conference for some of you all that are doing these kind of apps. Caching. The nice thing about this, just would go this over quickly because we don't have a lot of time left, but it doesn't do strict view caching. It does no fragment caching. You can actually specify the cache that you want inside the cell. So for instance, in the case you have a shopping cart, you can say, well, it expires in 10 minutes. Or you can call, you can pass it a block. And in that block, you can do anything you want to to be able to expire the cache. Testing for the win. This is, I love this, you can test your cells in isolation. I mean, people can't test their partials. I mean, I love unit code testing, but I really can't get into integration testing and the view testing. But this is really simple. You just have a test file per cell. And in there, you can test a state, render the HTML, and then check it and see if you got what you wanted. And it can't really get simpler than this. Ah, but there's more. Again, no double render error. You can nest cells within cells, call as many cells as you want to, go crazy. There's view inheritance where if you have a standard widget, but maybe you want to inherit that widget and change it on another controller or another view, you can do that, it's very object-oriented. Again, nested cells. And you can package your views, your cells, as an engine that can be passed between applications. So that's handy if you want to share your work with somebody else. And now, but Rails are very simple. And the really powerful of Rails is it comes with Apatomo, which I don't know if Nick will tell you what Apatomy means. But maybe we'll leave that as an exercise for the reader. Yeah, you can actually Google it. Yeah. But this is going to be interactivity in the next step. Thanks, Kevin, for this great talk. What about some applause for this guy? OK. It was for you. All right, so can you guys hear me? Because I can. So we got that rendering part about cells. And I will talk about interactivity, how to make your cell act like a real widget, where you can send data to the server and back, and which updates on events and stuff like that. So basically, Apatomo is, that's the framework I'm going to talk about. It sits on top of cells, and it provides interactive widgets. We also have some optional statefulness for the guys who want to have fancy stateful widgets that keep their inner states and keep their structure. Usually, I don't need that. And then we have a very interesting event system in Apatomo, which we are going to discover now. And I really love, I start really loving Apatomo. So I did a browser game with it, like a small example. Then there is some guy from Canada, Paul actually, who did a real complex back-end application. So Apatomo is perfect for building rich user interfaces like having forums and different lists and, I don't know, all these fancy web 2.0 stuff. Then it's perfect for building dashboard applications in Rails. I mean, how do you do dashboards in Rails? Hushalts and Ajax and yeah. And yeah, that's a very new example I got from some user from, I think he's from Monaco. He did some little widget about you can add nodes and you can sort and page these nodes. And it's all handled with widgets and via Ajax. So our domain widget we are going to discuss today is that tests cell Kevin introduced. And I just added some form so you can add items and it will check that item created in the database on the server side of course and will update the page and the widget on the page. Yeah, that was yesterday that beer because today I feel a little bit terrible. I tried to follow Tom's guidelines like have friends move to San Francisco, buy a Jeep and fuck it up. Oh, sorry. Meet nerds, talk to them, use GitHub, get drunk. Yeah, I mean, it was fun but today, yeah, we'll talk about that later. All right, so let's go through this widget conversion progress step by step. Sorry. So keep in mind we got that cell and we got that form below that cell and when I enter and click on new, it will update itself on the screen. So the first task is to drink some water because I'm thirsty. The first task is to generate the widget. Usually there's a widget generator and I just pass tests, widget, the name of the widget I'm going to create and some standard action display and minus, minus, hemel because I like hemel views. So it will create, stop out the widget class and a standard view for the state I want to create. It's the same as a cell creation. Next part is the widget. So instead of deriving from cell base, I derive from a bottom or widget and then I have this action called display which just looks through the database, finds all the tests I'm assigned to. This is a very simple example I know and then it basically renders the corresponding view which is in display html.hemel. Next part is to write a view for that display method and yeah, you know that from cells. I mean you've been watching it. The view is located in the tasks widget, app, cells, tasks widget actually and then display.hemel. What I'm doing here is I just let a bottom will create some basic container for my widget. It's widget diff and yeah, I iterate, I loop over the tasks and stop out that boring list and to get that widget into my controller, I use the controller class method hasWidgets. So this is something new to Rails. All the stuff you saw was like controllers. HasWidget simply yields root widget and I attach my tasks widget which I created to that root widget and I also pass an ID that's the only requirement a Potomo has. So I call that widget my tasks. Any questions here? No. I wanted to point out one things when I came across Potomo was the root. That was really a bit of a stumbling block for me. Root is just the uppermost widget. It's always there. It's the default widget, it's empty and you just add widgets, your widgets to the root. And so the root is just a place to hang all your widgets into. Usually Potomo is made for having like 20 widgets and you can nest them and have real widget families. That's how I call it. But there is always that standard top, very top widget root. And to render that widget, my tasks, the task list, I just use render widget in some layout or in some view of my controller. And I pass the ID. So I reference it by ID. So that was rendering only. I mean, I told you we are gonna discuss how to react on form submits and stuff like that. So the first task is I have to, so here we got that list and I will simply extend it with a form. So I use form tag. I create a HTML5 compatible unobtrusive JavaScript or a lot of passwords in a row. Data event URL, that's a HTML5 attribute. And I use URL for event, which is an Potomo helper method. And so a Potomo simply stops out some URL which will trigger the submit event. So you don't have to worry about what happens here. It's just a basic URL to trigger the submit event. Yeah, and then we got basic form stuff. So that's pretty boring. By the way, I'll point out, don't execute this code because the indentation is too much on it. Oh yeah. I took out a lot of parameters and stuff from Rails just to have a small example. So don't try this at home. All right, so we got the URL for event. You're gonna use that a lot because you want a Potomo to create URLs for you. And then I have to add some JavaScript. I, sorry for that horrible slide. But usually when I do talks about a Potomo, everybody is like, ah, a Potomo is a JavaScript library. It's not, it's just using JavaScript to transport events and the content back to the page. So I use jQuery in this example. You're open to use write.js, prototype, Mootools, whatever. So what I'm doing, I just catch the form. I just create it, oh, that way. And attach a submit event handler. I mean that's just, I tell the form when you're submitted, execute that Ajax request. In that Ajax request, I'm a good unobtrusive JavaScript guy. So I'll just take the data event URL from the form that's created by a Potomo and send that back to the server. So basically a Potomo does this, provides me this trigger URL in the data event URL and processes the request and sends back some content. All right, so I had this form. I enter some stuff. I click submit JavaScript. I'll send that stuff to Rails or to a Potomo. So how does my form know that it has to update? And that's the point where the event system in a Potomo comes into play. So I'm triggering a submit event in Rails. How can I catch that in my widget? Let's go back to the code. There's a nice method called response to event. I was about to say response to what? Response to event and I say, if you encounter an event of type submit, just execute your process action or state. So when my widget sees that submit event, it's gonna execute process so I have to write process as well. This is nothing more than a simple form processing state. I grab the text that was entered in the form and then I save it to a new task and then I execute my display method again. That's what state arrow display does. So I basically get all the tasks, the updated list, call render so I have an updated view about my items and then I call replace which will instruct a Potomo or your widget to update itself on the screen, take that content from display and put it back on the page. So this is very handy and this is the only part where a Potomo is doing a little bit of JavaScript. Yeah and what we get is that form where you can enter stuff and it will update itself on screen as soon as you click submit. Without a Potomo, this would be like partials, a lot of partials and maybe some partials as well. Fat controllers cause you would have to wire up all that AJAX handling stuff yourself. I mean a Potomo is very brief. It's just a simple small library and it provides you with some automatic controller action to process your AJAX. Yeah, that's what I said. You would have uncountable routes. That's what Kevin pointed to, so because you're triggering a lot of AJAX actions and you would have to set up that route to yourself. And yeah, again, in Rails right now it's not possible to test stuff like that. I mean, how can you test partials, JavaScript, AJAX submitting and stuff like that? It's not possible in a Potomo, it's no problem because you have these well encapsulated components that you can test and that you can rely on. So this is just, that was the basic part about widgets and I'm just show off a little bit. So for example, I'm using a Potomo to wrap jQuery widgets. I got a nice Carousel displaying wonderful German beer and then we have some autocomplete box. So I just type in some letter and it will provide me German delicious beer. I could start again. Then you can see it in the Firebug console that as soon as I hit some buttons in the box it will trigger the event to Rails and a Potomo will respond with new content. So how did I do that? I just write autocomplete box widget derived from a Potomo widget. I have my standard display method which will render the view for that autocomplete box. Again, just some text field, some input. I use URL for event to generate a triggering URL. This time I call the event typing. You could also call it attention, we got some input and then I use the jQuery autocomplete method just to turn that little input box into a real autocomplete box. So what I'm doing here is as soon as I type in I trigger the typing event. We all learned that we respond to events by using response to event. So I just assign my widget, hey, when you see the event typing, answer with your state search. So execute your search method. In the search method I just, well it's a simple example. I just render out some standard answer for that autocomplete box. Usually I would look up the input and then would look through the database and send back these items. But it's very simple to wrap that in a widget. I mean doing this in a Rails controller would be like a mess. So that's all I need for that autocomplete box. I also got some nice little example showing how to decouple widgets. So again I have some imaginary Twitter application. I just type in some message, hit the tweet button, the left item will update and the left list will update. And I can also drag and drop items to the trash bin which will basically delete that tweeted item. I'm not sure is that possible in Twitter, I think not. And will just update itself and the list. So again this is very simple in a polymer. I would have the trash bin widget and the list widget and they were both rendering stuff. And in the delete method of my trash bin widget, I just call, I can also trigger events from the server side, not only from the browser. So I call trigger, update, which is a basic event. And my list widget will respond to that event by using response to event, look into update and it will just call its redraw method. Of course I have to implement the redraw method but it's basically very simple to have that kind of interaction between widgets. Yeah, and so we already learned the basic part about a polymer as I said, you can also have complex widgets like being nested and having, I don't know, like spreadsheets or real desktop applications in your browser. You can have statefulness, which is very handy in some cases, you have bubbling events. That's too complex to show it in this talk, sorry. And then we got caching from cells and we got testing from cells. And yeah, we are already thinking about having some generic widget repository where you got, I don't know, like widgets for jQuery, widgets for prototype and stuff like that. So people would write widgets which you can use in your project instantly. So that's about it. If you're interested in that stuff, we got some great new guides online tutorials. They are at guides.apodomo.de. You can always hit me on a free note, IRC. I know I'm outdated, but I like it. So just join the sales channel and have a snack with me. And you can also check out apodomo.de which contains a lot of blog posts about that stuff. And yeah, that's about it. I would say questions and then thank you. Oh, there are really questions. The guy in the front. Is it possible to do it in a pen just to have it replaced? No. We got the method replace and we got update. It's out of the box, but you can also send back your own JavaScript, like you say, render text. And then I don't know, like a pen, something to something. You're free to do that yourself. It's just a handy method in apodomo. Replace. Thank you. The guy behind the guy in the front. Ah, Nelson. I need glasses. You got me. Usually widgets are like a tree. And if I trigger an event in some widget, it will bubble up the hierarchy to root. So the example I did will not work because both widgets are attached to root. So the list widget will not know about the triggering in the trash bin widget. So you did a good job observing. Yes, please. Yeah, I'd probably handle this. It's just like any other view. So you'd have your sass files or CSS files and you give them class or ID names and it just finds it in the CSS file. So it's like any other view is just in different directory. So that's a thing we're working on. I mean you can always put the stuff globally in your CSS file, which sucks. And we're already working on some technique to have a CSS file in your widget directory. So you have your own asset. Or you can also inline your CSS in the widget class using like a, I don't know, CSS and then you can pass in a string. So you have all in one place. All right, like from application to application or developer to developer? Yeah, so I mean that's basically up to the programmer of the widget, but it would be great to ship CSS information with your widget because otherwise if you write some great spreadsheet and it will look messy on my browser, then we all know that. Or even from layout to layout I guess also. If it's on multiple pages of the same app. Okay, I see what you mean, yeah. Yeah, it had to be either global or packaging it with a widget somehow. The guy in pink or is it white? Well, it does not have any built-in widgets except a Portomo widget, which is a basic generic widget. So you would have to write that tap widget for Jake Ferry yourself. That's the last point on this list, a widget repository. Like you would write a tap panel widget which I could use in my application. A Portomo is a framework for writing widgets. So how you would use a Jake Ferry widget? You would just derive a widget from a Portomo widget and then you would have different views like displaying the JavaScript code. And maybe for a tap panel one view would be sufficient. And then you would, you have all that stuff packaged up in one directory and you give it to me and I use it in my project. I would like, we have the root widget and then I append your tap widget to my root and then maybe I could append content to your widget, to your tap panel widget and you would render it in a nice way. So that's your job for today. Actually, there is an example online somewhere and somebody already did that like writing a tap panel widget. Pretty handy, so if you click on different taps it will reload the content on Ajax, yes. I think we may be out of time but I wanted to mention one more thing. In my application I was constantly having to go to the route file, routes.rb and with a Portomo it adds the routes dynamically so you don't have to touch the routes file anymore if you want to do Ajax in your application. So I mean it's important to note that a Portomo does no magic at all. It's very, very simple. It's just based on cells and it does add one default action to your controller. That's all. So we don't have any strange things happening behind your back. You can trust me. Thank you. Oh, well Portomo is view layer. So usually the view layer is sitting above rest. So a Portomo doesn't care about routes. It's just for your view. So you have your rest routes, you have your rest controllers and the controller would have to take care about which widget to render. So a Portomo doesn't handle that kind of stuff. It's just for the view. One question and then we'll be finished because cells is running with Rails 3. Jehuda did some work on it. That's very kind of him. And a Portomo is, as it is based on cells, there is no need to change anything in a Portomo. So it runs on Rails 3 as well. Thanks, you have been a wonderful audience. Thank you.