zafu 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +11 -0
- data/Rakefile +2 -1
- data/lib/zafu/all.rb +6 -4
- data/lib/zafu/controller_methods.rb +27 -18
- data/lib/zafu/info.rb +1 -1
- data/lib/zafu/markup.rb +87 -25
- data/lib/zafu/node_context.rb +48 -4
- data/lib/zafu/ordered_hash.rb +47 -0
- data/lib/zafu/parser.rb +140 -55
- data/lib/zafu/parsing_rules.rb +49 -17
- data/lib/zafu/process/ajax.rb +344 -66
- data/lib/zafu/process/conditional.rb +36 -25
- data/lib/zafu/process/context.rb +101 -4
- data/lib/zafu/process/forms.rb +124 -0
- data/lib/zafu/process/html.rb +78 -83
- data/lib/zafu/process/ruby_less_processing.rb +248 -0
- data/lib/zafu/test_helper.rb +1 -1
- data/lib/zafu/view_methods.rb +6 -0
- data/test/markup_test.rb +150 -8
- data/test/mock/classes.rb +24 -0
- data/test/mock/core_ext.rb +9 -0
- data/test/mock/params.rb +4 -10
- data/test/mock/process.rb +7 -0
- data/test/mock/test_compiler.rb +9 -0
- data/test/node_context_test.rb +135 -46
- data/test/ordered_hash_test.rb +69 -0
- data/test/ruby_less_test.rb +29 -19
- data/test/test_helper.rb +4 -3
- data/test/zafu/ajax.yml +7 -0
- data/test/zafu/asset.yml +3 -0
- data/test/zafu/basic.yml +3 -0
- data/test/zafu/markup.yml +4 -0
- data/test/zafu/meta.yml +8 -0
- data/test/zafu/security.yml +19 -0
- data/test/zafu_test.rb +29 -12
- data/zafu.gemspec +28 -6
- metadata +41 -8
- data/lib/zafu/process/ruby_less.rb +0 -145
data/lib/zafu/process/ajax.rb
CHANGED
@@ -1,90 +1,368 @@
|
|
1
1
|
module Zafu
|
2
2
|
module Process
|
3
3
|
module Ajax
|
4
|
+
def save_state
|
5
|
+
super.merge(:@markup => @markup.dup)
|
6
|
+
end
|
7
|
+
|
8
|
+
|
9
|
+
# This method process a list and handles building the necessary templates for ajax 'add'.
|
10
|
+
def expand_with_finder(finder)
|
11
|
+
return super unless finder[:class].kind_of?(Array)
|
12
|
+
|
13
|
+
# Get the block responsible for rendering each elements in the list
|
14
|
+
each_block = descendant('each')
|
15
|
+
add_block = descendant('add')
|
16
|
+
form_block = descendant('form') || each_block
|
17
|
+
edit_block = descendant('edit')
|
18
|
+
|
19
|
+
|
20
|
+
# Should 'edit' and 'add' auto-publish ?
|
21
|
+
publish_after_save = (form_block && form_block.params[:publish]) ||
|
22
|
+
(edit_block && edit_block.params[:publish])
|
23
|
+
|
24
|
+
# class name for create form
|
25
|
+
klass = (add_block && add_block.params[:klass]) ||
|
26
|
+
(form_block && form_block.params[:klass])
|
27
|
+
|
28
|
+
if need_ajax?(each_block)
|
29
|
+
# We need to build the templates for ajax rendering.
|
30
|
+
|
31
|
+
# 1. Render inline
|
32
|
+
# assign [] to var
|
33
|
+
out "<% if (#{var} = #{finder[:method]}) || (#{node}.#{node.will_be?(Comment) ? "can_comment?" : "can_write?"} && #{var}=[]) -%>"
|
34
|
+
# The list is not empty or we have enough rights to add new elements.
|
35
|
+
set_dom_prefix
|
36
|
+
|
37
|
+
# New node context.
|
38
|
+
open_node_context(finder, :node => self.node.move_to(var, finder[:class])) do #, :need_link_id => form_block.need_link_id) do
|
39
|
+
# Pagination count and other contextual variables exist here.
|
40
|
+
|
41
|
+
# INLINE ==========
|
42
|
+
# 'r_add' needs the form when rendering. Send with :form.
|
43
|
+
out @markup.wrap(
|
44
|
+
expand_with(
|
45
|
+
:in_if => false,
|
46
|
+
:form => form_block,
|
47
|
+
:publish_after_save => publish_after_save,
|
48
|
+
# Do not render the form block directly: let [add] do this.
|
49
|
+
:ignore => ['form'],
|
50
|
+
:klass => klass
|
51
|
+
)
|
52
|
+
)
|
53
|
+
|
54
|
+
# Render 'else' clauses
|
55
|
+
@markup.done = false
|
56
|
+
out @markup.wrap(
|
57
|
+
expand_with(
|
58
|
+
:in_if => true,
|
59
|
+
:only => ['elsif', 'else']
|
60
|
+
)
|
61
|
+
)
|
62
|
+
end
|
63
|
+
out "<% end -%>"
|
64
|
+
|
65
|
+
# 2. Save 'each' template
|
66
|
+
store_block(each_block) #, :klass => klass) # do we need klass here ?
|
67
|
+
|
68
|
+
# 3. Save 'form' template
|
69
|
+
cont = {
|
70
|
+
:saved_template => form_url(node),
|
71
|
+
:klass => klass,
|
72
|
+
:make_form => each_block == form_block,
|
73
|
+
:publish_after_save => publish_after_save,
|
74
|
+
}
|
75
|
+
|
76
|
+
store_block(form_block, cont)
|
77
|
+
else
|
78
|
+
super
|
79
|
+
end
|
80
|
+
|
81
|
+
# out @markup.wrap(expand_with(:node => node.move_to(var, finder[:class]), :in_if => true))
|
82
|
+
|
83
|
+
|
84
|
+
#query = opts[:query]
|
85
|
+
#
|
86
|
+
#
|
87
|
+
#if need_ajax?
|
88
|
+
# new_dom_scope
|
89
|
+
# # ajax, build template. We could merge the following code with 'r_block'.
|
90
|
+
#
|
91
|
+
# # FORM ============
|
92
|
+
# if each_block != form_block
|
93
|
+
# form = expand_block(form_block, :klass => klass, :add=>add_block, :publish_after_save => publish_after_save, :saved_template => true)
|
94
|
+
# else
|
95
|
+
# form = expand_block(form_block, :klass => klass, :add=>add_block, :make_form=>true, :publish_after_save => publish_after_save, :saved_template => true)
|
96
|
+
# end
|
97
|
+
# out helper.save_erb_to_url(form, form_url)
|
98
|
+
#else
|
99
|
+
# # no form, render, edit and add are not ajax
|
100
|
+
# if descendant('add') || descendant('add_document')
|
101
|
+
# out "<% if (#{list_var} = #{list_finder}) || (#{node}.#{node.will_be?(Comment) ? "can_comment?" : "can_write?"} && #{list_var}=[]) -%>"
|
102
|
+
# elsif list_finder != 'nil'
|
103
|
+
# out "<% if #{list_var} = #{list_finder} -%>"
|
104
|
+
# else
|
105
|
+
# out "<% if nil -%>"
|
106
|
+
# end
|
107
|
+
#
|
108
|
+
#
|
109
|
+
# out render_html_tag(expand_with(:list=>list_var, :in_if => false))
|
110
|
+
# out expand_with(:in_if=>true, :only=>['elsif', 'else'], :html_tag => @html_tag, :html_tag_params => @html_tag_params)
|
111
|
+
# out "<% end -%>"
|
112
|
+
#end
|
113
|
+
end
|
4
114
|
|
5
115
|
# Store a context as a sub-template that can be used in ajax calls
|
6
116
|
def r_block
|
117
|
+
# Since we are using ajax, we will need this object to have an ID set.
|
118
|
+
set_dom_prefix
|
7
119
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
120
|
+
if @context[:block] == self
|
121
|
+
# Storing template (called from within store_block)
|
122
|
+
# Set id with the template's node context (<%= @node.zip %>)
|
123
|
+
@markup.set_id(node.dom_id)
|
124
|
+
expand_with
|
125
|
+
else
|
126
|
+
# 1. store template
|
127
|
+
# will wrap with @markup
|
128
|
+
store_block(self)
|
12
129
|
|
130
|
+
# 2. render
|
131
|
+
# Set id with the current node context (<%= var1.zip %>)
|
132
|
+
@markup.set_id(node.dom_id)
|
133
|
+
out expand_with
|
134
|
+
end
|
135
|
+
end
|
13
136
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
markup_bak = block.markup.dup
|
137
|
+
def r_add
|
138
|
+
return parser_error("Should not be called from within 'each'") if parent.method == 'each'
|
139
|
+
return '' if @context[:make_form]
|
18
140
|
|
19
|
-
|
20
|
-
|
141
|
+
if node.will_be?(Comment)
|
142
|
+
out "<% if #{node.up(Node)}.can_comment? -%>"
|
143
|
+
else
|
144
|
+
out "<% if #{node.up(Node)}.can_write? -%>"
|
145
|
+
end
|
21
146
|
|
22
|
-
|
23
|
-
|
24
|
-
|
147
|
+
unless descendant('add_btn')
|
148
|
+
# Add a descendant between self and blocks. ==> add( add_btn(blocks) )
|
149
|
+
blocks = @blocks.dup
|
150
|
+
@blocks = []
|
151
|
+
add_btn = make(:void, :method => 'add_btn', :params => @params.dup, :text => '')
|
152
|
+
add_btn.blocks = blocks
|
153
|
+
remove_instance_variable(:@all_descendants)
|
25
154
|
end
|
26
155
|
|
27
|
-
|
156
|
+
if @context[:form]
|
157
|
+
# ajax add
|
158
|
+
@markup.set_id("#{node.dom_prefix}_add")
|
159
|
+
@markup.append_param(:class, 'btn_add')
|
28
160
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
k.kind_of?(String) && k =~ /\ANode_\w/
|
161
|
+
if @params[:focus]
|
162
|
+
focus = "$(\"#{node.dom_prefix}_#{@params[:focus]}\").focus();"
|
163
|
+
else
|
164
|
+
focus = "$(\"#{node.dom_prefix}_form_t\").focusFirstElement();"
|
34
165
|
end
|
35
|
-
|
36
|
-
|
37
|
-
@
|
38
|
-
|
39
|
-
|
40
|
-
|
166
|
+
|
167
|
+
# Expand 'add' block
|
168
|
+
out @markup.wrap("#{expand_with(:onclick=>"[\"#{node.dom_prefix}_add\", \"#{node.dom_prefix}_form\"].each(Element.toggle);#{focus}return false;")}")
|
169
|
+
|
170
|
+
# New object to render form.
|
171
|
+
# FIXME: use 'klass' param in r_add or r_form instead of current list content.
|
172
|
+
new_node = node.move_to("#{var}_new", [node.klass].flatten.first)
|
173
|
+
|
174
|
+
if new_node.will_be?(Node)
|
175
|
+
# FIXME: BUG if we set <r:form klass='Post'/> the user cannot select class with menu...
|
176
|
+
|
177
|
+
# FIXME: inspect '@context[:form]' to see if it contains v_klass ?
|
178
|
+
out "<% if #{new_node} = secure(Node) { Node.new_from_class('#{new_node.class_name}') } -%>"
|
179
|
+
else
|
180
|
+
out "<% if #{new_node} = #{new_node.class_name}.new -%>"
|
41
181
|
end
|
182
|
+
|
183
|
+
form_block = @context[:form]
|
184
|
+
|
185
|
+
# Expand (inline) 'form' block
|
186
|
+
out expand_block(form_block,
|
187
|
+
# Needed in form to be able to return the result
|
188
|
+
:template_url => template_url(node),
|
189
|
+
# ??
|
190
|
+
:in_add => true,
|
191
|
+
# ??
|
192
|
+
:add => self,
|
193
|
+
# Transform 'each' block into a form
|
194
|
+
:make_form => form_block.method == 'each',
|
195
|
+
# Node context = new node
|
196
|
+
:node => new_node
|
197
|
+
)
|
198
|
+
out "<% end -%>"
|
42
199
|
else
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
new_dom_scope
|
50
|
-
|
51
|
-
unless @context[:make_form]
|
52
|
-
# STORE TEMPLATE ========
|
53
|
-
|
54
|
-
context_bak = @context.dup # avoid side effects when rendering the same block
|
55
|
-
ignore_list = @method == 'block' ? ['form'] : [] # do not show the form in the normal template of a block
|
56
|
-
template = expand_block(self, :block=>self, :list=>false, :saved_template=>true, :ignore => ignore_list)
|
57
|
-
@context = context_bak
|
58
|
-
@result = ''
|
59
|
-
out helper.save_erb_to_url(template, template_url)
|
60
|
-
|
61
|
-
# STORE FORM ============
|
62
|
-
if edit = descendant('edit')
|
63
|
-
publish_after_save = (edit.params[:publish] == 'true')
|
64
|
-
if form = descendant('form')
|
65
|
-
# USE BLOCK FORM ========
|
66
|
-
form_text = expand_block(form, :saved_template=>true, :publish_after_save => publish_after_save)
|
67
|
-
else
|
68
|
-
# MAKE A FORM FROM BLOCK ========
|
69
|
-
form = self.dup
|
70
|
-
form.method = 'form'
|
71
|
-
form_text = expand_block(form, :make_form => true, :list => false, :saved_template => true, :publish_after_save => publish_after_save)
|
72
|
-
end
|
73
|
-
out helper.save_erb_to_url(form_text, form_url)
|
74
|
-
end
|
75
|
-
end
|
200
|
+
# no ajax
|
201
|
+
@markup.append_param(:class, 'btn_add') if @markup.tag
|
202
|
+
out @markup.wrap(expand_with)
|
203
|
+
end
|
204
|
+
out "<% end -%>"
|
205
|
+
end
|
76
206
|
|
77
|
-
|
78
|
-
|
79
|
-
@markup.params.merge!(:id=>erb_dom_id)
|
80
|
-
end
|
207
|
+
def r_add_btn
|
208
|
+
default = node.will_be?(Comment) ? _("btn_add_comment") : _("btn_add")
|
81
209
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
210
|
+
out "<a href='#' onclick='#{@context[:onclick]}'>#{text_for_link(default)}</a>"
|
211
|
+
end
|
212
|
+
|
213
|
+
def r_each
|
214
|
+
if @context[:saved_template]
|
215
|
+
# render to start a saved template
|
216
|
+
options = form_options
|
217
|
+
@markup.set_id(options[:id]) if options[:id]
|
218
|
+
@markup.set_param(:style, options[:style]) if options[:style]
|
219
|
+
|
220
|
+
out @markup.wrap(expand_with)
|
221
|
+
else
|
222
|
+
super
|
86
223
|
end
|
87
224
|
end
|
225
|
+
|
226
|
+
# Return true if we need to insert the dom id for this element. This method is overwritten in Ajax.
|
227
|
+
def need_dom_id?
|
228
|
+
@context[:form]
|
229
|
+
end
|
230
|
+
|
231
|
+
# Set a unique DOM prefix to build unique ids in the page.
|
232
|
+
def set_dom_prefix
|
233
|
+
@name ||= unique_name
|
234
|
+
node.dom_prefix = @name
|
235
|
+
end
|
236
|
+
|
237
|
+
# Unique template_url, ending with dom_id
|
238
|
+
def template_url(node)
|
239
|
+
"#{root.options[:root]}/#{node.dom_prefix}"
|
240
|
+
end
|
241
|
+
|
242
|
+
def form_url(node)
|
243
|
+
template_url(node) + '_form'
|
244
|
+
end
|
245
|
+
|
246
|
+
# Return a different name on each call
|
247
|
+
def unique_name
|
248
|
+
base = @name || @context[:name] || 'list'
|
249
|
+
root.get_unique_name(base, base == @name).gsub(/[^\d\w\/]/,'_')
|
250
|
+
end
|
251
|
+
|
252
|
+
def get_unique_name(key, own_id = false)
|
253
|
+
@next_name_index ||= {}
|
254
|
+
if @next_name_index[key]
|
255
|
+
@next_name_index[key] += 1
|
256
|
+
key + @next_name_index[key].to_s
|
257
|
+
elsif own_id
|
258
|
+
@next_name_index[key] = 0
|
259
|
+
key
|
260
|
+
else
|
261
|
+
@next_name_index[key] = 1
|
262
|
+
key + '1'
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
266
|
+
|
267
|
+
|
268
|
+
private
|
269
|
+
def store_block(block, cont = {})
|
270
|
+
cont = @context.merge(cont)
|
271
|
+
|
272
|
+
# Create new node context
|
273
|
+
node = cont[:node].as_main(ActiveRecord::Base)
|
274
|
+
node.dom_prefix = @name
|
275
|
+
|
276
|
+
cont[:template_url] = template_url(node)
|
277
|
+
cont[:node] = node
|
278
|
+
cont[:block] = block
|
279
|
+
cont[:saved_template] ||= cont[:template_url]
|
280
|
+
@context.each do |k, v|
|
281
|
+
if k.kind_of?(String)
|
282
|
+
cont[k] = nil
|
283
|
+
end
|
284
|
+
end
|
285
|
+
|
286
|
+
template = expand_block(block, cont)
|
287
|
+
|
288
|
+
out helper.save_erb_to_url(template, cont[:saved_template])
|
289
|
+
end
|
290
|
+
|
291
|
+
def need_ajax?(each_block)
|
292
|
+
return false unless each_block
|
293
|
+
# Inline editable
|
294
|
+
each_block.descendant('edit') ||
|
295
|
+
# Ajax add
|
296
|
+
descendant('add') ||
|
297
|
+
# List is reloaded from the 'add_document' popup
|
298
|
+
descendant('add_document') ||
|
299
|
+
# We use 'each' as block to render swap
|
300
|
+
(descendant('swap') && descendant('swap').parent.method != 'block') ||
|
301
|
+
# We use 'each' as block instead of the declared 'block' or 'drop'
|
302
|
+
['block', 'drop'].include?(each_block.single_child_method)
|
303
|
+
end
|
304
|
+
|
305
|
+
#template = expand_block(self, :)
|
306
|
+
#
|
307
|
+
#if @context[:block] == self
|
308
|
+
# # called from self (storing template)
|
309
|
+
# @context.reject! do |k,v|
|
310
|
+
# # FIXME: reject all stored elements in a better way then this
|
311
|
+
# k.kind_of?(String) && k =~ /\ANode_\w/
|
312
|
+
# end
|
313
|
+
# @markup.done = false
|
314
|
+
# @markup.params.merge!(:id=>node.dom_id)
|
315
|
+
# @context[:scope_node] = node if @context[:scope_node]
|
316
|
+
# out expand_with(:node => node)
|
317
|
+
# if @method == 'drop' && !@context[:make_form]
|
318
|
+
# out drop_javascript
|
319
|
+
# end
|
320
|
+
#else
|
321
|
+
# if parent.method == 'each' && @method == parent.single_child_method
|
322
|
+
# # use parent as block
|
323
|
+
# # FIXME: will not work with block as distant target...
|
324
|
+
# # do nothing
|
325
|
+
# else
|
326
|
+
# @markup.tag ||= 'div'
|
327
|
+
# new_dom_scope
|
328
|
+
#
|
329
|
+
# unless @context[:make_form]
|
330
|
+
# # STORE TEMPLATE ========
|
331
|
+
#
|
332
|
+
# context_bak = @context.dup # avoid side effects when rendering the same block
|
333
|
+
# ignore_list = @method == 'block' ? ['form'] : [] # do not show the form in the normal template of a block
|
334
|
+
# template = expand_block(self, :block=>self, :list=>false, :saved_template=>true, :ignore => ignore_list)
|
335
|
+
# @context = context_bak
|
336
|
+
# @result = ''
|
337
|
+
# out helper.save_erb_to_url(template, template_url)
|
338
|
+
#
|
339
|
+
# # STORE FORM ============
|
340
|
+
# if edit = descendant('edit')
|
341
|
+
# publish_after_save = (edit.params[:publish] == 'true')
|
342
|
+
# if form = descendant('form')
|
343
|
+
# # USE BLOCK FORM ========
|
344
|
+
# form_text = expand_block(form, :saved_template=>true, :publish_after_save => publish_after_save)
|
345
|
+
# else
|
346
|
+
# # MAKE A FORM FROM BLOCK ========
|
347
|
+
# form = self.dup
|
348
|
+
# form.method = 'form'
|
349
|
+
# form_text = expand_block(form, :make_form => true, :list => false, :saved_template => true, :publish_after_save => publish_after_save)
|
350
|
+
# end
|
351
|
+
# out helper.save_erb_to_url(form_text, form_url)
|
352
|
+
# end
|
353
|
+
# end
|
354
|
+
#
|
355
|
+
# # RENDER
|
356
|
+
# @markup.done = false
|
357
|
+
# @markup.params.merge!(:id=>node.dom_id)
|
358
|
+
# end
|
359
|
+
#
|
360
|
+
# out expand_with
|
361
|
+
# if @method == 'drop' && !@context[:make_form]
|
362
|
+
# out drop_javascript
|
363
|
+
# end
|
364
|
+
#end
|
365
|
+
|
88
366
|
end
|
89
367
|
end
|
90
368
|
end
|
@@ -2,44 +2,55 @@ module Zafu
|
|
2
2
|
module Process
|
3
3
|
# This module manages conditional rendering (if, else, elsif, case, when).
|
4
4
|
module Conditional
|
5
|
-
def r_if
|
6
|
-
|
5
|
+
def r_if(cond = nil)
|
6
|
+
cond ||= get_attribute_or_eval(false)
|
7
|
+
return parser_error("condition error") unless cond
|
8
|
+
expand_if(cond)
|
7
9
|
end
|
8
10
|
|
9
|
-
def
|
10
|
-
|
11
|
-
# We use 'elsif' just in case there are more then one 'else' clause
|
12
|
-
out "<% elsif true -%>#{expand_with(:in_if => false)}" # do not propagate
|
11
|
+
def r_case
|
12
|
+
r_if('false')
|
13
13
|
end
|
14
14
|
|
15
|
-
def
|
16
|
-
|
15
|
+
def r_else
|
16
|
+
r_elsif('true')
|
17
17
|
end
|
18
18
|
|
19
|
-
|
20
|
-
|
21
|
-
def node(klass = nil)
|
22
|
-
return @context[:node] if !klass
|
23
|
-
@context[:node].get(klass)
|
19
|
+
def r_when
|
20
|
+
r_elsif
|
24
21
|
end
|
25
22
|
|
26
|
-
def
|
27
|
-
|
28
|
-
|
23
|
+
def r_elsif(cond = nil)
|
24
|
+
return '' unless @context[:in_if]
|
25
|
+
cond ||= get_attribute_or_eval(false)
|
26
|
+
return parser_error("condition error") unless cond
|
29
27
|
|
30
|
-
|
31
|
-
# context = @context.dup
|
32
|
-
# context[:node] = context[:node].move_to(name, klass)
|
33
|
-
# end
|
28
|
+
res = expand_with(:in_if => false, :markup => nil)
|
34
29
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
@
|
30
|
+
# We use 'elsif' just in case there are more then one 'else' clause
|
31
|
+
if markup = @context[:markup]
|
32
|
+
@markup.tag ||= markup.tag
|
33
|
+
@markup.steal_html_params_from(@params)
|
34
|
+
markup.params.each do |k, v|
|
35
|
+
next if @markup.param[k]
|
36
|
+
@markup.set_param(k, v)
|
37
|
+
end
|
38
|
+
out "<% elsif #{cond} -%>#{@markup.wrap(res)}" # do not propagate
|
39
39
|
else
|
40
|
-
@
|
40
|
+
@markup.done = true # never wrap else/elsif clause
|
41
|
+
out "<% elsif #{cond} -%>#{res}" # do not propagate
|
41
42
|
end
|
42
43
|
end
|
44
|
+
|
45
|
+
# Expand blocks with conditional enabled (else, elsif, etc).
|
46
|
+
def expand_if(condition, new_node_context = self.node)
|
47
|
+
res = ""
|
48
|
+
res << "<% if #{condition} -%>"
|
49
|
+
res << @markup.wrap(expand_with(:node => new_node_context))
|
50
|
+
res << expand_with(:in_if => true, :only => %w{else elsif when}, :markup => @markup)
|
51
|
+
res << "<% end -%>"
|
52
|
+
res
|
53
|
+
end
|
43
54
|
end # Context
|
44
55
|
end # Process
|
45
56
|
end # Zafu
|