Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails 3: yield/content_for with some default value?

Is there any way to detect if #content_for was actually applied to a yield scope in Rails?

A classic example being something like:

<title><%= yield :page_title %></title>

If a template doesn't set that with

<% content_for :page_title, "Something here" %>

Is there a way to have the layout put something else there instead?

I tried defining it with #content_for in the layout itself, but this just causes the text to be doubled-up. I also tried:

<%= (yield :page_title) or default_page_title %>

Where #default_page_title is a view helper.

This just left the block completely empty.

like image 517
d11wtq Avatar asked May 07 '11 16:05

d11wtq


3 Answers

You can use content_for? to check if there is content with a specific name:

<% if content_for?(:page_title) %>
  <%= yield(:page_title) %>
<% else %>
  <%= default_page_title %>
<% end %>

or

<%= content_for?(:page_title) ? yield(:page_title) : default_page_title %>

Then in your views you can specify the content like

<% content_for :page_title do %>
    Awesome page
<% end %>
like image 145
Dylan Markow Avatar answered Oct 20 '22 00:10

Dylan Markow


As of Rails 3, yield() returns empty string if there was no content for the requested key, so you can do something like this:

<title><%= yield(:page_title).presence || 'Default Page Title' %></title>

In your application helper, if you define:

def page_title(title = nil)
  title ? content_for(:page_title) { title } : content_for(:page_title).presence
end

Then you can do something like this:

<title><%= page_title or 'Default Page Title' %></title>

And in your views you can customize with:

<% page_title 'My Page Title' %>
like image 16
Joshua Coady Avatar answered Oct 20 '22 00:10

Joshua Coady


Better answer for rails 3 here:

Yield and default case || do not output default case

<%= yield(:title).presence || 'My Default Title' %>

like image 6
cyrilchampier Avatar answered Oct 20 '22 00:10

cyrilchampier