mirror of
https://github.com/sinatra/sinatra
synced 2023-03-27 23:18:01 -04:00
don't rely on template engine internals to capture a block, makes yield_content usage consistent in erb and haml, allows combining the two
This commit is contained in:
parent
7fa95253e3
commit
7e72a34a3a
4 changed files with 30 additions and 26 deletions
|
@ -9,7 +9,7 @@ module Sinatra
|
||||||
# <chunk of="html">...</chunk>
|
# <chunk of="html">...</chunk>
|
||||||
# <% end %>
|
# <% end %>
|
||||||
#
|
#
|
||||||
# <% yield_content :some_key %>
|
# <%= yield_content :some_key %>
|
||||||
#
|
#
|
||||||
# This allows you to capture blocks inside views to be rendered later
|
# This allows you to capture blocks inside views to be rendered later
|
||||||
# in this request. For example, to populate different parts of your
|
# in this request. For example, to populate different parts of your
|
||||||
|
@ -23,12 +23,6 @@ module Sinatra
|
||||||
#
|
#
|
||||||
# = yield_content :some_key
|
# = yield_content :some_key
|
||||||
#
|
#
|
||||||
# <b>Note</b> that with ERB <tt>yield_content</tt> is called <b>without</b>
|
|
||||||
# an '=' block (<tt><%= %></tt>), but with Haml it uses <tt>= yield_content</tt>.
|
|
||||||
#
|
|
||||||
# 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
|
# == Usage
|
||||||
#
|
#
|
||||||
# If you're writing "classic" style apps, then requring
|
# 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
|
# Your blocks can also receive values, which are passed to them
|
||||||
# by <tt>yield_content</tt>
|
# by <tt>yield_content</tt>
|
||||||
def content_for(key, &block)
|
def content_for(key, &block)
|
||||||
content_blocks[key.to_sym] << block
|
@current_engine ||= :ruby
|
||||||
|
content_blocks[key.to_sym] << [@current_engine, block]
|
||||||
end
|
end
|
||||||
|
|
||||||
# Render the captured blocks for a given key. For example:
|
# Render the captured blocks for a given key. For example:
|
||||||
#
|
#
|
||||||
# <head>
|
# <head>
|
||||||
# <title>Example</title>
|
# <title>Example</title>
|
||||||
# <% yield_content :head %>
|
# <%= yield_content :head %>
|
||||||
# </head>
|
# </head>
|
||||||
#
|
#
|
||||||
# Would render everything you declared with <tt>content_for
|
# Would render everything you declared with <tt>content_for
|
||||||
|
@ -80,25 +75,38 @@ module Sinatra
|
||||||
# You can also pass values to the content blocks by passing them
|
# You can also pass values to the content blocks by passing them
|
||||||
# as arguments after the key:
|
# as arguments after the key:
|
||||||
#
|
#
|
||||||
# <% yield_content :head, 1, 2 %>
|
# <%= yield_content :head, 1, 2 %>
|
||||||
#
|
#
|
||||||
# Would pass <tt>1</tt> and <tt>2</tt> to all the blocks registered
|
# Would pass <tt>1</tt> and <tt>2</tt> to all the blocks registered
|
||||||
# for <tt>:head</tt>.
|
# for <tt>:head</tt>.
|
||||||
#
|
|
||||||
# *NOTICE* that you call this without an <tt>=</tt> sign. IE,
|
|
||||||
# in a <tt><% %></tt> block, and not in a <tt><%= %></tt> block.
|
|
||||||
def yield_content(key, *args)
|
def yield_content(key, *args)
|
||||||
content_blocks[key.to_sym].map do |content|
|
content_blocks[key.to_sym].map { |e,b| capture(e, args, b) }.join
|
||||||
if respond_to?(:block_is_haml?) && block_is_haml?(content)
|
|
||||||
capture_haml(*args, &content)
|
|
||||||
else
|
|
||||||
content.call(*args)
|
|
||||||
end
|
end
|
||||||
end.join
|
|
||||||
|
def self.capture(name, template = nil)
|
||||||
|
@capture ||= {}
|
||||||
|
@capture[name] = template if template
|
||||||
|
@capture[name]
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
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
|
def content_blocks
|
||||||
@content_blocks ||= Hash.new {|h,k| h[k] = [] }
|
@content_blocks ||= Hash.new {|h,k| h[k] = [] }
|
||||||
end
|
end
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
<% yield_content :foo %>
|
<%= yield_content :foo %>
|
|
@ -1 +1 @@
|
||||||
<% yield_content :foo, 1, 2 %>
|
<%= yield_content :foo, 1, 2 %>
|
|
@ -11,10 +11,6 @@ describe Sinatra::ContentFor do
|
||||||
super.gsub(/\s/, '')
|
super.gsub(/\s/, '')
|
||||||
end
|
end
|
||||||
|
|
||||||
before do
|
|
||||||
pending "different layout engines not supported yet" unless inner == outer
|
|
||||||
end
|
|
||||||
|
|
||||||
before :all do
|
before :all do
|
||||||
begin
|
begin
|
||||||
require inner
|
require inner
|
||||||
|
|
Loading…
Reference in a new issue