Join Kevin Skoglund for an in-depth discussion in this video Layouts, part of Ruby on Rails 4 Essential Training.
Throughout this chapter, we'll be learning techniques for managing view templates, and exploring the view helpers that rails provides. We'll start by looking at layouts. Most pages on a website are going to share a common structure. Header, footer, style sheets, and possibly other site items, like navigation, menus, or sidebars. At the end of the last chapter, we saw an example of this with the flash hash, which we would like to appear on every page that might need to show a flash message. It makes the most sense if we can define those page elements in one place and then reuse them.
Remember don't repeat yourself is a core principle of rails. And this is exactly what layouts allow us to do. Up until now, the templates we've been working with are HTML fragments, not proper HTML pages with header, body tags, etc. That was intentional on my part because now we'll be able to drop those fragments into a layout. Let's take a look at a simple rails layout. I have a basic html template with html, head, title, and body text. But notice the line between the body text. That's where our layout yields to our template.
It's as if our template content were dropped right into that spot. We can put other content of the layout, such as headers, footers, or site navigation, we just have to make sure that we have that yield statement in the place where we want to drop the HTML fragments of our templates. [INAUDIBLE] Gives us a default layout, it's going to be inside your application folder, inside views, inside a directory called layouts. And its called application.HTML.erb. And the directory that that follows in, views, layouts, is the standard place for all of your layouts.
Unless we specify another layout, this is the default layout that rails will use for all templates in a controller. Let's modify this layout a little bit to make it look more like the HTML from my example. I'm just going to take everything from head all the way down to body, and just indent it a bit. I'll change the title to say, simple CMS. And we're just going to remove these different link tags there, those different helpers. So they really looks exactly like what we had before, we have the doctype HTML, the head, the body and most importantly we have that yield inside ERB tags; that will output our template.
Let's also add an HTML comment right above this, it's just going to say before. Yield. And then we'll do the same thing. We'll copy it, put it below it, and say after. Yield. So that's just a simple HTML comment that we'll be able to see in the source code. Now as I said, by default, this is the layout that it would use, but if you remember, I actually turned that behavior off. In my subjects controller I set it to layout false. So let's comment that out for now so that we do get that default instead. So let's save that, and then let's fire it up. Let's go back over to our command line, into the root of my rails project and type rails server, and then we'll open up Firefox localhost 3000subjects.
Alright so here's my subjects index page, it doesn't look that different. But if we do a view source on it, we'll see that now we do get our HTML up here at the top. And here's that before yield comment, then all of my template code gets dropped in and then we have our after yield comment right here; followed by the body and HTML tag. So you can really see where that template is being dropped in, right between that Before Yield and that After Yield Let's create a new layout. The easiest way to do that in sublime is to control click onto layouts and choose new file.
Once we're there, I'm going to paste in some HTML. You can pause the movie, if you want to copy it down. It's not that different than the layout we just had. I've just added a few more HTML tags. You can see that we still have that all important yield statement right here inside a div with a ID of content. Now as you can see this is going to be for the admin area that's what we;re going to be using this for simple CMS admin let's save that as admin.html.erb and make sure you're putting it in your layouts folder.
We'll click save we'll tell subline that we do in fact want to use erb not html for that line ending and now we have our new layout in order to use this new layout. We need to go back to the controller and tell it that instead of the default layout, it ought to now be using layout "admin". And we'll do the same thing for our pages controller and for our sections controller. Make sure you save each of those after you make a change. And my subjects controller needs saving as well. Let's go back to our simple CMS and let's just reload the page, and there we are.
We now see our new layout. We can see immediately that it's different because we now have a title up at the top, and we have copyright information down here, and a slightly different title over here. You can also view the page source to see that. Now, I noted at the top of this movie that the flash hash is the kind of thing that would be good to include in our layouts. Because in our layouts, we're often wanting to pass those flash messages, and we don't always know what page we're going to be re-directing to. So, instead of having it, on our templates, like we have on show for example.
We're going to take that, and we're going to cut it. Take it out of there completely. Save that up and switch back to admin. And right before we get to our div with main ID content, I'm going to insert that flash right there. If we have a flash it will show it right before it shows the content. Just indent it so it looks a little nicer and then we'll save it. Now every single page in my cms amend has the ability to display a flash notice. So all those other pages that had it before. I think we had it on our index page, for example.
That won't need it. And because we're reusing this layout for our pages and sections controllers, we can do the same thing there. We can remove the flash hash from that page, and from this page. And let's go into sections, the index, and, show. [NOISE] Alright, let's just try it just to confirm that it does still work. Switch back to the simple CMS. And let's just edit tone of our subjects. Let's change revive subject to be invisible. So, visible was set to one.
That's true. We're going to set it to zero, meaning it's not visible. Click update subject. And it says subject updated successfully. And let's just go back and flip it the other way this bold is now going to be one update subject subject update is successful so we still see those flash notices. Even though there now just in our layout we have not repeated ourselves we took it out of our code 6 different times. And just put it in one place. And that's much much easier for us to maintain. If we want to make changes to this. If we want to change the HTML that's around our flash notice, we can do it in one place.
And it flows throughout our whole application. Now, before we leave this subject, I want to show you something else that is very cool and very useful. Let's switch back to our admin layout. And let's change the HTML title, so that, instead of just being simple CMS, we're going to put an upright pipe. And then let's put some ERB tags at page title. And if there is not a page title set that is what those oars mean. The upright pikes like that. Then we are going to output the string admin. Okay. So some basic ruby.
Either put out the value of page title or put out admin if nothing else has been set. Now, we could set the value for @page_title in each one of our controller actions. But I want to show you that it's even better to assign a string in the template. Let's open up subjects index. Let's close some of these up here, subjects index. And at the very top of this file, let's just set a value for that. At page_title equals, and we'll call it Subjects.
And then we'll close our ERB tags. Now, I'm not outputting that, I'm just setting this variable equal to the string, subjects. Let's try it. Let's go back, and let's hit Back to List, so that we go back to our page. Now, notice, it says Subjects up here. If we click Show, it says, admin. It's only when we're on this subjects page that it uses that at page title. Now stop and think about that for a second. I'm using at page title at the top of the layout. The yield takes place further down in the layout and that's where the template is rendered. In the template is where I'm setting a value for at page title.
Why is it possible? How can I set a value for a variable after I've used it? It's because when rails renders layouts and templates, it does not render them sequentially like you might suppose. It's doing something much more complicated than that, where it gathers instance variables. And binds them to the template. The result is that we have the ability to set instance variables in the template for use in the layout. And it feels a bit like magic when we do. I usually set my page titles in my templates. If feels right for the HTML title to be with the view template.
Which deals with presentation. And not in the controller. Which generally deals with control and gathering objects. If you feel up to it go back and take some time to enter page titles for the different templates that we've created. It's not strictly necessary but it does add a nice user interface if users can see what pages they're on in the page title, in their back action and in their bookmarks.
- Why use Ruby on Rails?
- Installing Ruby on Rails on Mac and Windows
- Rendering templates and redirecting requests
- Generating and running database migrations
- Creating, updating, and deleting records
- Understanding association types
- Using layouts, partials, and view helpers
- Incorporating assets using asset pipeline
- Validating form data
- Authenticating users and managing user access
- Architecting RESTful applications
- Debugging and error handing