
- Ruby on Rails - Home
- Ruby on Rails - Introduction
- Ruby on Rails - Installation
- Ruby on Rails - IDEs
- Ruby on Rails - Hello World
- Ruby on Rails - Framework
- Ruby on Rails - Directory Structure
- Ruby on Rails - Rails Console
- Ruby on Rails - Bundler
- Ruby on Rails - Examples
- Ruby on Rails - Database Setup
- Ruby on Rails - Active Records
- Ruby on Rails - Validation
- Active Record Associations
- Active Record Query
- Ruby on Rails - Migrations
- Ruby on Rails - Active Model
- Ruby on Rails - Controllers
- Cookies and Session
- Ruby on Rails - Authentication
- Ruby on Rails - Routes
- Ruby on Rails - Views
- Ruby on Rails - Rendering
- Ruby on Rails - Layouts
- Ruby on Rails - Scaffolding
- Ruby on Rails - Forms
- Ruby on Rails - Active Jobs
- Ruby on Rails - Action Text
- Ruby on Rails - Active Storage
- Ruby on Rails - JavaScript
- Ruby on Rails - Propshaft
- Ruby on Rails - ImportMap
- Ruby on Rails - AJAX
- Ruby on Rails - WebSockets
- Ruby on Rails - Action Cable
- Ruby on Rails - File Uploading
- Ruby on Rails - Send Emails
- Ruby on Rails - Rack
- Ruby on Rails - Error Handling
- Ruby on Rails - Deployment
- Ruby on Rails Resources
- Ruby on Rails - References Guide
- Ruby on Rails - Quick Guide
- Ruby on Rails - Resources
- Ruby on Rails - Discussion
- Ruby Tutorial
- Ruby Tutorial
Ruby on Rails - Layouts
When Rails renders a view as a response, it does so by combining the view with the current layout. A layout defines the surroundings of an HTML page. It's the place to define a common look and feel of your final output.
By default, Rails uses the app/views/layouts/application.html.erb file as the main layout. It is created when you create a new ails application.
If you create a library application with rails new library command, its main layout code would be as follows:
<!DOCTYPE html> <html> <head> <title><%= content_for(:title) || "library" %></title> <meta name="viewport" content="width=device-width,initial-scale=1"> <meta name="apple-mobile-web-app-capable" content="yes"> <meta name="mobile-web-app-capable" content="yes"> <%= csrf_meta_tags %> <%= csp_meta_tag %> <%= yield :head %> <%# Enable PWA manifest for installable apps (make sure to enable in config/routes.rb too!) %> <%#= tag.link rel: "manifest", href: pwa_manifest_path(format: :json) %> <link rel="icon" href="/icon.png" type="image/png"> <link rel="icon" href="/icon.svg" type="image/svg+xml"> <link rel="apple-touch-icon" href="/icon.png"> <%# Includes all stylesheet files in app/assets/stylesheets %> <%= stylesheet_link_tag :app, "data-turbo-track": "reload" %> <%= javascript_importmap_tags %> </head> <body> <%= yield %> </body> </html>
The main aspects of this layout code are:
- Asset tags
- yield and content_for
- Partials
Asset Tags
These tags generate HTML to create links to different resources such as JavaScript and CSS scripts, images etc.
The stylesheet_link_tag helper returns an HTML <link> tag for each source provided. In the above code, the statement
<%= stylesheet_link_tag :app, "data-turbo-track": "reload" %>
generates a link to /assets/stylesheets/app.css
Similarly, the statement such as,
<%= javascript_include_tag "main" %>
Outputs a script tag as follows:
<script src='app/assets/javascripts/main.js'></script>
The yield Tag
The application.html.erb file acts as a base template used by the individual view templates. For example, the index action in the BooksController renders the index.html.erb view. The tag <%= yield %> inside application.html.erb marks a section where content from the view should be inserted.
This can be verified by looking at the log generated on the command terminal when you start the server and visit the index view (http://localhost:3000/books/)
Started GET "/books" for ::1 at 2025-03-25 00:11:13 +0530 Processing by BooksController#index as HTML Rendering layout layouts/application.html.erb Rendering books/index.html.erb within layouts/application Book Load (4.3ms) SELECT "books".* FROM "books" /*action='index' ,application='Controllerdemo',controller='books'*/ â³ app/views/books/index.html.erb:1 Rendered books/index.html.erb within layouts/application (Duration: 14.6ms | GC: 0.0ms) Rendered layout layouts/application.html.erb (Duration: 519.7ms | GC: 0.3ms) Completed 200 OK in 2448ms (Views: 518.6ms | ActiveRecord: 4.3ms (1 query, 0 cached) | GC: 0.3ms)
Rails first renders the application layout and then renders the index.html.erb inside it. Thus the yield tag is a place holder for the output of the view to be inserted.
Let us assume that the Rails application has a BooksController with index and show actions, A book model that has been migrated and a few book records already entered.
class BooksController < ApplicationController def index @books = Book.all end
The index action renders the index view (index.html.erb):
<% if @books.blank? %> <p>There are not any books currently in the system.</p> <% else %> <p>These are the current books in our system</p> <ul id = "books"> <% @books.each do |c| %> <li><%= link_to c.title, {:action => 'show', :id => c.id} -%></li> <% end %> </ul> <% end %> <p><%= link_to "Add new Book", {:action => 'new' }%></p>
The following figure shows the output of index view when the default application layout is used.

Changing the Default Layout
Let us now change the default layout. Save the following code to app\views\layouts\standard.html.erb.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns = "http://www.w3.org/1999/xhtml"> <head> <meta http-equiv = "Content-Type" content = "text/html; charset = iso-8859-1" /> <meta http-equiv = "Content-Language" content = "en-us" /> <title>Library Info System</title> </head> <body id = "library"> <div id = "container"> <div id = "header"> <h1>Library Info System</h1> <h3>Library powered by Ruby on Rails</h3> </div> <div id = "content"> <%= yield -%> </div> <div id = "sidebar"></div> </div> </body> </html>
You let the controllers know what template to use by the name of the file, so following a same naming scheme is advised. Now open books_controller.rb and add layout command to specify the layout to be used.
class BooksController < ApplicationController layout "standard" def index @books = Book.all end
It instructs the controller that we want to use a layout available in the standard.html.erb file. Now try browsing books that will produce the following screen. Restart the server and visit the index view. The browser shows the following output.

The command terminal log also confirms that the standard layout is in use.
Rendered books/index.html.erb within layouts/standard (Duration: 6.9ms | GC: 0.0ms) Rendered layout layouts/standard.html.erb (Duration: 9.0ms | GC: 0.0ms)
Adding the Style Sheet
Till now, we have not created any style sheet, so Rails is using the default style sheet. Now let's create a new file called style.css and save it in /public/stylesheets. Add the following code to this file.
body { font-family: Helvetica, Geneva, Arial, sans-serif; font-size: small; color: #000; background-color: #fff; } a:link, a:active, a:visited { color: #CD0000; } input { margin-bottom: 5px; } p { line-height: 150%; } div#container { width: 760px; margin: 0 auto; } div#header { text-align: center; padding-bottom: 15px; } div#content { float: left; width: 450px; padding: 10px; } div#content h3 { margin-top: 15px; } ul#books { list-style-type: none; } ul#books li { line-height: 140%; } div#sidebar { width: 200px; margin-left: 480px; } ul#subjects { width: 700px; text-align: center; padding: 5px; background-color: #ececec; border: 1px solid #ccc; margin-bottom: 20px; } ul#subjects li { display: inline; padding-left: 5px; }
Now refresh your browser and see the difference −

You can also create a layout with multiple yielding regions:
<html> <head> <%= yield :head %> </head> <body> <%= yield %> </body> </html>
The main body of the view will always render into the unnamed yield. To render content into a named yield, call the content_for method with the same argument as the named yield.
Using Partials
Rails supports Partial templates - usually just called "partials" are reusable components stored in files prefixed with an underscore (_).
Let us add a navbar to the standard layout. For this purpose, first save the following HTML as _navbar.html.erb in app\views\books folder
<nav> <ul class="horizontal-navbar"> <li><a href="/">Home</a></li> <li><a href="/show">Show</a></li> </ul> </nav>
To render a partial as part of a view, you use the render method inside the standard layout. Here, the navbar is to be displayed on the top, so add the following stamen in the <head> section.
<%= render "navbar" %>
This will render a file named _navbar.html.erb at that point within the view being rendered. Note the leading underscore character: partials are named with a leading underscore to distinguish them from regular views, even though they are referred to without the underscore.
You may have to update the style.css to include the navbar styles.
.horizontal-navbar { list-style-type: none; padding: 0; margin: 0; display: flex; } .horizontal-navbar li { margin-right: 20px; } .horizontal-navbar li a { text-decoration: none; color: black; }
Save the changes and refresh the browser. The index view now displays the navbar at the top as a result of including the partial template.
