Froze rails gems
[depot.git] / vendor / rails / actionpack / lib / action_view / helpers / capture_helper.rb
diff --git a/vendor/rails/actionpack/lib/action_view/helpers/capture_helper.rb b/vendor/rails/actionpack/lib/action_view/helpers/capture_helper.rb
new file mode 100644 (file)
index 0000000..e86ca27
--- /dev/null
@@ -0,0 +1,136 @@
+module ActionView
+  module Helpers
+    # CaptureHelper exposes methods to let you extract generated markup which
+    # can be used in other parts of a template or layout file.
+    # It provides a method to capture blocks into variables through capture and 
+    # a way to capture a block of markup for use in a layout through content_for.
+    module CaptureHelper
+      # The capture method allows you to extract part of a template into a 
+      # variable. You can then use this variable anywhere in your templates or layout. 
+      # 
+      # ==== Examples
+      # The capture method can be used in ERb templates...
+      # 
+      #   <% @greeting = capture do %>
+      #     Welcome to my shiny new web page!  The date and time is
+      #     <%= Time.now %>
+      #   <% end %>
+      #
+      # ...and Builder (RXML) templates.
+      # 
+      #   @timestamp = capture do
+      #     "The current timestamp is #{Time.now}."
+      #   end
+      #
+      # You can then use that variable anywhere else.  For example:
+      #
+      #   <html>
+      #   <head><title><%= @greeting %></title></head>
+      #   <body>
+      #   <b><%= @greeting %></b>
+      #   </body></html>
+      #
+      def capture(*args, &block)
+        # Return captured buffer in erb.
+        if block_called_from_erb?(block)
+          with_output_buffer { block.call(*args) }
+        else
+          # Return block result otherwise, but protect buffer also.
+          with_output_buffer { return block.call(*args) }
+        end
+      end
+
+      # Calling content_for stores a block of markup in an identifier for later use.
+      # You can make subsequent calls to the stored content in other templates or the layout
+      # by passing the identifier as an argument to <tt>yield</tt>.
+      # 
+      # ==== Examples
+      # 
+      #   <% content_for :not_authorized do %>
+      #     alert('You are not authorized to do that!')
+      #   <% end %>
+      #
+      # You can then use <tt>yield :not_authorized</tt> anywhere in your templates.
+      #
+      #   <%= yield :not_authorized if current_user.nil? %>
+      #
+      # You can also use this syntax alongside an existing call to <tt>yield</tt> in a layout.  For example:
+      #
+      #   <%# This is the layout %>
+      #   <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+      #   <head>
+      #            <title>My Website</title>
+      #            <%= yield :script %>
+      #   </head>
+      #   <body>
+      #     <%= yield %>
+      #   </body>
+      #   </html>
+      #
+      # And now, we'll create a view that has a content_for call that
+      # creates the <tt>script</tt> identifier.
+      #
+      #   <%# This is our view %>
+      #   Please login!
+      #
+      #   <% content_for :script do %>
+      #     <script type="text/javascript">alert('You are not authorized to view this page!')</script>
+      #   <% end %>
+      #
+      # Then, in another view, you could to do something like this:
+      #
+      #   <%= link_to_remote 'Logout', :action => 'logout' %>
+      #
+      #   <% content_for :script do %>
+      #     <%= javascript_include_tag :defaults %>
+      #   <% end %>
+      #
+      # That will place <script> tags for Prototype, Scriptaculous, and application.js (if it exists)
+      # on the page; this technique is useful if you'll only be using these scripts in a few views.
+      #
+      # Note that content_for concatenates the blocks it is given for a particular
+      # identifier in order. For example:
+      #
+      #   <% content_for :navigation do %>
+      #     <li><%= link_to 'Home', :action => 'index' %></li>
+      #   <% end %>
+      #
+      #   <%#  Add some other content, or use a different template: %>
+      # 
+      #   <% content_for :navigation do %>
+      #     <li><%= link_to 'Login', :action => 'login' %></li>
+      #   <% end %>
+      #
+      # Then, in another template or layout, this code would render both links in order:
+      #
+      #   <ul><%= yield :navigation %></ul>
+      #
+      # Lastly, simple content can be passed as a parameter:
+      #
+      #   <% content_for :script, javascript_include_tag(:defaults) %>
+      #
+      # WARNING: content_for is ignored in caches. So you shouldn't use it
+      # for elements that will be fragment cached.
+      #
+      # The deprecated way of accessing a content_for block is to use an instance variable
+      # named <tt>@content_for_#{name_of_the_content_block}</tt>. The preferred usage is now
+      # <tt><%= yield :footer %></tt>.
+      def content_for(name, content = nil, &block)
+        ivar = "@content_for_#{name}"
+        content = capture(&block) if block_given?
+        instance_variable_set(ivar, "#{instance_variable_get(ivar)}#{content}")
+        nil
+      end
+
+      # Use an alternate output buffer for the duration of the block.
+      # Defaults to a new empty string.
+      def with_output_buffer(buf = '') #:nodoc:
+        self.output_buffer, old_buffer = buf, output_buffer
+        yield
+        output_buffer
+      ensure
+        self.output_buffer = old_buffer
+      end
+    end
+  end
+end