Skip to content
Browse files

move capturing to its own extension

  • Loading branch information...
1 parent 6d8d4aa commit 8db79da471d6f06d7a70ed88f3bb03db6d5bc212 @rkh rkh committed
Showing with 55 additions and 25 deletions.
  1. +46 −0 lib/sinatra/capture.rb
  2. +6 −25 lib/sinatra/content_for.rb
  3. +2 −0 lib/sinatra/contrib.rb
  4. +1 −0 sinatra-contrib.gemspec
View
46 lib/sinatra/capture.rb
@@ -0,0 +1,46 @@
+require 'sinatra/base'
+
+module Sinatra
+ module Capture
+ DUMMIES = {
+ Tilt::HamlTemplate => "!= capture_haml(*args, &block)",
+ Tilt::ERBTemplate => "<% yield(*args) %>",
+ Tilt::ErubisTemplate => "<%= yield(*args) %>",
+ :slim => "== yield(*args)"
+ }
+
+ def call!(env)
+ @current_engine = :ruby
+ super
+ end
+
+ def capture(options = {}, &block)
+ opts = { :block => block, :args => [] }.merge options
+ engine = opts.delete(:engine) || @current_engine
+ block = opts[:block]
+ if engine == :ruby
+ block[*opts[:args]]
+ else
+ dummy = DUMMIES[Tilt[engine]] || DUMMIES.fetch(engine)
+ eval '_buf.clear if defined? _buf', block.binding
+ render(engine, dummy, {}, opts, &block)
+ end
+ end
+
+ def capture_later(options = {}, &block)
+ opts = { :block => block, :args => [], :engine => @current_engine }
+ opts.merge options
+ end
+
+ private
+
+ def render(engine, *)
+ @current_engine, engine_was = engine.to_sym, @current_engine
+ super
+ ensure
+ @current_engine = engine_was
+ end
+ end
+
+ helpers Capture
+end
View
31 lib/sinatra/content_for.rb
@@ -1,4 +1,5 @@
require 'sinatra/base'
+require 'sinatra/capture'
module Sinatra
##
@@ -36,6 +37,8 @@ module Sinatra
# <tt>content_for</tt> setting the appropriate set of tags that should
# be added to the layout.
module ContentFor
+ include Capture
+
# Capture a block of content to be rendered later. For example:
#
# <% content_for :head do %>
@@ -50,8 +53,7 @@ module ContentFor
# Your blocks can also receive values, which are passed to them
# by <tt>yield_content</tt>
def content_for(key, &block)
- @current_engine ||= :ruby
- content_blocks[key.to_sym] << [@current_engine, block]
+ content_blocks[key.to_sym] << capture_later(&block)
end
# Render the captured blocks for a given key. For example:
@@ -72,33 +74,12 @@ def content_for(key, &block)
# Would pass <tt>1</tt> and <tt>2</tt> to all the blocks registered
# for <tt>:head</tt>.
def yield_content(key, *args)
- content_blocks[key.to_sym].map { |e,b| capture(e, args, b) }.join
- end
-
- def self.capture
- @capture ||= {}
+ opts = { :args => args }
+ content_blocks[key.to_sym].map { |c| capture c.merge(opts) }.join
end
private
- # generated templates will be cached by Sinatra in production
- capture[:haml] = "!= capture_haml(*args, &block)"
- capture[:erb] = "<% yield(*args) %>"
- capture[:erubis] = "<%= yield(*args) %>"
- capture[:slim] = "== yield(*args)"
-
- def capture(engine, args, block)
- eval '_buf.clear if defined? _buf', block.binding
- render(engine, Sinatra::ContentFor.capture.fetch(engine), {}, :args => args, :block => 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
View
2 lib/sinatra/contrib.rb
@@ -11,6 +11,8 @@ module Common
register :ConfigFile
register :Namespace
register :RespondWith
+
+ helpers :Capture
helpers :ContentFor
helpers :LinkHeader
end
View
1 sinatra-contrib.gemspec
@@ -28,6 +28,7 @@ Gem::Specification.new do |s|
"README.md",
"Rakefile",
"ideas.md",
+ "lib/sinatra/capture.rb",
"lib/sinatra/config_file.rb",
"lib/sinatra/content_for.rb",
"lib/sinatra/contrib.rb",

0 comments on commit 8db79da

Please sign in to comment.
Something went wrong with that request. Please try again.