#7 All About Layouts
This episode is all about layouts. Layouts are view files that define the code that surrounds a template. They can be shared across many actions and controllers.
Application layouts
The template below lists all of the projects.
<h2>Projects</h2> <ul> <% for project in @projects %> <li><%= project.name %></li> <% end %> </ul>
This generates a fairly basic web page:
If we want to add, say, a header, a logo and some menu navigation to this site and have it visible on every page then we should use a layout. Layout files live in the /app/view/layouts
folder of a Rails application. To create one, create a new file called application.rhtml
[1] in the layouts folder. This will create a global layout which will be used by all controllers and all actions. Our application layout file looks like this.
<h1>Application Layout!</h1> <%= yield %>
The important line in the code above is the second one. The keyword yield
tells the layout where to place the content for the template that is using the layout. Now, if we look again at the page above we can see that the layout has been added.
The layout is global, so it will be added to any action in any controller across the application. Most of the time this will be enough, but what if we need different layouts for different parts of our application?
Controller-specific Layouts
A layout can be made specific to a controller by giving it the name of the controller. So, to make a layout that will be used by all of the actions in the Projects
controller create a file in the layouts
folder called projects.rhtml
[2]. This means that the layout will be used only by the projects controller.
<h1>Project Layout!</h1> <%= yield %>
What if we want to share a layout across a number of controllers, not just one, e.g. for an admin layout? Rails allows you to use the layout
command to specify the name of the layout that should be used within a controller.
class ProjectsController < ApplicationController layout "admin" def index @projects = Project.find(:all) end end
A layout specified with the layout
commmand will override any controller-specific or application-specific layouts.
Dynamic Layouts
Layouts can also be used dynamically. We might only want the admin
layout to be used when a user is logged in. This can be done by passing a symbol as the argument to the layout
command and creating a method with the same name as the symbol which determines which layout should be used.
class ProjectsController < ApplicationController layout :user_layout def index @projects = Project.find(:all) end protected def user_layout if current_user.admin? "admin" else "application" end end end
We can even restrict a layout to a single action in a controller with the render
command.
def index @projects = Project.find(:all) render :layout => 'projects' end
The layout specified with the render
command will override any controller-specific layout. To render an action with no layout we can use
render :layout => false
Notes
- In Rails 2 and above the file should be called
application.html.erb
- Again, for Rails 2 and above the extension should be
.html.erb
rather than.rhtml
.