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
Source: show
# File rails/actionpack/lib/action_view/helpers/capture_helper.rb, line 56 def capture(*args, &block) # execute the block begin buffer = eval("_erbout", block.binding) rescue buffer = nil end if buffer.nil? capture_block(*args, &block) else capture_erb_with_buffer(buffer, *args, &block) end 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 %>
.
Source: show
# File rails/actionpack/lib/action_view/helpers/capture_helper.rb, line 92 def content_for(name, content = nil, &block) eval "@content_for_#{name} = (@content_for_#{name} || '') + capture(&block)" end