Permalink
Browse files

Updated how the content_for code works. It is slightly different -- a…

… blending

of the Rails and Merb tehcniques. Instead of creating an instance variable for
each hunk of content, they are all stored in a @_content_for hash. Content is
stored and retrieved using the same method -- if you pass it arguments then you
are storing content; without arguments you are retrieving content.
  • Loading branch information...
1 parent 201dd1e commit 9ef7e0acd86cec85e798e02c5905b7b95e79e818 @TwP TwP committed Jun 1, 2008
Showing with 110 additions and 30 deletions.
  1. +82 −17 lib/webby/helpers/capture_helper.rb
  2. +1 −0 lib/webby/renderer.rb
  3. +27 −13 spec/webby/helpers/capture_helper_spec.rb
View
99 lib/webby/helpers/capture_helper.rb
@@ -5,38 +5,84 @@ module Webby::Helpers
#
module CaptureHelper
+ # Called in pages and partials to store up content for later use. Takes a
+ # string and/or a block. First, the string is evaluated, and then the
+ # block is captured using the capture() helper provided by the template
+ # languages. The two are concatenated together.
+ #
+ # Content is retrieved by calling the method without a string or a block.
+ #
+ # ==== Parameters
+ # obj<Object>:: The key in the conetnt_for hash.
+ # string<String>:: Textual content. Defaults to nil.
+ # &block:: A block to be evaluated and concatenated to string.
+ #
+ # ==== Returns
+ # Any content associated with the key (or nil).
+ #
+ # ==== Example
+ # content_for(:foo, "Foo")
+ # content_for(:foo) #=> "Foo"
+ # content_for(:foo, "Bar")
+ # content_for(:foo) #=> "FooBar"
+ #
+ def content_for( obj, string = nil, &block )
+ return @_content_for[obj] unless string || block_given?
- def content_for( name, content = nil, &block )
- cur = instance_variable_get("@content_for_#{name}").to_s
- new = if block.nil? then content
- else capture_erb(&block) end
+ cur = @_content_for[obj].to_s
+ new = string.to_s + (block_given? ? capture_erb(&block) : "")
+ @_content_for[obj] = cur + new
+ end
- new = cur + new.to_s
- instance_variable_set("@content_for_#{name}", new)
+ # Returns true if there is content for the given key. Otherwise returns
+ # false.
+ #
+ # ==== Parameters
+ # obj<Object>:: The key in the conetnt_for hash.
+ #
+ # ==== Example
+ # content_for(:foo, "Foo")
+ # content_for?(:foo) #=> true
+ # content_for?(:bar) #=> false
+ #
+ def content_for?( obj )
+ @_content_for.key?(obj)
end
- # Provides direct acccess to the buffer for this view context
+ # Deletes any content associated with the given object in the content_for
+ # hash.
#
# ==== Parameters
- # the_binding<Binding>:: The binding to pass to the buffer.
+ # obj<Object>:: The key in the conetnt_for hash.
#
# ==== Returns
- # DOC
- def _erb_buffer( the_binding )
- eval("_erbout", the_binding, __FILE__, __LINE__)
+ # Any content associated with the key (or nil).
+ #
+ # ==== Example
+ # content_for(:foo, "Foo")
+ # content_for?(:foo) #=> true
+ # delete_content_for(:foo)
+ # content_for?(:foo) #=> false
+ #
+ def delete_content_for( obj )
+ @_content_for.delete(obj)
end
+ # This method is used to capture content from an ERB filter evaluation. It
+ # is useful to helpers that need to process chunks of data during ERB filter
+ # processing.
+ #
# ==== Parameters
# *args:: Arguments to pass to the block.
- # &block:: The template block to call.
+ # &block:: The ERB block to call.
#
# ==== Returns
# String:: The output of the block.
#
# ==== Examples
- # Capture being used in a .html.erb page:
+ # Capture being used in an ERB page:
#
- # <% @foo = capture do %>
+ # <% @foo = capture_erb do %>
# <p>Some Foo content!</p>
# <% end %>
#
@@ -56,17 +102,36 @@ def capture_erb( *args, &block )
data = buffer[pos..-1]
# replace it in the original with empty string
- buffer[pos..-1] = ''
+ buffer[pos..-1] = ""
data
end
end
- # DOC
- def concat_erb(string, the_binding)
+ # This method is used to concatenate content into the ERB output buffer.
+ # It is usefule to helpers that need to insert transformed text back into
+ # the ERB output buffer.
+ #
+ # ==== Parameters
+ # string<String>:: The string to insert into the ERB output.
+ # the_binding<Binding>:: The binding to pass to the buffer.
+ #
+ def concat_erb( string, the_binding )
_erb_buffer(the_binding) << string
end
+ # Provides direct acccess to the ERB buffer in the conext of the binding.
+ #
+ # ==== Parameters
+ # the_binding<Binding>:: The binding to pass to the buffer.
+ #
+ # ==== Returns
+ # The current ERB output buffer.
+ #
+ def _erb_buffer( the_binding )
+ eval("_erbout", the_binding, __FILE__, __LINE__)
+ end
+
end # module CaptureHelper
register(CaptureHelper)
View
1 lib/webby/renderer.rb
@@ -63,6 +63,7 @@ def initialize( page )
@config = ::Webby.site
@_bindings = []
+ @_content_for = {}
@log = Logging::Logger[self]
end
View
40 spec/webby/helpers/capture_helper_spec.rb
@@ -1,5 +1,6 @@
-require ::File.join(::File.dirname(__FILE__), %w[.. .. spec_helper])
+require ::File.expand_path(
+ ::File.join(::File.dirname(__FILE__), %w[.. .. spec_helper]))
# ---------------------------------------------------------------------------
describe Webby::Helpers::CaptureHelper do
@@ -15,28 +16,41 @@
"<% end %>"
]
- before do
+ before :all do
::File.open(CFN,'w') {|fd| fd.write CLINES.join("\n") }
- @page = Webby::Resources::Page.new(CFN)
- @renderman = Webby::Renderer.new(@page)
- @page_content = @page.render( @renderman )
end
-
- after do
- ::FileUtils.rm_f(CFN)
+
+ before :each do
+ @renderman = Webby::Renderer.new(
+ Webby::Resources::Page.new(CFN))
+ @page_content = @renderman.render_page
end
+ after :all do
+ ::FileUtils.rm_f(CFN)
+ end
it 'should not "leak" any content to containing page' do
@page_content.should_not be_nil
@page_content.should eql("Hello world!\n")
end
-
- it "should create an instance variable containing the nested content" do
- @renderman.instance_variable_get("@content_for_sidebar").should_not be_nil
- @renderman.instance_variable_get("@content_for_sidebar").should eql("\nI'm sidebar content.\n") # Note: Leading newline
+
+ it "should return the stored content for the given key" do
+ @renderman.content_for(:sidebar).should_not be_nil
+ @renderman.content_for(:sidebar).should eql("\nI'm sidebar content.\n") # Note: Leading newline
+ end
+
+ it "should report if content is associated with a given key" do
+ @renderman.content_for?(:sidebar).should == true
+ @renderman.content_for?(:header).should == false
+ end
+
+ it "should clear content associated with a given key" do
+ @renderman.content_for?(:sidebar).should == true
+ @renderman.delete_content_for(:sidebar)
+ @renderman.content_for?(:sidebar).should == false
end
-end # describe Webby::Resources::File
+end
# EOF

0 comments on commit 9ef7e0a

Please sign in to comment.