opensoul.org

Abusing Rails I18N to Set Page Titles

November 5, 2012 code 3 min read

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…

This content is open source. Suggest Improvements.

@bkeepers

avatar of Brandon Keepers I am Brandon Keepers, and I work at GitHub on making Open Source more approachable, effective, and ubiquitous. I tend to think like an engineer, work like an artist, dream like an astronaut, love like a human, and sleep like a baby.