sinatra/sinatra-contrib/lib/sinatra/capture.rb

114 lines
2.5 KiB
Ruby

require 'sinatra/base'
require 'sinatra/engine_tracking'
module Sinatra
#
# = Sinatra::Capture
#
# Extension that enables blocks inside other extensions.
# It currently works for erb, slim and haml.
# Enables mixing of different template languages.
#
# Example:
#
# # in hello_world.erb
#
# Say
# <% a = capture do %>World<% end %>
# Hello <%= a %>!
#
# # in hello_world.slim
#
# | Say
# - a = capture do
# | World
# | Hello #{a}!
#
# # in hello_world.haml
#
# Say
# - a = capture do
# World
# Hello #{a.strip}!
#
#
# You can also use nested blocks.
#
# Example
#
# # in hello_world.erb
#
# Say
# <% a = capture do %>
# <% b = capture do %>World<% end %>
# <%= b %>!
# <% end %>
# Hello <%= a.strip %>
#
#
# The main advantage of capture is mixing of different template engines.
#
# Example
#
# # in mix_me_up.slim
#
# - two = capture do
# - erb "<%= 1 + 1 %>"
# | 1 + 1 = #{two}
#
# == Usage
#
# === Classic Application
#
# In a classic application simply require the helpers, and start using them:
#
# require "sinatra"
# require "sinatra/capture"
#
# # The rest of your classic application code goes here...
#
# === Modular Application
#
# In a modular application you need to require the helpers, and then tell
# the application you will use them:
#
# require "sinatra/base"
# require "sinatra/capture"
#
# class MyApp < Sinatra::Base
# helpers Sinatra::Capture
#
# # The rest of your modular application code goes here...
# end
#
module Capture
include Sinatra::EngineTracking
def capture(*args, &block)
return block[*args] if ruby?
if haml? && Tilt[:haml] == Tilt::HamlTemplate && defined?(Haml::Buffer)
buffer = Haml::Buffer.new(nil, Haml::Options.new.for_buffer)
with_haml_buffer(buffer) { capture_haml(*args, &block) }
else
buf_was = @_out_buf
@_out_buf = ''
begin
raw = block[*args]
captured = block.binding.eval('@_out_buf')
captured.empty? ? raw : captured
ensure
@_out_buf = buf_was
end
end
end
def capture_later(&block)
engine = current_engine
proc { |*a| with_engine(engine) { @capture = capture(*a, &block) } }
end
end
helpers Capture
end