module ActionView::Helpers::CaptureHelper

def capture(*args)



<%= @greeting %>

<%= @greeting %>


You can then use that variable anywhere else. For example:

end
"The current timestamp is #{Time.now}."
@timestamp = capture do

...and Builder (RXML) templates.

<% end %>
<%= Time.now %>
Welcome to my shiny new web page! The date and time is
<% @greeting = capture do %>

The capture method can be used in ERB templates...

variable. You can then use this variable anywhere in your templates or layout.
The capture method allows you to extract part of a template into a
def capture(*args)
  value = nil
  buffer = with_output_buffer { value = yield(*args) }
  if string = buffer.presence || value and string.is_a?(String)
    ERB::Util.html_escape string
  end
end

def content_for(name, content = nil, options = {}, &block)

WARNING: content_for is ignored in caches. So you shouldn't use it for elements that will be fragment cached.

<% content_for :script, javascript_include_tag(:defaults) %>

Lastly, simple content can be passed as a parameter:

    <%= content_for :navigation %>


Then, in another template or layout, this code would render only the last link:

<% end %>
  • <%= link_to 'Login', action: 'login' %>

  • <% content_for :navigation, flush: true do %>

    <%# Add some other content, or use a different template: %>

    <% end %>
  • <%= link_to 'Home', action: 'index' %>

  • <% content_for :navigation do %>

    If the flush parameter is true content_for replaces the blocks it is given. For example:

      <%= content_for :navigation %>


    Then, in another template or layout, this code would render both links in order:

    <% end %>
  • <%= link_to 'Login', action: 'login' %>

  • <% content_for :navigation do %>

    And in other place:

    <% end %>
  • <%= link_to 'Home', action: 'index' %>

  • <% content_for :navigation do %>

    identifier in order. For example:
    Note that content_for concatenates (default) the blocks it is given for a particular

    this technique is useful if you'll only be using these scripts in a few views.
    That will place +script+ tags for your default set of JavaScript files on the page;

    <% end %>
    <%= javascript_include_tag :defaults %>
    <% content_for :script do %>

    <%= link_to 'Logout', action: 'logout', remote: true %>

    Then, in another view, you could to do something like this:

    <% end %>

    <% content_for :script do %>

    Please login!
    <%# This is our view %>

    creates the script identifier.
    And now, we'll create a view that has a content_for call that



    <%= yield %>


    <%= yield :script %>
    My Website


    <%# This is the layout %>

    yield in a layout. For example:
    You can also use the yield syntax alongside an existing call to

    <%= stored_content %>

    This helper works just like normal helpers.

    end
    end
    content_for(:storage) || "Your storage is empty"
    def stored_content
    module StorageHelper

    content_for, however, can also be used in helper modules.

    <%= yield :not_authorized if current_user.nil? %>

    This is equivalent to:

    <%= content_for :not_authorized if current_user.nil? %>

    You can then use content_for :not_authorized anywhere in your templates.

    <% end %>
    alert('You are not authorized to do that!')
    <% content_for :not_authorized do %>

    yield doesn't work in helper modules, while content_for does.
    Note: yield can still be used to retrieve the stored content, but calling

    or the layout, you would pass the identifier as an argument to content_for.
    In order to access this stored content in other templates, helper modules
    Calling content_for stores a block of markup in an identifier for later use.
    def content_for(name, content = nil, options = {}, &block)
      if content || block_given?
        if block_given?
          options = content if content
          content = capture(&block)
        end
        if content
          options[:flush] ? @view_flow.set(name, content) : @view_flow.append(name, content)
        end
        nil
      else
        @view_flow.get(name).presence
      end
    end

    def content_for?(name)



    <%= yield :right_col %>
    <%= yield %>


    <%= yield :script %>
    My Website


    <%# This is the layout %>

    Useful to render parts of your layout differently based on what is in your views.
    content_for? checks whether any content has been captured yet using `content_for`.
    def content_for?(name)
      @view_flow.get(name).present?
    end

    def provide(name, content = nil, &block)

    the layout to stop looking for more contents.
    template, you should use +content_for+, if not, use +provide+ to tell
    concatenate several times to the same buffer when rendering a given
    straight back to the layout. In other words, if you want to
    The same as +content_for+ but when used with streaming flushes
    def provide(name, content = nil, &block)
      content = capture(&block) if block_given?
      result = @view_flow.append!(name, content) if content
      result unless content
    end

    def with_output_buffer(buf = nil) #:nodoc:

    :nodoc:
    Defaults to a new empty string.
    Use an alternate output buffer for the duration of the block.
    def with_output_buffer(buf = nil) #:nodoc:
      unless buf
        buf = ActionView::OutputBuffer.new
        if output_buffer && output_buffer.respond_to?(:encoding)
          buf.force_encoding(output_buffer.encoding)
        end
      end
      self.output_buffer, old_buffer = buf, output_buffer
      yield
      output_buffer
    ensure
      self.output_buffer = old_buffer
    end