module ActionView::Helpers::CaptureHelper

def capture(*args)


@greeting # => "Welcome to my shiny new web page! The date and time is 2018-09-06 11:09:16 -0500"

The return of capture is the string generated by the block. For Example:



<%= @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...

You can then use this object anywhere in your templates, layout, or helpers.
The capture method extracts part of a template as a String object.
def capture(*args)
  value = nil
  buffer = with_output_buffer { value = yield(*args) }
  if (string = buffer.presence || value) && 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 another 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