Abusing Rails I18N to Set Page Titles
I got tired of @page_title
variables being sprinkled around in controllers and views on Speaker Deck, so I made good use of Rails’ I18n API to define them all in one spot.
My config/locales/en.yml
now looks something like this:
en:
title:
default: "Speaker Deck - Share Presentations without the Mess"
account:
new: "Sign Up"
show: "My Account"
tags:
show: "%{category}"
likes:
index: "Presentations Liked by %{user}"
passwords:
index: "Password Reset"
talks:
index: "All Presentations"
edit: "Edit %{talk}"
new: "New Presentation"
show: "%{talk}"
users:
show: "Talks by %{user}"
To make this work, add a #page_title
helper method, which looks up the page title translation using the controller and action name.
module TitleHelper
def page_title
t page_title_translation_key,
page_title_context.merge(:default => :"title.default")
end
def page_title_translation_key
:"title.#{controller_name}.#{action_name}"
end
def page_title_context
controller.view_assigns.symbolize_keys
end
end
The helper also passes all of the instance variables assigned in the controller, so you can use any of those variables in your page title. The only caveat is that we have to define #to_s
in order for our model objects to show up properly in the title:
class User < ActiveRecord::Base
def to_s
username
end
end
Now in our layout, we can use our new helper:
<title><%= page_title %></title>
I’m really happy with how this little hack worked out. This almost seems like something that should be in Rails core. Maybe I’ll have to submit a pull request…