From 7e72a34a3aff17c578bdbb8981c694363138618a Mon Sep 17 00:00:00 2001 From: Konstantin Haase Date: Mon, 28 Mar 2011 16:06:17 +0200 Subject: [PATCH] don't rely on template engine internals to capture a block, makes yield_content usage consistent in erb and haml, allows combining the two --- sinatra-contrib/lib/sinatra/content_for.rb | 48 +++++++++++-------- sinatra-contrib/spec/content_for/layout.erb | 2 +- .../spec/content_for/passes_values.erb | 2 +- sinatra-contrib/spec/content_for_spec.rb | 4 -- 4 files changed, 30 insertions(+), 26 deletions(-) diff --git a/sinatra-contrib/lib/sinatra/content_for.rb b/sinatra-contrib/lib/sinatra/content_for.rb index 039b2218..66156ba2 100644 --- a/sinatra-contrib/lib/sinatra/content_for.rb +++ b/sinatra-contrib/lib/sinatra/content_for.rb @@ -9,7 +9,7 @@ module Sinatra # ... # <% end %> # - # <% yield_content :some_key %> + # <%= yield_content :some_key %> # # This allows you to capture blocks inside views to be rendered later # in this request. For example, to populate different parts of your @@ -23,12 +23,6 @@ module Sinatra # # = yield_content :some_key # - # Note that with ERB yield_content is called without - # an '=' block (<%= %>), but with Haml it uses = yield_content. - # - # Using an '=' block in ERB will output the content twice for each block, - # so if you have problems with that, make sure to check for this. - # # == Usage # # If you're writing "classic" style apps, then requring @@ -64,14 +58,15 @@ module Sinatra # Your blocks can also receive values, which are passed to them # by yield_content def content_for(key, &block) - content_blocks[key.to_sym] << block + @current_engine ||= :ruby + content_blocks[key.to_sym] << [@current_engine, block] end # Render the captured blocks for a given key. For example: # # # Example - # <% yield_content :head %> + # <%= yield_content :head %> # # # Would render everything you declared with content_for @@ -80,25 +75,38 @@ module Sinatra # You can also pass values to the content blocks by passing them # as arguments after the key: # - # <% yield_content :head, 1, 2 %> + # <%= yield_content :head, 1, 2 %> # # Would pass 1 and 2 to all the blocks registered # for :head. - # - # *NOTICE* that you call this without an = sign. IE, - # in a <% %> block, and not in a <%= %> block. def yield_content(key, *args) - content_blocks[key.to_sym].map do |content| - if respond_to?(:block_is_haml?) && block_is_haml?(content) - capture_haml(*args, &content) - else - content.call(*args) - end - end.join + content_blocks[key.to_sym].map { |e,b| capture(e, args, b) }.join + end + + def self.capture(name, template = nil) + @capture ||= {} + @capture[name] = template if template + @capture[name] end private + # generated templates will be cached by Sinatra in production + capture :haml, "= capture_haml(*args, &block)" + capture :erb, "<% block.call(*args) %>" + + def capture(engine, args, block) + render(engine, Sinatra::ContentFor.capture(engine), {}, + :args => args, :block => block) + end + + def render(engine, *) + @current_engine, engine_was = engine.to_sym, @current_engine + super + ensure + @current_engine = engine_was + end + def content_blocks @content_blocks ||= Hash.new {|h,k| h[k] = [] } end diff --git a/sinatra-contrib/spec/content_for/layout.erb b/sinatra-contrib/spec/content_for/layout.erb index c7bc9102..22cdc056 100644 --- a/sinatra-contrib/spec/content_for/layout.erb +++ b/sinatra-contrib/spec/content_for/layout.erb @@ -1 +1 @@ -<% yield_content :foo %> \ No newline at end of file +<%= yield_content :foo %> \ No newline at end of file diff --git a/sinatra-contrib/spec/content_for/passes_values.erb b/sinatra-contrib/spec/content_for/passes_values.erb index f7b00777..6034243e 100644 --- a/sinatra-contrib/spec/content_for/passes_values.erb +++ b/sinatra-contrib/spec/content_for/passes_values.erb @@ -1 +1 @@ -<% yield_content :foo, 1, 2 %> \ No newline at end of file +<%= yield_content :foo, 1, 2 %> \ No newline at end of file diff --git a/sinatra-contrib/spec/content_for_spec.rb b/sinatra-contrib/spec/content_for_spec.rb index 88272dc8..9347353e 100644 --- a/sinatra-contrib/spec/content_for_spec.rb +++ b/sinatra-contrib/spec/content_for_spec.rb @@ -11,10 +11,6 @@ describe Sinatra::ContentFor do super.gsub(/\s/, '') end - before do - pending "different layout engines not supported yet" unless inner == outer - end - before :all do begin require inner