Smart page titles in Ruby on Rails
Having separate titles for each page in Rails application is a very common requirement and yet RoR does not provide any built in ways to deal with it. I am going to present you with some handy code that can solve this problem without use of gems.
There are going to be 3 ways to define a page title:
- For tho whole controller.
- For a specific action inside a controller.
- Implicitly from a controller name.
So lets add code to our parent ApplicationController:
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class ApplicationController < ActionController::Base | |
before_filter :set_page_title | |
CONTROLLER_TITLES = Hash.new | |
# for setting page titles for the whole controller | |
def self.page_title title | |
CONTROLLER_TITLES[self.name] = title | |
end | |
# for setting page titles for a specific actions. | |
# this overrides @page_title previously set in before_filter | |
def page_title title | |
@page_title = title | |
end | |
private | |
def set_page_title | |
@page_title = CONTROLLER_TITLES[self.class.name] || controller_implicit_title | |
end | |
def controller_implicit_title | |
@@controller_implicit_titles ||= Hash.new | |
# remove any namespaces and mentions of controller | |
# so Client::OrdersController becomes "Orders" | |
@@controller_implicit_titles[self.class.name] ||= (self.class.name.gsub(/(.+::)/, '').gsub('Controller', '').underscore.gsub('_', ' ').titleize | |
end | |
end |
And reference page title in our layout:
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<title><%= @page_title || 'My Awesome App'%></title> | |
</head> | |
<body> | |
<%= yield %> | |
</body> |
After that setting pages titles is extremely easy. You don't even have to do it if you are naming your controllers properly.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class OrdersController < ApplicationController | |
page_title 'Orders' # unless specified otherwise all pages are gonna have title 'Orders" | |
def index # Page title == 'Orders' | |
@orders = Order.all | |
end | |
def cancelled # Page title == 'Cancelled Orders' | |
page_title 'Cancelled Orders' | |
@orders = Order.cancelled | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class OrderNotesController < ApplicationController | |
def index # Page title == 'Order Notes' | |
@note = OrderNote.all | |
end | |
def order # Page title == 'Notes for Order #12345' | |
page_title = "Notes for Order ##{params[:order_id]}" | |
@note = OrderNote.where(order_id: params[:order_id]) | |
end | |
end |