Written November 26, 2007. Tagged Ruby, Ruby on Rails.
I figured I should blog the title helpers I made of late.
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!"
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>
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.