How to implement a multi-layout application in Ruby on Rails

02 Aug 2019
0 Comments
How to implement a multi-layout application in Ruby on Rails

How to implement a multi-layout application in Ruby on Rails

Layout is the container for view templates. When we create Rails application by default it creates the layout for us that is ‘application.html.erb’ file and it’s a parent layout of the application. All the common HTML components like the navigation bar, footer, sidebar, etc. go into the layout file at run-time.

When we run the application and navigate between pages the navigation bar and footer remain the same but the middle section of the page is changed. The ‘application.html.erb’ contains the default layout of the application, the whole application uses the default layout file for rendering different views templates.


Simple Layout

 

The default layout works perfectly for small applications where the design of the application is common and you don't need to hide or show navigation bar links based on some user interactions.

What if you want to implement an e-commerce system. Which has three kinds of users and the look and feel of the application is different as per the user role. In this case, if you want to use a single layout for three user sections. You have to write lots of unnecessary code to the manage navigation bar, footer, sidebar, etc. with different styles and links. If you wish to add another section for a user to the existing system it's a death wish.

So, what is the solution to such a problem? Well, we all know Rails is the most flexible and intelligent web application development framework. We can create multiple layouts in the Rails application.


Let's, take the example of an e-commerce system. In this system, we have three different user roles.

  1. Customer user

  2. Sales staff user

  3. System admin

 


 

To implement this kind of system we have to manage the followings files in the application.

  • Layouts files

  • Stylesheet files

  • JavaScript files

So, let’s start by creating Rails project $rails new EcommerceDemo, here the name of the application is EcommerceDemo you can choose whatever you want. Go ahead and open the application in your favorite code editor. I am using VSCode.


 

Manage layout files

First thing first, let’s create a layout for our users, go to ‘app/views/layouts’ directory. Create files ‘sales.html.erb’ and ‘admin.html.erb’

We are using default layout application.html.erb for customer user. All three layouts look like this.

App/views/layouts/application.html.erb

<!DOCTYPE html>

<html>

<head>

<title>EcomDemo</title>

<%= csrf_meta_tags %>

<%= csp_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>

App/views/layouts/sales.html.erb

<!DOCTYPE html>

<html>

<head>

<title>Ecommerce Demo | Sales</title>

<%= csrf_meta_tags %>

<%= csp_meta_tag %>

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

<%= javascript_include_tag 'sales/sales', 'data-turbolinks-track': 'reload' %>

</head>

<body>

<%= yield %>

</body>

</html>


 

App/views/layouts/admin.html.erb

<!DOCTYPE html>

<html>

<head>

<title>Ecommerce Demo | Admin</title>

<%= csrf_meta_tags %>

<%= csp_meta_tag %>

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

<%= javascript_include_tag 'admin/admin', 'data-turbolinks-track': 'reload' %>

</head>

<body>

<%= yield %>

</body>

</html>


Now the layouts are ready to use.

Manage Stylesheet files

For layout specific styles, we have to create a manifest file for stylesheets like ‘application.css’. Let’s create a manifest file for sales and admin layout. Go to ‘app/assets/stylesheet’ directory and create a subdirectories ‘sales’ and admin.

  • sales

    • sales.css

    • sales_style.css

  • admin

    • admin.css

    • admin_style.css

 

 

Now, we have to add some contents to manifest file and stylesheet file. So, we can see the difference between layouts.

sales.css

/*

*= require_tree ../sales

*/


 

sales_style.css

body {

background-color: #00c832;

}

 

h1 {

text-align: center;

color: #ffffff;

}


 

admin.css

/*

*= require_tree ../admin

*/


 

admin_style.css

body {

background-color: #34a4ff;

}

 

h1 {

text-align: center;

color: #ffffff;

}


 

Manage JavaScript files

Go to ‘app/assets/javascript’ directory. Create two subdirectories and a couple of files like we have created in the stylesheet directory.

  • sales

    • sales.js

    • sales_script.js

  • admin

    • admin.js

    • admin_script.js


 

Add below contents to manifest and script files.

sales.js

//= require rails-ujs

//= require activestorage

//= require turbolinks

//= require_tree ../sales


 

sales_script.js

alert('From sales');


 

admin.js

//= require rails-ujs

//= require activestorage

//= require turbolinks

//= require_tree ../admin


 

admin_script.js

alert('From admin');


 

Before moving forward, we have to add manifest files to ‘assets.rb’ file because Rails don't know about our custom manifest files. So, we have to tell Rails that add those files into asset pipeline. Let’s do it.

Open ‘config/assets.rb’ files and add below lines.


 

Rails.application.config.assets.precompile += %w(admin/admin.css sales/sales.css)

Rails.application.config.assets.precompile += %w(admin/admin.js sales/sales.js)


 

Pretty simple, isn't it?

 

Create controllers

The real magic happens in the controller, we have to tell the controller which layout to use. Go ahead and create three controllers with index action like below.


 

$rails generate controller customers index

$rails generate controller sales index

$rails generate controller admin index


 

Add the layout method right above the index action and pass the name of the layout as parameter. The controllers should look like below.

customers_controller.rb

class CustomersController < ApplicationController

def index

end

end


 


sales_controller.rb

class SalesController < ApplicationController

layout 'sales'

def index

end

end


 

admin_controller.rb

class AdminController < ApplicationController

layout 'admin'

def index

end

End


 

Now, add routes to check how the layout looks.


 

config/route.rb

Rails.application.routes.draw do

resources :customers

resources :admin

resources :sales

root 'customers#index'

end


 

Start the Rails server and got to below paths.


 




Leave a comment: