Layouts in Rails 5

Objective

To learn about layouts in Rails 5 and how to customize it.

Steps

Step 1

The application wide layout is in app/views/layouts/application.html.erb:

<!DOCTYPE html>
<html>
  <head>
    <title>Blog5</title>
    <%= csrf_meta_tags %>
    <%= action_cable_meta_tag %>

    <%= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track' => 'reload' %>
    <%= javascript_include_tag 'application', 'data-turbolinks-track' => 'reload' %>
  </head>

  <body>
    <%= yield %>
  </body>
</html>

Step 2

The projects index page lists all the projects. In app/views/projects/index.html.erb:

<h1>Projects</h1>

<table>
  <thead>
    <tr>
      <th>Name</th>
      <th colspan="3"></th>
    </tr>
  </thead>

  <tbody>
    <% @projects.each do |project| %>
      <tr>
        <td><%= project.name %></td>
      </tr>
    <% end %>
  </tbody>
</table>

Step 3

You can view page source to see the application layout provided title and other html tags.

<!DOCTYPE html>
<html>
  <head>
    <title>Blog5</title>
  ...
  </head>

  <body>

<h1>Projects</h1>

<table>
  <thead>
    <tr>
      <th>Name</th>
      <th colspan="3"></th>
    </tr>
  </thead>

  <tbody>
      <tr>
        <td>Wealth Building</td>
      </tr>
      <tr>
        <td>Be Happy</td>
      </tr>
  </tbody>
</table>

  </body>
</html>

Step 4

We can create a admin layout in app/views/layouts/admin.html.erb:

<h1>Admin layout</h1>

<%= yield %>

This can be used in the projects controller with the layout method.

class ProjectsController < ApplicationController
  layout 'admin'
  ...
end

Reload the projects index page to see admin layout displayed in the view.

Step 5

Create a controller specific layout in app/views/layouts/projects.html.erb:

<h1>Projects layout</h1>

<%= yield %>

Projects controller will use projects layout by default. Reload the projects index page to see the projects layout in action.

Step 6

Let's now look at how to use dynamic layouts. We can use the layout method in the projects controller:

layout :user_layout 

and define user_layout method to dynamically change the layout based on some condition.

private

def user_layout
  if admin?
    'admin'
  else
    'application'
  end
end

def admin?
  false
end

The original railscast defines these methods with protected access. This is not necessary. We can make it private.

Step 7

We can restrict the layout to a single action in a controller by using the render method.

def index
  @projects = Project.all

  render layout: 'admin'
end

You can download the source code for this article from https://github.com/bparanj/blog5.

Summary

In this article, you learned that application layout will be used by default if no other layout is specified. We can over-ride the layout per controller basis. We can also define dynamic layout based on custom logic.


Related Articles