This post originated from an RSS feed registered with Ruby Buzz
by Robby Russell.
Original Post: Managing SEO-friendly HTML Titles with Rails
Feed Title: Robby on Rails
Feed URL: http://feeds.feedburner.com/RobbyOnRails
Feed Description: Ruby on Rails development, consulting, and hosting from the trenches...
I’ve seen this come up a few times in the #rubyonrails IRC channel and figured that I’d post a quick entry for future reference.
Problem: HTML titles
You want to have a clean way to manage the titles on your HTML pages.
<html>
<head>
<title>Robby on Rails — Article Title Goes Here</title>
</head>
<body>
...
Possible Solution(s):
Since the <title> tag is usually declared in your layout, you need to be able to dynamically update this information from almost every action in your application.
Here are a few ways that I’ve seen this handled.
Use a instance variable, which would have a default value and you could override it in any controller action
Use the content_for method to manage it.
Let’s take a few minutes to look at these two approaches.
Instance Variable
With the instance variable, you might end up with something like:
# app/views/layouts/application.html.erb
<title>Robby on Rails — <%= @html_title || 'Default text here...' -%></title>
Then in a controller action…
# app/controllers/articles_controller.rb
def show
# ...
@html_title = @article.title
end
So, that’s one way to handle it and is probably a more common way.
content_for helper method approach
This solution is very similar (and underneath uses an instance variable).
We’ll use the content_for and a little yield action.
# app/views/layouts/application.html.erb
<title>Robby on Rails <%= (html_title = yield :html_title) ? html_title : '— Default text here...' %></title>
Then we’ll create a helper method.
# app/helpers/application_helper.rb
def set_html_title(str="")
unless str.blank?
content_for :html_title do
"— #{str} "
end
end
end
Now, instead of defining the HTML<title> value in the controllers, we’ll just toss this into our html.erb files as necessary.
<% set_html_title(@article.name) -%>
... rest of view
..and that’s pretty much it.
Which is the better solution?
This is where we’ll not find a lot of consensus amongst people. I’m a fan of the content_for-based approach and defining the title in views rather than in controller actions. I’m an advocate of skinny controllers and while I’m not a big fan of messy views, I believe that there is less overhead in managing this within the View-world.
I’d love to hear your thoughts on this. Perhaps you have a better solution for managing things like this? Do share. :-)