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.
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 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?
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. 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.
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
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
- In Rails 2 and above the file should be called
- Again, for Rails 2 and above the extension should be