 When they are loosely coupled, it is very easy to reuse them and replace them with some other component. So in Java, how many of you are doing Java here? So Java folks, you might be aware of different different components that we generally use in Java world. But in Rails, it is little difficult inside Rails application. This talk is mainly around view components. When I joined, earlier I used to be a Java developer. When I joined Rails project, the first question came to my mind that time it was a web application that, okay, is there a way to add components or to create components so that I can segment my page into different, different components, which are MVC in itself and which would be easy for anybody to replace component by other. The straightforward answer came to me was, no, there is no direct support. I know that we all know Rails is directly or tightly coupled with active records. It is, it has done really an amazing job at, from where it was in 0.7 and where it has reached and soon, sooner we will get 4.0. But at that time immediately after the question, I found there was this render component. How many of you have used it? So I was really, I, I became really happy, okay, there is, there is a component stuff in Rails and let's go and start use it. I started using it and very soon it got deprecated and I again became sad. The reason for deprecation according to Rails document was do not use components to separate concerns within a single application. Furthermore to it, it says reserve the usage of this components for those rare cases where you definitely or you are 100% sure that you have a reusability in views and mainly talks about try to create components where it can, it can be applicable across application. And at the very end it says it can better be replaced by partials and filters. There is something I kind of, the best example of components which are, which may not be view related or which may be view related are like Ruby gems. For Java ball, it could be like jar. How many of you use a very simple library like display tag from Java? It's, it's basically, it's basically at view layer. So it is, it is again related to, it is again a component which is, which allows you to easily create tables and columns. When it comes to Rails, because of the convention, you got a very good directory structure and it becomes very easy to find or to locate a particular view. Let's say if I want to go to list.html that is the list action inside my events controller, I can use, I, I know that it is there in the events directory, which is really an awesome thing. But this makes this, this is better fit when application is small, though because of the convention, you can directly locate a view. But as your application grows, let's see what happens to this view directory structure. Let's take this example. So you have a big, let's say it's a landing page, homepage. You have sidebar where different promotional sections can, can appear. You have then tab navigation at the top. You have sections, section one, section two and section three, which could be again promotional contents and could be driven by an administrator or an editor. Now let's try to imagine, I want to develop this in a very traditional way in Rails. How do I do that? I'll start creating controller, I'll put an index action and I'll start writing code for it. And in views, I'll start creating all these separate, separate partials. When I say partials for Java world, it is very similar to what you do for your simple JSP include. You can map it, it's not direct mapping, but it is, it is very much similar to that. I was having a conversation with Nick, who is creator of sales and Apotomo, which is our main topic. And over email, he said, it would be nice to show some real life example or examples in production. Community who are currently using sales and Apotomo, they wanted to see some examples in production. So this is something currently in production. This is from our very recent project. So this is again a landing page. Everything is unrelated. On this page, nothing is related. So you have a breaking news section. You have a watch live promo. You have some other promo like supporters. You have an author column and then you have a middle section of shows. Nothing is related. Let me give a brief introduction about what this project is all about. This is basically news. This organization is basically an independent media and they run one hour show. So basically in that one hour show, they produce stories and headlines. And if you see that video, it is related to the headlines and stories, which is one chunk and all other are related unrelated. There is another example of the same stuff. This is a headlines page where you have a video and you have some description about this headline. Let's say, but look at the right hand side. It's totally unrelated. So you have some stories and headlines from some day. Then you have watch live and most popular. Editors have no relation to the headlines page. It's not even related to related headlines. It's totally different. Now to add on to complexity, let's say I want to show this on the headlines page immediately after the description. Is this related to headline? No, because it's talks about top stories which could be driven by editors, which could be controlled by editors. Then you have a feature topics which has no relation to your headlines. Let's say as an editor, I want to promote Follow DN option. When I say DN, it's from the project, Democracy Now. Let's say I want to promote this follow option so that users would come and start following on different social platforms. Then you have, let's say, this is a tab navigation. And again, this either, let's say, editors decide, okay. For some day, I want to show featured section. And later, I don't want to show featured section. Instead of that, I want to show top stories like this, recent stories. And the last one, let's say, example of speaking events. Speaking events could be events happening all over the place, like the same Rubicon. We'll take a look at how we can implement a speaking event and create a view component little later. Now the main problem comes when CMS is used. How many of you have used CMS? Good. Great. So, let's say I want to control everything from CMS. As an editor, I want to define a layout. I want to define what should come on what part of the page. And I want a flexibility to turn it off, turn it on, or I want to replace it with some other component, which has the same CSS styling for the dimensions, width and height. It becomes very difficult to manage it. We fall into the same trap of creating monolithic controllers, monolithic page, defining one controller, and then different, different, different partials. It becomes difficult to understand and to practically implement mashup. In Java world, how many of you used sitemesh? In Java world, I really like this sitemesh tool. It's a page decorating framework. It's very, because of that, it becomes very easy to decorate your pages. Let's say if you want to implement something like YouTube, you have a video related video more from something like that. And let's say, as an editor of YouTube.com, I want to control what should appear on the related, whether related should appear or something else should appear there. Then it becomes easy with the help of sitemesh, where you can add different, different page rules on the page. Let's say, how many of you have heard segmentation by freshness? It becomes easy to achieve segmentation by freshness. Martin has written a very good article on segmentation by freshness. What it means in a very basic, in a very simple terminology, let's say you have a page divided into sections. Let individual component own that section so that everything related to caching performance can be handled there itself. Rails by default gives different, different caching mechanisms. You have a page caching. You have action caching. You can think of fragment caching when you want to cache individual parts of the page. But fragment caching has a cost. And the cost is, first of all, the code lies in the view. Second thing is the expiration is little trickier. Expiration of the cache, cache invalidation is anyways one of the difficult jobs. But fragment caching, there is a lot of things that you have to write, let's say for expiration. And let's say if you write sweepers, sweepers need to understand, okay, for this particular model, there are six, seven fragments. Let's say if tomorrow you delete one, you add two, you have to go and modify those many stuff, which is little tricky. So how do we handle this? Let's consider one example. Only one page with unrelated section as one. As I said, this is again the snippet from the code base. Let's say I write a controller and on this page, I want to show those speaking events which we just saw. How do I write it? I'll just say before filter, I'll try to gather data and make it available as an instance variable so that it is available in the view. What should we really do this? Personally, I use before filter only if it is, I tend to use before filter only when it is related to authentication and authorization and not for too many data gatherings unless it is really tricky and becomes very messy. This was a very simple. Now let's add complexity. What if some unrelated sections are used on all pages? Any guesses? What do we do here? Very simple. We all know in inheritance, what we do, we actually take everything and put it into application controller. Again, there is a problem. In an object-oriented world, we say instead of inheritance, go for composition. But when it comes to coding, when it comes to actually writing, modifying, we actually move it to immediately application controller and everything works fine and we become productive. But that's not really the way we should think of. The other way is somebody say, we can create a mixing. Somebody say, we can create a module and include it. It's a composition. What if there are many unrelated sections? Let's add a complexity here as well. Many unrelated sections and there are, let's say, many pages. So there would be lot of combinations of page and its unrelated section. In that case, we definitely need a way to divide page into segments so that segments can be treated as MVC in itself. When we do all these things, when we want to write something in view, what we do? We start creating partials. Let's say if there is one unrelated section, we create, let's say, one partial. If there are many, we tend to create some more partials. If there are, let's say, lot of, then we try to create some more partials again and we keep going on. And then let's see what happens to our view. There's so many partials. So what are the options? So long time back, when Merb came into existence, there was a nice gem, came in like Merb parts. How many have you, how many have you used Merb, Merb parts? So Merb parts was basically giving, creating a parts controller, that means one controller which was extending from abstract controller and giving all the basic functionalities. Basically it was a wrapper on your request, responses, templates, whatever the abstract controller provides. Then there was a Rails part. Rails parts, I won't talk about merge of Rails and Merb. Rails part is Merb parts ported for Rails 3. And there is third, sales and apatomoe. So let's understand what is sales. Sales is a view component. It's a gem, it's a view component and it is a mini controller. So when I talked about, when I said page can be divided into segments, each segment can be treated as sales. But word of caution, do not create unnecessary sales. Create sales only if they are unrelated, so that they can become, they can be independent and they can be reusable. Let's take an example of this. Let's try to create speaking event cell. Basically it's nothing but an events model which has let's say date and time, a URL to go to a venue and then a detail. Let's say if I've already created this, how do in a normal way I would say render partial, give a partial name and pass different parameters. If I create a cell, you can replace it with say render cell, give the name of the cell and give the state, that means it's action. You can treat sales as a block on a page, one particular block on a page. How do I create this cell? Let's say, here I am using 187 to actually generate cell. When I say cell speaking event show, it has generators. It actually creates a directory inside app folder. So now it is, how many of you use Rails 3.1? So slide sheets are now coming in app folder, right? In the form of CSS or SAS. So similarly you have a app folder defined as cells and inside cell you have views associated to that cell. So when I say cell speaking events, speaking events is the name of the cell. Show is the action and you have app cells, speaking events, that is the name of the class, that means object and then you have associated view that should show.html.erb. One interesting thing, you can easily test this cell object. Let's start with the test first as we all like TDD or BDD. Let's say I want to return future events in a very simple way. I'll create two events and I'll try to assert on event. It looks exactly similar to your controller. There is hardly any difference that you would find out. Let's use, it has self test case, which actually makes it easier to write test cases for cell. Here I'm just verifying the instance variable and doing an asset equal, but you could also verify the HTML getting generated out of it. This is an object, speaking event cell which stays in app cells. You have a show, action, basically it says find upcoming, try to look at the events and does the rendering. You notice something like head. There is a little problem currently in cells in Apotomo related to CSS and JavaScript. How and where do we include CSS and JavaScript? In a better practice, in a very, if you follow all good practices, JavaScript, where should be a JavaScript? At the bottom of the page, right? But with this, you have to get the, you have to find little bit work around to actually put JavaScript at the end, at the very end. But if you think cell as an independent block, you can create another state, let's say call head, and you can put all the CSS and JavaScript associated to the cell itself. In any parent view, you just say render cell, speaking events and show. Render cell is the name of the cell, show is the action, and you get a nice looking speaking events. When Yehuda wrote an article on Merck parts, he mentioned that, okay, there was something like render component, which was heavy weight and not really used by many developers. They cut that off, but still we need lightweight component. And further to that, he was saying, we need lightweight component first, so that it can be, it can replace partials and filters. Second thing is, it can understand the context, current context, when I say current context, it can understand what controller is, the request is coming from. When I say what controller, let's say if I am on welcome controller, and I want to show this speaking events there, then my cell understand, cell understand that the request is coming from welcome controller, how it may, it actually takes a controller variable inside it, it's like a dependency. And because of that, your session, request and params are easily available in cell. But as a practice, we should try to avoid using and directly not to, we should try to avoid using all those things and try to make it little independent and pass explicit parameters to cell. So when I say, let's say I want to show only one particular event. I could say show and pass either event ID or event title and let cell do the job of actual finding the title, actual finding the event. The other important aspect, when I was talking about segmentation by freshness, a page divided into multiple segments, each segment can cache itself, let's say for some point, some particular duration. So that cache invalidation happens directly. So there is a nice DSL like cache, you have a state and you can easily specify how much time do you want that cache to be available, and then it will expire it immediately after the duration. There is another variation to it. Let's assume that I'm showing all the speaking events. And instead of caching the entire output of the cell, I want to cache individual events. Let's say if some, let's say if editors has, you know, removed one of the event. Instead of caching the entire cell, what I could do, I could easily say cache, instead of show, I need to create another action, which would accept only one event. And just here in the cache, I could just say the, if you look at the do block, it accepts two parameters like cell and the item. The item could be the object, it could be the single node or whatever you want to actually customize the caching for. Let's assume that it is a single event and in the cache block, in the do block, you could specify, you could try to return what cache key you want to use for that particular node. If it is event, then it could be event.id or you could provide some hash or you could generate a key for it. There is another variation like you have an expiration in sweepers. The expiration is pretty straight forward, expires cell state. Cell caching, because of cell caching, fragments are gone. But internally it is a fragment. Even if you want to cache fragments of a fragment, as an example I've just given, that is also possible. Even instead of expire cell state, you could also expire fragment by giving the directly URL, the path that would expire the fragment, because cell caching is internally is a fragment caching. But the overhead of the maintaining fragment caches is taken over. Interestingly, cells can be nested. It supports view in inheritance. Now Rails has in inheritance and one interesting problem, how many of you have faced double renderer error? Yes, there is no double renderer error. It is nested. It is view in inheritance. You can call render as many times as possible. It won't throw double renderer error to you. Cell, it is very good when you want to create view components which are not interactive. But when, because of the reach client, reach internet applications, everybody is moving towards web 2.0, 3.0, et cetera, then you have to have some kind of interactivity in these components. So cells plus interactivity is called upper term. It is based on cells, it is again a gem and it uses JavaScript. It's very similar to RJs, but it does not have that much of code. It is JavaScript agnostic. All the things have have been moved into gem. So you don't really need to worry about what is being used, whether it is jQuery, prototype. It's all there. Persistent, reusable, independent and events. Actually, events might create misunderstanding. It is actually, it supports event driven model. It's not events. It supports event driven model. When I say persistent, we'll talk about the examples. Then I'll give the clarity on all these things. I'm pretty sure reusable and independent are clear by itself. These are the examples where you could go for upper term. You have dashboards. Dashboards again have different, different sections, which actually keeps refreshing themselves. You might have seen the spinning. When you do Ajax calls, you might have added some spin, spinner and you might see spinning there. Then you have image galleries. When I talked about persistent, image galleries could be an example. Let's say you have loads of images as thumbnails. And as you click on a thumbnail, you show a bigger size image and some attributes. And on the same page, let's say you have an upload form where you could upload n number of images simultaneously. So the persistent, putting images or if you're using maybe a paperclip, putting image metadata in the table can be done by the cell itself. And if you think, sorry, upper term itself. If you think upper term it that way, then it is easier to actually create reusable components, reusable view interactivity components across application. Let's say I want to use the similar functionality like thumbnail, because thumbnail could be generic. Then tap panels could be generic. And that could go and that could be there in all the applications. Let's try to look at this simple example. This is the most amazing page I have ever written. It has one form, only two list items. So you have a form, you have a listing, and you have a count. How do you do that in upper term? As I said, it is a cell based. I'll quickly go through generators. It's very similar to cell. You have generators available. The interesting part is there are two widgets I'm going to create here. One is note listing and one is note form. Two separate widgets just to understand events. Let's say I'm creating a note form. I have a notes widget where I'm just getting all the notes. This is a basic view for it where I'm just collecting all the titles for it. And this is a note form where you have, you just have a text box and a create block. This is important. In the controller, you have to have a has widget entry where you could put the entire widget tree out here. You can actually move this outside and create your own widget tree and just use the reference over here as a family name because widget trees are attached to a root, which is a topmost note and you can have different different families inside it. Like it could you could have a tab related stuff. You could have a comment related stuff. You could have a thumbnail gallery related stuff. And simple index.html you have render widgets. It just uses the ID. It just uses the ID, which have been defined under has widget block, nothing else. You just need to know the ID, which would be your div ID. That's the only thing you need to do. And if you run this application, which is available on GitHub, you would see this particular entry. Now let's go through very quick stuff. Let's say if you want to create a note and update listing encounter and filter notes on typing both the approaches. I've just added a URL to the existing form URL for event submit and URL for event typing as I type. I need to say submit an event. This is a basic JavaScript block. This is very simple stuff I've written. One is from form submit. One is for key up. This is the change response to event submit with update. So whenever there is a submit event happening from client side on the server side, it would respond with an update state. And what does an update do? It would create a new note and trigger a new note event. When the new note event is triggered, it would actually, it actually needs to update note listing, right? So how do I do that? In the notes widget, I would do again respond to event, the event name, and what callback do I need to do that is update. And it would actually replace the existing state of the displaced action. That would, it would again phased all the notes and render, re-render it. The similar thing goes for the typing. This is the important stuff. The event bubbling happens from one widget to another till the root. There is another provision from where you can pass an event directly from widget 1.1. Let's say to widget 2.1. That means you can pass an event between two different widgets. That is also possible for, in production examples, which are currently live, you can go to democracynow.org and which has, I would say 75% of, you know, sales, which are unrelated, but there is still a scope of adding more and more sales. That's it I have for this talk. Thank you. Is there any question? I have two things. One is doubt and one is question. So the sales caching that you just told, it's a fragment caching, right? So is it really helpful in the distributed system having multiple servers? Distributed systems having multiple servers. So as long as you maintain your cache at one main store, at one store, it won't have an impact. So the thing is, even if you don't use this fragment caching and if you use any other caching, as long as your store is maintained at one particular location, if you don't replicate, you know, if you replicate, then in that case, you have to manage the replication. If the replication is directly generated with, let's say, for example, a kind of relation like master and slave, then it would be, but that support has to be given by tool itself. For example, even if it is a distributed or a single application, if you use one store, let's say if you use memcache, for example, to put all your, you know, cache over there and if all the system related to this talks to one store, then you can get that. Cell caching is something different from memcache, right? Cell caching is nothing but internally it is a fragment cache, but for fragment cache, you can define a store, which is there in the, which is, you can define in your configurations like either development.rb or in Rails, you have different, different configuration based on different, different environments. So you have development, staging, test and production. There you can store, there you can define your main store. It could be cache store. It could be a memory. It could be memcache, something like that. One more thing is, you just mentioned that in new thing, the double rendering error is like, doesn't bother if we use double rendering thing. So does it meaning that it like tends to, in case that wrong thing is rendered without notifying something or like, as of now what happens is it notifies that double rendering is not possible. Like someone has rendered and someone has redirected, it just notifies, which will not happen. Right? Which will not happen. Like without notification, it should happen that the thing like go to the wrong thing, like without notification. Can you please repeat? In double rendering, what happens that if, if I write two renders, like one render and one redirect, redirect, it will say that this is not. It will give you, it will give you an exception. It will give you an error. So meaning I want to render something by mistake. I have written redirect somewhere. Okay. Like I haven't noticed that it should be in some condition, but some condition is not getting raised and it is happening like both, both of the things will execute in that case, the render will like redirect. The next statement will, will take the priority, right? Yes. If it is played without notification to the like to me. Yes. So in that case, as I, as I wrote that there, the problem with the problem with, let's say if you do, if you try to do redirect, okay? And if you have render after that in, even if you don't use it, there are two ways. I think in Rails 3.x, that case is not there, but in Rails, at least in Rails 2.3.14, unless and until you write an if block where you segregated out the redirects and renders, it won't have a problem. But after one render, after another render, after another render, it won't cause any issue. Where is the? So the sales and upper term is anyways on the GitHub. The example is on GitHub. Should I? Yeah. But to install this is a gem. Where's we just do gem install? Yeah. Yeah. It's on RubyGems. So it's just gem install. Yes. And where's the code for that? Where's that gem? So the code is available on the GitHub, but it is also available on the RubyGems. And where is it on GitHub? That's what I'm trying to ask. So on the GitHub, it is under Apatonic username. Oh, OK. Good. Thanks. So Apatonic is a nickname for the creator. His name is Nick Shatrud. Yeah. Darshan, thanks for the talk. One question. I come from mainly the Java background. I'm a Java developer, so correct me if I'm wrong, but this Apatoma itself is what Portlet is in the property in the Java world. I mean, over the years, people were very excited about portals and portlets. Now they've realized it's making their life very easy. They know all the pages have become very easy, and all that stuff. So have you seen any kind of similar experience when it comes to performance that sells? And you're using this in a page which is very rich in functionality, a lot of components. Is there any performance or any other non-functional constraint or drawback? No. So to be honest, it's an experiment with Apatoma. But sales, we haven't faced anything. Can I initiate expiry time of sales? You can. Can I initiate expiry time of sales from the server side? Yes. So you have to specify if you want to cache a cell for a given duration, then that expired time you have to specify in your cell block, in the cell object. It's in one request flow. Yes. It depends on your application, whether you want to, whether you are going to render all the sales on one page or you want only some sales on this page and the other remaining sales on the other page. I am just talking about the double render. You just mentioned that in sales, you are not going to get double render error because it's not going to be as all sales are rendered in one particular equation. Every cell is an object which uses a controller needs within it. So you would never get a double render error. So I did not hear a comparison with an alternative would be for Widget. Sorry. I can go ahead, right? Okay, sorry. So an alternative would be to have segmentation by freshness implemented in a way where your widgets are driven from the client side and each of them just hit a controller starting from the browser itself. Whereas this is all probably server side in one shot. So how do you compare these two approaches of one server side response versus a chatty application? Yeah, very good question. So the problem I saw with the first one was let's say I want to show n number of unrelated items on page load. In that case, what do I do? I try to create, I try to send those many Ajax request on the page load itself. And if it is going to take time, then I might see spinners all over the page. At least for let's say there are 500 later sections and then immediately you would see five spinners for Ajax calls. And personally I feel that we should try to avoid and move it to one page load and have segmentation by freshness mostly on the server side. We'll take one last question before we wrap up. Might sound silly, but can you just redefine what the issue was with partials and why we're using cells instead of just the usual partials? Cell is an object oriented replacement for partials. So when you use partials... What is the challenge with partials? I mean here I can see that it's making stuff a bit more complicated and it's something new and that has baggage that comes with it. So we have partials we're all used to it and you have that you can render a partial directly with the instance variable and you have simple stuff like that and you can use decorators to kind of give you and delegate those getters so stuff they're familiar with. So why cells, what's wrong with partials? So it's the same thing whether you want to opt whether you want to go for individual partials you have seen the... So you have to write a HTML code somewhere. I mean you can't escape that. So it's a underscore whatever file or a cell file that code has to be there. Then in that case... So what problem are we solving? So the problem is your code gets messier. Like can you define... So let's say for example, let's say for five undilated sections on your one page. How are you going to write let's say before filter? So are we assuming, I mean I'm not talking about before filters because the way I'd collect the data would be using conditional sort of decorating it wouldn't be before filters because even I use before filters for like what you said but my point is if you have a lot of undilated sections and a lot of partials you'd use template inheritance and share them and that code has to be written somewhere. So you're not escaping, you know, writing that code. Getting those partials you have that render with the at instance variable which just by convention finds the partial. So you have these two things as long as that instance variable is available in the controller you're looking for why do we need to add in this complex? Is it making... I mean because I don't know about caching that much the caching advantage then completely sold but apart from that So forget about caching and I won't even defend object oriented let's take an example where you want to show five undilated sections and should be driven by editors. Let's say I want to show I want to show video and as an editor I want to today I want to show related images or related videos for this particular video in that case I would create a related blog related cell Can we start from the view? Your view would have some conditional logic which will call render or whatever right? No, why would... So when it is... Let's say I have a XYZ controller and there is a main body and there are five unrelated sections in that controller in the view for that controller there has to be you'd have to have a way perhaps of making sure the HTML code gets in that view right? So if I had to render some cell name whereas say I had to render some partial name you'd need to do that right? But your editors would... Can I interrupt you guys for a second? We're just out of time so maybe you guys could... We'll talk about this later So the next talk in this track is going to be...