Capture lets you extract parts of code which can be used in other points of the template or even layout file.
Capturing a block into an instance variable
<% @script = capture do %>
[some html...]
<% end %>
Add javascript to header using content_for
content_for("name") is a wrapper for capture which will make the fragment available by name to a yielding layout or template.
layout.rhtml:
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>layout with js</title>
<script type="text/javascript">
<%= yield :script %>
</script>
</head>
<body>
<%= yield %>
</body>
</html>
view.rhtml
This page shows an alert box!
<% content_for("script") do %>
alert('hello world')
<% end %>
Normal view text
Capture allows you to extract a part of the template into an instance variable. You can use this instance variable anywhere in your templates and even in your layout.
Example of capture being used in a .rhtml page:
<% @greeting = capture do %>
Welcome To my shiny new web page!
<% end %>
Example of capture being used in a .rxml page:
@greeting = capture do
'Welcome To my shiny new web page!'
end
[ show source ]
# File vendor/rails/actionpack/lib/action_view/helpers/capture_helper.rb, line 56
56: def capture(*args, &block)
57: # execute the block
58: begin
59: buffer = eval("_erbout", block.binding)
60: rescue
61: buffer = nil
62: end
63:
64: if buffer.nil?
65: capture_block(*args, &block)
66: else
67: capture_erb_with_buffer(buffer, *args, &block)
68: end
69: end
Calling content_for stores the block of markup for later use. Subsequently, you can make calls to it by name with yield in another template or in the layout.
Example:
<% content_for("header") do %>
alert('hello world')
<% end %>
You can use yield :header anywhere in your templates.
<%= yield :header %>
NOTE: Beware that content_for is ignored in caches. So you shouldn‘t use it for elements that are going to be fragment cached.
The deprecated way of accessing a content_for block was to use a instance variable named @@content_for_#{name_of_the_content_block}@. So <%= content_for(‘footer’) %> would be avaiable as <%= @content_for_footer %>. The preferred notation now is <%= yield :footer %>.
[ show source ]
# File vendor/rails/actionpack/lib/action_view/helpers/capture_helper.rb, line 92
92: def content_for(name, content = nil, &block)
93: eval "@content_for_#{name} = (@content_for_#{name} || '') + capture(&block)"
94: end