Category Archives: themes

Introduction

In Rails applications we can serve common assets like javascripts, stylesheets and images. I want to serve different assets for different domains in a single rails application. Say for example I have rails application with 2 domains like “blog.nbostech.com” and “wiki.nbostech.com”.

To do this we have many solutions in rails. Here I am going to explain a simple solution in three steps:

1. Create domain specific assets directories in rails application assets root.
2. Add logic in application controller to determine domain specific assets based on requested url.
3. Test the application in development environment by adding your domains in /etc/hosts file.

Step1:

In rails application the default assets directory look like this:

assets_directory1

Now I want to serve different assets for different domains. To do that create different sub directories for each domain under app/assets/stylesheets directory with domain names as follows: for example I have two domains “blogs.nbostech.com” and “wiki.nbostech.com”

1. app/assets/stylesheets/blogs
2. app/assets/stylesheets/wiki

After creating sub directories create one applicaton.css manifest file and related style sheets file. Now each domain specific sub directories have it’s own styles.

Step2:

We have created the domain specific styles in assets directory. In rails application requests are handled by controllers. The base controller is application controller for all other costume controllers. In application controller we need to parse the request and get the subdomain using before_action filter.

Now add the following logic to your application controller:

  # file app/controllers/application_controller.rb
  class ApplicationController < ActionController::Base
    .
    .
    before_action :set_them #Add this line
    .
    .
    #Add this method at the end of application controller
    def set_them
     if request.subdomain.present? && request.subdomain != 'www'
      @css_root = "#{request.subdomain}/application"
     else
      @css_root = "application"  
     end  
    end

   end   
  

In the above method we are parsing the request to get the subdomain. If the request has subdomain and the subdomain not equal “www” then we are setting the css_root instance variable to domain specific stylesheet manifest file path. Otherwise we are using default one. In our case say for example the request from “blog.nbostech.com” then the css_root instance variable set to @css_root = “blog/application”.

After adding above logic to application controller we need to add a condition in application layout to include style sheets. In rails application.html.erb is the default layout for the application. In this layout we will include all the javascript and stylesheet files. The default application layout header section looks like this:

   # File app/views/layouts/application.html.erb
   .
   .
    <head>
     <title>NbosRorOauthProvider</title>
     <%= stylesheet_link_tag   'application', 'data-turbolinks-track' => true %>
     <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
     <%= csrf_meta_tags %>
   </head>
  

Here stylesheet_link_tag & javascript_include_tag are helper methods in rails views. Above lines will include the manifest files of stylesheet & javascript. manifest files includes the information about all the related assets which means application.js under app/assets/javascripts include all the javascript related logic and application.css under app/assets/stylesheets include all the css related logic. Note that here file name extensions are not required if you are using rails helper methods.

As per our requirement we need to use different stylesheet manifest file for different domain. We already have an instance variable @css_root which holds the path of manifest file of domain specific in application controller. We can use that instance variable in our application layout. Only thing we need to replace ‘application’ parameter with @css_root in stylesheet_link_tag helper method as follows:

   #file app/views/layouts/application.html.erb
   .
   .
   .
   <%= stylesheet_link_tag  @css_root, 'data-turbolinks-track' => true %>
   .
   .
  

Step3:

Now we have created domain specific styles & added the back end logic. It’s time to test the functionality in development environment.

Rails application by default run on port 3000. we can access the application using http://localhost:3000 from browser. Here localhost is nothing but 127.0.0.1. To test our functionality we need to add the domain names to point 127.0.0.1 in etc/hosts(unix based OS) file. Go to the root directory of hosts file and open it in your favorite editor. I am using nano editor as follows:

  sudo nano hosts
 

It will prompt your root user password. After entering the root password it will open the hosts file. In that file add the following two lines:

   127.0.0.1  blog.nbostech.com
   127.0.0.1  wiki.nbostech.com
  

After adding above lines save and exit. Go to your rails application root directory and run the server “rails server”. Now we are ready to test our domain specific theming in development environment. Now the assets directory structure looks as follows:

domain_assets_structure

To demonstrate I am using different background image & font styles for two domains.

Open a browser and access “http://blog.nbostech.com:3000”. Out put is:

domain1

Open another tab and access “http://wiki.nbostech.com:3000”. Out put is:

domain2

you can observe the different background image and different font styles for two domains.

Conclusion

Above is a simple example for serve different themes for different subdomains. But let’s say if you have more than 20 subdomains then we need to create a directory for each subdomain under assets/stylesheets. So there is lot of code redundancy. To avoid this we need to follow DRY(don’t repeat yourself) approach in rails. I will cover that topic in my next article.

Thanks for reading this article. We hope this was useful!