Rails 3 - Ideal way to set title of pages

you could a simple helper:

def title(page_title)
  content_for :title, page_title.to_s
end

use it in your layout:

<title><%= yield(:title) %></title>

then call it from your templates:

<% title "Your custom title" %>

hope this helps ;)


There's no need to create any extra function/helper. You should have a look to the documentation.

In the application layout

<% if content_for?(:title) %>
  <%= content_for(:title) %>
<% else %>
  <title>Default title</title>
<% end %>

In the specific layout

<% content_for :title do %>
  <title>Custom title</title>
<% end %>

I found that apeacox's solution didn't work for me (in Rails 3.0.3).

Instead I did...

In application_helper.rb:

def title(page_title, options={})
  content_for(:title, page_title.to_s)
  return content_tag(:h1, page_title, options)
end

In the layout:

<title><%= content_for(:title) %></title>

In the view:

<% title "Page Title Only" %>

OR:

<%= title "Page Title and Heading Too" %>

Note, this also allows us to check for the presence of a title and set a default title in cases where the view hasn't specified one.

In the layout we can do something like:

<title><%= content_for?(:title) ? content_for(:title) : 'This is a default title' %></title>

This is my preferred way of doing it:

application_helper.rb

module ApplicationHelper
  def title(*parts)
    content_for(:title) { (parts << t(:site_name)).join(' - ') } unless parts.empty?
  end
end

views/layouts/application.html.erb

<title>
  <%= content_for?(:title) ? yield(:title) : t(:site_name) %>
</title>

config/locales/en.yml

en:
  site_name: "My Website"

This has the nice advantage to always falling back to the site name in your locales, which can be translated on a per-language basis.

Then, on every other page (eg. on the About page) you can simply put:

views/home/about.html.erb

<% title 'About' %>

The resulting title for that page will be:

About - My Website

Simples :)


@akfalcon - I use a similar strategy, but without the helper.. I just set the default @title in the application controller and then use, <%=@title%> in my layout. If I want to override the title, I set it again in the controller action as you do. No magic involved, but it works just fine. I do the same for the meta description & keywords.

I am actually thinking about moving it to the database so an admin could change the titles,etc without having to update the Rails code. You could create a PageTitle model with content, action, and controller. Then create a helper that finds the PageTitle for the controller/action that you are currently rendering (using controller_name and action_name variables). If no match is found, then return the default.

@apeacox - is there a benefit of setting the title in the template? I would think it would be better to place it in the controller as the title relates directly to the action being called.