/
capture.rb
123 lines (117 loc) · 2.87 KB
/
capture.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
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
DUMMIES = {
:haml => "!= capture_haml(*args, &block)",
:erubis => "<% @capture = yield(*args) %>",
:slim => "== yield(*args)"
}
def capture(*args, &block)
@capture = nil
if current_engine == :ruby
result = block[*args]
elsif current_engine == :erb || current_engine == :slim
@_out_buf, _buf_was = '', @_out_buf
block[*args]
result = eval('@_out_buf', block.binding)
@_out_buf = _buf_was
else
buffer = eval '_buf if defined?(_buf)', block.binding
old_buffer = buffer.dup if buffer
dummy = DUMMIES.fetch(current_engine)
options = { :layout => false, :locals => {:args => args, :block => block }}
buffer.clear unless buffer.nil?
result = render(current_engine, dummy, options, &block)
end
result.strip.empty? && @capture ? @capture : result
ensure
buffer.replace(old_buffer) unless buffer.nil?
end
def capture_later(&block)
engine = current_engine
proc { |*a| with_engine(engine) { @capture = capture(*a, &block) }}
end
end
helpers Capture
end