The Pug Automatic

My Rails title helpers

Written November 26, 2007. Tagged Ruby, Ruby on Rails.

I figured I should blog the title helpers I made of late.

Usage

First, example usage. In an erb view:

<% self.title = "Foo" -%>

gives a title like "Foo – My Site".

<% self.full_title = "Foo" -%>

gives the title "Foo".

<% self.full_title = "Welcome to %s!" -%>

gives the title "Welcome to My Site!".

Things look even nicer in Haml:

- self.full_title = "Welcome to %s!"

Displaying the title

I like to define an ApplicationLayoutHelper for helpers that will only be used in that layout (you'll need to declare helper :all or helper ApplicationLayoutHelper in your ApplicationController). If you want to, though, you can just stick this helper method in ApplicationHelper:

def title
h(@title_full ? @title_full : [@title_prefix, SITE_TITLE].compact.join(' – '))
end

SITE_TITLE is e.g. "My Site" from the examples above. Instead of a constant, you might want to use an environment variable or a configuration object – whatever.

Note that we apply h() in this helper, so don't apply it to the title again or things can become overescaped.

Now, just use this helper where you want to display the title – typically in your application layout:

<title><%= title %></title>

Setting the title

I like to be able to set the title from controller as well as from its views. Thus, the setters are defined in ApplicationController:

class ApplicationController < ActionController::Base
helper_method :title=, :full_title=



protected

def title=(title)
@title_prefix = title
@template.instance_variable_set("@title_prefix", @title_prefix) # Necessary if set from view
end

def full_title=(title)
@title_full = title % SITE_TITLE
@template.instance_variable_set("@title_full", @title_full) # Necessary if set from view
end

end

The instance_variable_set bits are necessary when you set the title from a view: in Rails, controllers and views only share instance variables because Rails copies them to the view behind the scenes. If we set an instance variable on the controller after that has happened, we must copy it over ourselves.

Bonus tip: you can override these setters per-controller if you want to:

class UsersController < ApplicationController
protected
def title=(title)
super("Users: #{title}")
end
end

This isn't rocket surgery, but I thought it was worth blogging. I like the self.title= syntax a lot.