How do you handle Page titles in Rails? I’ve tried a few different methods over the years. I could never really settle on where I thought the data should go. I’ve set instance variables in controllers, I’ve set instance variables in views, I’ve used content_for in views… etc.
Once Rails implemented I18n support and starting using locale files, I finally felt like I’d found a good place to put this data. I started doing things like this:
en:
default:
title: "My default title"
users:
index: "My Awesome User index"
show: "{{name}}'s page!"
And the nice thing is that since you’re already putting all this in the locale files, internationalization is easy. I’d then use something in my views like:
<% content_for(:html_title, t('users.show', :name => @user.name)) %>
and something like
<title><%= yield(:html_title) || t('default.title') %></title>
in my layouts.
It worked out pretty well, but the translations are dumb. I ended up having to specify several cases in my locale file dependent upon how the controller actions were used. If my action was nested, I might want my page title to reflect that. The YAML locale file didn’t really allow for this easily so I used some conditional logic in my helpers.
This approach worked but it wasn’t pretty. There was also a lot of redundancy.
Now I’m using SmartMeta, a plugin that is just a simple extraction of my most recent pattern. There are other plugins out there that assist in storing titles in YAML, but with SmartMeta your translation entries can access your instance variables and your methods.
As an example, you can do things like:
en:
users:
show:
title: "{{@user.name}} has {{@user.hair.color}} hair"
description: "{{@user.name}}'s page on my site"
keywords: "user, {{@user.name}}, {{page_keywords}}, etc. etc."
and
<title><%= yield(:html_title) || smart_title || t('default.title') %></title>
I’m making use of the @user variable. You can send message after message – in the title, we’re going through the user association “hair” to get the color. In keywords, I’m using a page_keywords method which I can define in UsersHelper or ApplicationHelper. I make use of such methods to handle logic considering nesting, etc.
The benefits of this approach is that you can keep all your titles and other metadata in your locale files and out of your views without sacrificing the accessibility of your instance variables.
This isn’t a catch all solution and I’ll still have to use content_for in places to specify alternate titles… but it works well enough that I thought it would be worth sharing.
Back to the question: How do you handle page titles in Rails?