Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can Ruby on Rails's "content_for :title" get something that is assigned later?

The short question is: how can a subpage's

<% content_for :title do 'Showing product' end %>

set the :title for the main layout?


details:

We can use in the application layout application.html.erb

<title><%= content_for :title %>
  ...
  <%= yield %>

and I think yield returns the content for a subpage, such as from show.html.erb, where it contains:

<% content_for :title do 'Showing product' end %>

How can the :title somehow get used by something above the yield? I thought the title part is evaluated first, and then the yield, so how can the :title retroactively set the content for the <title> tag?

like image 718
nonopolarity Avatar asked Nov 07 '10 18:11

nonopolarity


2 Answers

Short answer: By cheating.

Long answer: ActionView redefines yield so it is not the same yield we know and love from good ol' ruby. In fact the template file is rendered before the layout file and then the yield in the layout file will be substituted by the already rendered template. content_for blocks are saved into class variables and so you can later access them from your layout.

like image 118
Jakub Hampl Avatar answered Oct 05 '22 23:10

Jakub Hampl


I defined a helper method title in my application_helper.rb file like so:

module ApplicationHelper
  def title(page_title)
    content_for(:title){ page_title }
    page_title
  end
end

Then at the top of my content ERB files I can do this

<% title "Rails Rocks" %>
Other regular content

And in the application.html.erb

<html>
<head>
  <% title = yield(:title).chop! %>
  <title><%= title || 'Default Title' %></title>
</head>
<body>
  <h1 class="title"><%= title %></h1>
</body>
like image 33
Paul Alexander Avatar answered Oct 06 '22 01:10

Paul Alexander