Class: Fiasco::Template::RenderContext
- Inherits:
-
Object
- Object
- Fiasco::Template::RenderContext
show all
- Defined in:
- lib/fiasco/template/render_context.rb
Defined Under Namespace
Classes: Entry, NullOutput
Instance Method Summary
collapse
-
#_compile(name, entry, locals = []) ⇒ Object
-
#_declare(options) {|entry| ... } ⇒ Object
-
#_process_locals(name, locals) ⇒ Object
-
#_render(name, locals = {}) ⇒ Object
-
#block(key, &b) ⇒ Object
-
#declare(name, options = {}) ⇒ Object
-
#display_value(value) ⇒ Object
-
#extends(base, *args) ⇒ Object
-
#initialize ⇒ RenderContext
constructor
A new instance of RenderContext.
-
#load_macros(options) ⇒ Object
-
#macro(mname, defaults = {}, &b) ⇒ Object
-
#render(name, locals = {}) ⇒ Object
(also: #[])
-
#superblock(*args) ⇒ Object
-
#yield_block(key, *args, &b) ⇒ Object
Constructor Details
Returns a new instance of RenderContext.
10
11
12
13
14
15
16
17
18
19
|
# File 'lib/fiasco/template/render_context.rb', line 10
def initialize
@content_blocks = Hash.new {|h,k| h[k] = [] }
@template_locals = Hash.new {|h,k| h[k] = [] }
@templates = {}
@compiled = Set.new
display_value = lambda do |outvar, literal|
"__tmp = (#{literal}); #{outvar} << display_value(__tmp)"
end
@compiler = Compiler.new(display_value: display_value)
end
|
Instance Method Details
#_compile(name, entry, locals = []) ⇒ Object
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
|
# File 'lib/fiasco/template/render_context.rb', line 62
def _compile(name, entry, locals = [])
src = "params ||= {}; @render_output ||= ''; "
locals.each {|var| src += "#{var} = params[:#{var}]; "}
src << "\n"
src << @compiler.compile(entry.body)
src << "\n@render_output"
meth = <<-EOS
#coding:UTF-8
define_singleton_method(:'__view__#{name}') do |params|
#{src}
end
EOS
eval(meth, binding, entry.filename || "(TEMPLATE:#{name})", -2)
@compiled << name
end
|
#_declare(options) {|entry| ... } ⇒ Object
91
92
93
94
95
96
97
98
99
100
101
|
# File 'lib/fiasco/template/render_context.rb', line 91
def _declare(options)
contents = options[:path] ? File.read(options[:path]) : options[:contents]
if contents.nil?
raise ArgumentError.new("Need either path or contents")
end
entry = Entry.new(contents, options[:path])
yield(entry)
end
|
#_process_locals(name, locals) ⇒ Object
79
80
81
82
83
84
85
86
87
88
89
|
# File 'lib/fiasco/template/render_context.rb', line 79
def _process_locals(name, locals)
seen_variables = @template_locals[name]
diff = locals.keys - seen_variables
unless diff.empty?
seen_variables += diff
@compiled.delete(name)
end
seen_variables
end
|
#_render(name, locals = {}) ⇒ Object
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
# File 'lib/fiasco/template/render_context.rb', line 108
def _render(name, locals = {})
name = name.to_s
variables = _process_locals(name, locals)
unless @compiled.include?(name)
entry = @templates.fetch(name) do
raise ArgumentError, "template `#{name}` not declared"
end
_compile(name, entry, variables)
end
send("__view__#{name}", locals)
if @extends
parent, pargs = @extends
@extends = nil
@render_output, @original_render_output = @original_render_output, nil
_render(parent, *pargs)
end
@render_output
end
|
#block(key, &b) ⇒ Object
21
22
23
|
# File 'lib/fiasco/template/render_context.rb', line 21
def block(key, &b)
@content_blocks[key.to_s] << b
end
|
#declare(name, options = {}) ⇒ Object
103
104
105
106
|
# File 'lib/fiasco/template/render_context.rb', line 103
def declare(name, options = {})
name = name.to_s
_declare(options) {|e| @templates[name] = e}
end
|
#display_value(value) ⇒ Object
141
142
143
144
|
# File 'lib/fiasco/template/render_context.rb', line 141
def display_value(value)
str = value.to_s
value.tainted? ? Rack::Utils.escape_html(str) : str
end
|
#extends(base, *args) ⇒ Object
55
56
57
58
59
60
|
# File 'lib/fiasco/template/render_context.rb', line 55
def extends(base, *args)
@render_output, @original_render_output = NullOutput.new, @render_output
@extends = [base, args]
end
|
#load_macros(options) ⇒ Object
161
162
163
164
165
166
167
168
169
|
# File 'lib/fiasco/template/render_context.rb', line 161
def load_macros(options)
@render_output, tmp = NullOutput.new, @render_output
b = binding
_declare(options) do |e|
eval(@compiler.compile(e.body), b, e.filename || 'MACROS')
end
ensure
@render_output = tmp
end
|
#macro(mname, defaults = {}, &b) ⇒ Object
146
147
148
149
150
151
152
153
154
155
156
157
158
159
|
# File 'lib/fiasco/template/render_context.rb', line 146
def macro(mname, defaults = {}, &b)
arguments = b.parameters
define_singleton_method mname do |named = defaults, &block|
args = arguments.select{|t| t[0] != :block}.map do |type, name|
named.fetch(name) do
defaults.fetch(name) do
msg = "Macro invocation '#{mname}' is missing a required argument: #{name}"
raise ArgumentError, msg, caller(10)
end
end
end
b.call(*args, &block)
end
end
|
#render(name, locals = {}) ⇒ Object
Also known as:
[]
132
133
134
135
136
137
|
# File 'lib/fiasco/template/render_context.rb', line 132
def render(name, locals = {})
_render(name, locals)
ensure
@content_blocks.clear
@render_output = nil
end
|
#superblock(*args) ⇒ Object
25
26
27
28
29
30
31
32
|
# File 'lib/fiasco/template/render_context.rb', line 25
def superblock(*args)
@blocklevel += 1
@content_blocks[@blockname][@blocklevel].call(*args)
ensure
@blocklevel -= 1
end
|
#yield_block(key, *args, &b) ⇒ Object
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
|
# File 'lib/fiasco/template/render_context.rb', line 34
def yield_block(key, *args, &b)
key = key.to_s
@content_blocks[key] << b if b
if @content_blocks[key].length > 0
begin
old_blocklevel, @blocklevel = @blocklevel, -1
old_blockname, @blockname = @blockname, key
superblock(*args)
ensure
@blocklevel, @blockname = old_blocklevel, old_blockname
end
else
''
end
end
|