forme 1.11.0 → 2.1.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.
- checksums.yaml +4 -4
- data/CHANGELOG +54 -0
- data/MIT-LICENSE +1 -1
- data/README.rdoc +235 -209
- data/Rakefile +1 -7
- data/lib/forme/bs3.rb +18 -4
- data/lib/forme/erb.rb +13 -25
- data/lib/forme/form.rb +144 -149
- data/lib/forme/input.rb +1 -1
- data/lib/forme/rails.rb +39 -83
- data/lib/forme/raw.rb +2 -2
- data/lib/forme/tag.rb +3 -12
- data/lib/forme/template.rb +110 -0
- data/lib/forme/transformers/formatter.rb +4 -1
- data/lib/forme/transformers/helper.rb +0 -1
- data/lib/forme/transformers/inputs_wrapper.rb +4 -4
- data/lib/forme/version.rb +2 -2
- data/lib/forme.rb +15 -2
- data/lib/roda/plugins/forme.rb +1 -1
- data/lib/roda/plugins/forme_erubi_capture.rb +57 -0
- data/lib/roda/plugins/forme_route_csrf.rb +16 -34
- data/lib/roda/plugins/forme_set.rb +39 -76
- data/lib/sequel/plugins/forme.rb +40 -50
- data/lib/sequel/plugins/forme_i18n.rb +3 -1
- data/lib/sequel/plugins/forme_set.rb +3 -1
- data/spec/all.rb +1 -1
- data/spec/bs3_reference_spec.rb +18 -18
- data/spec/bs3_sequel_plugin_spec.rb +17 -17
- data/spec/bs3_spec.rb +23 -11
- data/spec/erb_helper.rb +69 -58
- data/spec/erubi_capture_helper.rb +198 -0
- data/spec/forme_spec.rb +21 -32
- data/spec/rails_integration_spec.rb +39 -25
- data/spec/roda_integration_spec.rb +118 -70
- data/spec/sequel_helper.rb +0 -1
- data/spec/sequel_i18n_helper.rb +1 -1
- data/spec/sequel_i18n_plugin_spec.rb +3 -2
- data/spec/sequel_plugin_spec.rb +29 -12
- data/spec/sequel_set_plugin_spec.rb +9 -2
- data/spec/shared_erb_specs.rb +71 -0
- data/spec/sinatra_integration_spec.rb +5 -6
- data/spec/spec_helper.rb +21 -8
- metadata +9 -7
- data/lib/forme/erb_form.rb +0 -74
- data/lib/forme/sinatra.rb +0 -17
data/Rakefile
CHANGED
@@ -50,7 +50,7 @@ end
|
|
50
50
|
|
51
51
|
desc "Run specs"
|
52
52
|
task :spec do
|
53
|
-
sh "#{FileUtils::RUBY} spec/all.rb"
|
53
|
+
sh "#{FileUtils::RUBY} #{'-w' if RUBY_VERSION >= '3'} spec/all.rb"
|
54
54
|
end
|
55
55
|
task :default => :spec
|
56
56
|
|
@@ -60,12 +60,6 @@ task :spec_cov do
|
|
60
60
|
sh "#{FileUtils::RUBY} spec/all.rb"
|
61
61
|
end
|
62
62
|
|
63
|
-
desc "Run specs with -w, some warnings filtered"
|
64
|
-
task :spec_w do
|
65
|
-
ENV['WARNING'] = '1'
|
66
|
-
sh "#{FileUtils::RUBY} -w spec/all.rb"
|
67
|
-
end
|
68
|
-
|
69
63
|
### Other
|
70
64
|
|
71
65
|
desc "Print #{NAME} version"
|
data/lib/forme/bs3.rb
CHANGED
@@ -80,12 +80,26 @@ module Forme
|
|
80
80
|
copy_options_to_attributes(ATTRIBUTE_OPTIONS)
|
81
81
|
copy_boolean_options_to_attributes(ATTRIBUTE_BOOLEAN_OPTIONS)
|
82
82
|
handle_key_option
|
83
|
+
handle_errors_option
|
83
84
|
|
84
85
|
Forme.attr_classes(@attr, @opts[:class]) if @opts.has_key?(:class)
|
85
|
-
|
86
|
+
|
87
|
+
if @opts[:error]
|
88
|
+
# Forme.attr_classes(@attr, 'error')
|
89
|
+
@attr["aria-invalid"] = "true"
|
90
|
+
if @opts.fetch(:error_handler, true)
|
91
|
+
unless @opts[:error_id]
|
92
|
+
if id = @attr[:id] || @attr['id']
|
93
|
+
error_id = @attr['aria-describedby'] ||= "#{id}_error_message"
|
94
|
+
@opts[:error_id] = error_id
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
86
99
|
|
87
100
|
if data = opts[:data]
|
88
101
|
data.each do |k, v|
|
102
|
+
k = k.to_s.tr("_", "-") if k.is_a?(Symbol) && input.opts[:dasherize_data]
|
89
103
|
sym = :"data-#{k}"
|
90
104
|
@attr[sym] = v unless @attr.has_key?(sym)
|
91
105
|
end
|
@@ -210,7 +224,7 @@ module Forme
|
|
210
224
|
Forme.attr_classes(attr, 'inputs')
|
211
225
|
if legend = opts[:legend]
|
212
226
|
form.tag(:fieldset, attr) do
|
213
|
-
form.
|
227
|
+
form.tag(:legend, opts[:legend_attr], legend)
|
214
228
|
yield
|
215
229
|
end
|
216
230
|
else
|
@@ -230,11 +244,11 @@ module Forme
|
|
230
244
|
attr = opts[:attr] ? opts[:attr].dup : { :class=>'table table-bordered'}
|
231
245
|
form.tag(:table, attr) do
|
232
246
|
if legend = opts[:legend]
|
233
|
-
form.
|
247
|
+
form.tag(:caption, opts[:legend_attr], legend)
|
234
248
|
end
|
235
249
|
|
236
250
|
if (labels = opts[:labels]) && !labels.empty?
|
237
|
-
form.
|
251
|
+
form.tag(:tr, {}, labels.map{|l| form._tag(:th, {}, l)})
|
238
252
|
end
|
239
253
|
|
240
254
|
yield
|
data/lib/forme/erb.rb
CHANGED
@@ -1,36 +1,24 @@
|
|
1
1
|
# frozen-string-literal: true
|
2
2
|
|
3
|
-
|
3
|
+
require_relative 'template'
|
4
4
|
|
5
5
|
module Forme
|
6
6
|
module ERB
|
7
|
-
|
7
|
+
# This is the module used to add the Forme integration to ERB templates, with optional support for
|
8
|
+
# rack_csrf for CSRF handling.
|
9
|
+
module Helper
|
10
|
+
include Template::Helper
|
8
11
|
|
9
|
-
|
10
|
-
# The block is yielded the Forme::Tag object for the form tag.
|
11
|
-
# The block should return either nil if hidden tag should be added, or a Forme::Tag object (or an array of them),
|
12
|
-
# or a hash with keys specifying the name of the tags and the values specifying the values of the tags .
|
13
|
-
def self.add_hidden_tag(&block)
|
14
|
-
HIDDEN_TAGS << block
|
15
|
-
end
|
12
|
+
private
|
16
13
|
|
17
|
-
|
18
|
-
|
19
|
-
if defined?(::Rack::Csrf) && (form = tag.form) && (env = form.opts[:env]) && env['rack.session'] && (tag.attr[:method] || tag.attr['method']).to_s.upcase == 'POST'
|
20
|
-
{::Rack::Csrf.field=>::Rack::Csrf.token(env)}
|
21
|
-
end
|
22
|
-
end
|
14
|
+
def _forme_form_options(obj, attr, opts)
|
15
|
+
super
|
23
16
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
def form(obj=nil, attr={}, opts={}, &block)
|
30
|
-
h = {:hidden_tags=>Forme::ERB::HIDDEN_TAGS, :env=>env}
|
31
|
-
h[:output] = @_out_buf if block
|
32
|
-
(obj.is_a?(Hash) ? attr = attr.merge(h) : opts = opts.merge(h))
|
33
|
-
Form.form(obj, attr, opts, &block)
|
17
|
+
if defined?(::Rack::Csrf) && env['rack.session']
|
18
|
+
opts[:_before_post] = lambda do |form|
|
19
|
+
form.tag(:input, :type=>:hidden, :name=>::Rack::Csrf.field, :value=>::Rack::Csrf.token(env))
|
20
|
+
end
|
21
|
+
end
|
34
22
|
end
|
35
23
|
end
|
36
24
|
end
|
data/lib/forme/form.rb
CHANGED
@@ -2,9 +2,8 @@
|
|
2
2
|
|
3
3
|
module Forme
|
4
4
|
# The +Form+ class is the main entry point to the library.
|
5
|
-
# Using the +form+, +input+, +tag+, and +inputs+ methods, one can
|
6
|
-
#
|
7
|
-
# to a string using +to_s+.
|
5
|
+
# Using the +form+, +input+, +tag+, and +inputs+ methods, one can return HTML
|
6
|
+
# form tag string (or fragments of an HTML form tag).
|
8
7
|
class Form
|
9
8
|
# A hash of options for the form.
|
10
9
|
attr_reader :opts
|
@@ -13,13 +12,17 @@ module Forme
|
|
13
12
|
# input type keys and values that are hashes of input options.
|
14
13
|
attr_reader :input_defaults
|
15
14
|
|
16
|
-
# The
|
17
|
-
attr_reader :
|
15
|
+
# The attributes used for the form tag for this form.
|
16
|
+
attr_reader :form_tag_attributes
|
18
17
|
|
19
18
|
# The +serializer+ determines how +Tag+ objects are transformed into strings.
|
20
19
|
# Must respond to +call+ or be a registered symbol.
|
21
20
|
attr_reader :serializer
|
22
21
|
|
22
|
+
# The contents of the form as a string. This should not be mutated by
|
23
|
+
# external code.
|
24
|
+
attr_reader :to_s
|
25
|
+
|
23
26
|
# Use appropriate Form subclass for object based on the current class, if the
|
24
27
|
# object responds to +forme_form_class+.
|
25
28
|
def self.new(obj=nil, opts={})
|
@@ -30,23 +33,9 @@ module Forme
|
|
30
33
|
end
|
31
34
|
end
|
32
35
|
|
33
|
-
#
|
34
|
-
#
|
35
|
-
|
36
|
-
#
|
37
|
-
# Argument Handling:
|
38
|
-
# No args :: Creates a +Form+ object with no options and not associated
|
39
|
-
# to an +obj+, and with no attributes in the opening tag.
|
40
|
-
# 1 hash arg :: Treated as opening form tag attributes, creating a
|
41
|
-
# +Form+ object with no options.
|
42
|
-
# 1 non-hash arg :: Treated as the +Form+'s +obj+, with empty options
|
43
|
-
# and no attributes in the opening tag.
|
44
|
-
# 2 hash args :: First hash is opening attributes, second hash is +Form+
|
45
|
-
# options.
|
46
|
-
# 1 non-hash arg, 1-2 hash args :: First argument is +Form+'s obj, second is
|
47
|
-
# opening attributes, third if provided is
|
48
|
-
# +Form+'s options.
|
49
|
-
def self.form(obj=nil, attr={}, opts={}, &block)
|
36
|
+
# Parse the args given to #form and return Form instance, form tag attributes,
|
37
|
+
# and block for form.
|
38
|
+
def self.form_args(obj, attr, opts, &block)
|
50
39
|
f = if obj.is_a?(Hash)
|
51
40
|
raise Error, "Can't provide 3 hash arguments to form" unless opts.empty?
|
52
41
|
opts = attr
|
@@ -60,12 +49,32 @@ module Forme
|
|
60
49
|
button = opts[:button]
|
61
50
|
if ins || button
|
62
51
|
block = proc do |form|
|
63
|
-
form.
|
52
|
+
form.inputs(ins, opts) if ins
|
64
53
|
yield form if block_given?
|
65
|
-
form.
|
54
|
+
form.button(button) if button
|
66
55
|
end
|
67
56
|
end
|
68
57
|
|
58
|
+
[f, attr, block]
|
59
|
+
end
|
60
|
+
|
61
|
+
# Create a +Form+ instance and yield it to the block. Returns an HTML string
|
62
|
+
# for the form tag.
|
63
|
+
#
|
64
|
+
# Argument Handling:
|
65
|
+
# No args :: Creates a +Form+ object with no options and not associated
|
66
|
+
# to an +obj+, and with no attributes in the opening tag.
|
67
|
+
# 1 hash arg :: Treated as opening form tag attributes, creating a
|
68
|
+
# +Form+ object with no options.
|
69
|
+
# 1 non-hash arg :: Treated as the +Form+'s +obj+, with empty options
|
70
|
+
# and no attributes in the opening tag.
|
71
|
+
# 2 hash args :: First hash is opening attributes, second hash is +Form+
|
72
|
+
# options.
|
73
|
+
# 1 non-hash arg, 1-2 hash args :: First argument is +Form+'s obj, second is
|
74
|
+
# opening attributes, third if provided is
|
75
|
+
# +Form+'s options.
|
76
|
+
def self.form(obj=nil, attr={}, opts={}, &block)
|
77
|
+
f, attr, block = form_args(obj, attr, opts, &block)
|
69
78
|
f.form(attr, &block)
|
70
79
|
end
|
71
80
|
|
@@ -97,27 +106,33 @@ module Forme
|
|
97
106
|
|
98
107
|
@serializer = @opts[:serializer]
|
99
108
|
@input_defaults = @opts[:input_defaults] || {}
|
100
|
-
@
|
101
|
-
@nesting = []
|
109
|
+
@to_s = String.new
|
102
110
|
end
|
103
111
|
|
104
|
-
# Create a form tag with the given attributes.
|
105
|
-
|
112
|
+
# Create a form tag with the given attributes. Returns an HTML string for
|
113
|
+
# the generated form tag.
|
114
|
+
def form(attr={})
|
106
115
|
if obj && !attr[:method] && !attr['method'] && obj.respond_to?(:forme_default_request_method)
|
107
|
-
attr = attr
|
116
|
+
attr = Hash[attr]
|
117
|
+
attr['method'] = obj.forme_default_request_method
|
118
|
+
end
|
119
|
+
@form_tag_attributes = attr
|
120
|
+
|
121
|
+
tag(:form, attr) do
|
122
|
+
before_form_yield
|
123
|
+
yield self if block_given?
|
124
|
+
after_form_yield
|
108
125
|
end
|
109
|
-
tag(:form, attr, method(:hidden_form_tags), &block)
|
110
126
|
end
|
111
127
|
|
112
|
-
#
|
113
|
-
#
|
114
|
-
|
115
|
-
|
128
|
+
# Whether the method for this form is POST. Only callable after calling
|
129
|
+
# #form.
|
130
|
+
def post?
|
131
|
+
(form_tag_attributes[:method] || form_tag_attributes['method']).to_s.upcase == 'POST'
|
116
132
|
end
|
117
133
|
|
118
134
|
# Creates an +Input+ with the given +field+ and +opts+ associated with
|
119
|
-
# the receiver
|
120
|
-
# open tag.
|
135
|
+
# the receiver. Returns the HTML generated by the given input.
|
121
136
|
#
|
122
137
|
# If the form is associated with an +obj+, or the :obj key exists in
|
123
138
|
# the +opts+ argument, treats the +field+ as a call to the +obj+. If
|
@@ -129,36 +144,39 @@ module Forme
|
|
129
144
|
# type (e.g. <tt>:text</tt>, <tt>:textarea</tt>, <tt>:select</tt>), and
|
130
145
|
# an input is created directly with the +field+ and +opts+.
|
131
146
|
def input(field, opts={})
|
132
|
-
|
133
|
-
|
134
|
-
obj = opts.delete(:obj)
|
135
|
-
else
|
136
|
-
obj = self.obj
|
137
|
-
end
|
138
|
-
input = if obj
|
139
|
-
if obj.respond_to?(:forme_input)
|
140
|
-
obj.forme_input(self, field, opts.dup)
|
141
|
-
else
|
147
|
+
content_added do
|
148
|
+
if opts.has_key?(:obj)
|
142
149
|
opts = opts.dup
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
+
obj = opts.delete(:obj)
|
151
|
+
else
|
152
|
+
obj = self.obj
|
153
|
+
end
|
154
|
+
|
155
|
+
input = if obj
|
156
|
+
if obj.respond_to?(:forme_input)
|
157
|
+
obj.forme_input(self, field, opts.dup)
|
158
|
+
else
|
159
|
+
opts = opts.dup
|
160
|
+
opts[:key] = field unless opts.has_key?(:key)
|
161
|
+
type = opts.delete(:type) || :text
|
162
|
+
unless opts.has_key?(:value) || type == :file
|
163
|
+
opts[:value] = if obj.is_a?(Hash)
|
164
|
+
obj[field]
|
165
|
+
else
|
166
|
+
obj.send(field)
|
167
|
+
end
|
150
168
|
end
|
169
|
+
_input(type, opts)
|
151
170
|
end
|
152
|
-
|
171
|
+
else
|
172
|
+
_input(field, opts)
|
153
173
|
end
|
154
|
-
|
155
|
-
|
174
|
+
|
175
|
+
self << input
|
156
176
|
end
|
157
|
-
self << input
|
158
|
-
input
|
159
177
|
end
|
160
178
|
|
161
|
-
#
|
179
|
+
# Return a new +Input+ associated with the receiver with the given
|
162
180
|
# arguments, doing no other processing.
|
163
181
|
def _input(*a)
|
164
182
|
Input.new(self, *a)
|
@@ -182,6 +200,8 @@ module Forme
|
|
182
200
|
# wrapper to use for this inputs call. You can use the :nested_inputs_wrapper
|
183
201
|
# option to set the default :inputs_wrapper option for the duration of the block.
|
184
202
|
#
|
203
|
+
# Returns the HTML generated by the inputs added to the form.
|
204
|
+
#
|
185
205
|
# This can also be called with a single hash argument to just use an options hash:
|
186
206
|
#
|
187
207
|
# f.inputs(:legend=>'Foo') do
|
@@ -193,32 +213,28 @@ module Forme
|
|
193
213
|
# f.inputs do
|
194
214
|
# # ...
|
195
215
|
# end
|
196
|
-
def inputs(inputs=[], opts={}
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
def _inputs(inputs=[], opts={}) # :nodoc:
|
203
|
-
if inputs.is_a?(Hash)
|
204
|
-
opts = inputs.merge(opts)
|
205
|
-
inputs = []
|
206
|
-
end
|
216
|
+
def inputs(inputs=[], opts={})
|
217
|
+
content_added do
|
218
|
+
if inputs.is_a?(Hash)
|
219
|
+
opts = inputs.merge(opts)
|
220
|
+
inputs = []
|
221
|
+
end
|
207
222
|
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
223
|
+
form_opts = {}
|
224
|
+
form_opts[:inputs_wrapper] = opts[:nested_inputs_wrapper] if opts[:nested_inputs_wrapper]
|
225
|
+
TRANSFORMER_TYPES.each do |t|
|
226
|
+
if opts.has_key?(t) && t != :inputs_wrapper
|
227
|
+
form_opts[t] = opts[t]
|
228
|
+
end
|
213
229
|
end
|
214
|
-
end
|
215
230
|
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
231
|
+
Forme.transform(:inputs_wrapper, opts, @opts, self, opts) do
|
232
|
+
with_opts(form_opts) do
|
233
|
+
inputs.each do |i|
|
234
|
+
input(*i)
|
235
|
+
end
|
236
|
+
yield if block_given?
|
220
237
|
end
|
221
|
-
yield if block_given?
|
222
238
|
end
|
223
239
|
end
|
224
240
|
end
|
@@ -255,35 +271,34 @@ module Forme
|
|
255
271
|
end
|
256
272
|
|
257
273
|
# Creates a +Tag+ associated to the receiver with the given arguments.
|
258
|
-
#
|
259
|
-
#
|
260
|
-
# the block.
|
274
|
+
# If a block is given, yield to the block inside the generated tag.
|
275
|
+
# Returns the HTML added to the form by the addition of this tag.
|
261
276
|
def tag(*a, &block)
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
277
|
+
content_added do
|
278
|
+
tag = _tag(*a)
|
279
|
+
if block
|
280
|
+
self << serialize_open(tag)
|
281
|
+
if children = tag.children
|
282
|
+
children.each{|child| self << child}
|
283
|
+
end
|
284
|
+
yield self
|
285
|
+
self << serialize_close(tag)
|
286
|
+
else
|
287
|
+
self << tag
|
288
|
+
end
|
289
|
+
end
|
271
290
|
end
|
272
291
|
|
273
|
-
# Creates a :submit +Input+ with the given opts
|
274
|
-
#
|
292
|
+
# Creates a :submit +Input+ with the given opts. Returns the generated
|
293
|
+
# HTML for the input.
|
275
294
|
def button(opts={})
|
276
295
|
opts = {:value=>opts} if opts.is_a?(String)
|
277
|
-
|
278
|
-
self << input
|
279
|
-
input
|
296
|
+
content_added{self << _input(:submit, opts)}
|
280
297
|
end
|
281
298
|
|
282
|
-
# Add the +Input+/+Tag+ instance
|
299
|
+
# Add the +Input+/+Tag+ instance to the HTML buffer.
|
283
300
|
def <<(tag)
|
284
|
-
|
285
|
-
n << tag
|
286
|
-
end
|
301
|
+
@to_s << tag.to_s
|
287
302
|
end
|
288
303
|
|
289
304
|
# Calls the block for each object in objs, using with_obj with the given namespace
|
@@ -296,18 +311,11 @@ module Forme
|
|
296
311
|
end
|
297
312
|
end
|
298
313
|
|
299
|
-
# Return a new string that will not be
|
314
|
+
# Return a new string that will not be HTML escaped by the default serializer.
|
300
315
|
def raw(s)
|
301
316
|
Forme.raw(s)
|
302
317
|
end
|
303
318
|
|
304
|
-
# Marks the string as containing already escaped output. Returns string given
|
305
|
-
# by default, but subclasses for specific web frameworks can handle automatic
|
306
|
-
# html escaping by overriding this.
|
307
|
-
def raw_output(s)
|
308
|
-
s
|
309
|
-
end
|
310
|
-
|
311
319
|
# Temporarily override the given object and namespace for the form. Any given
|
312
320
|
# namespaces are appended to the form's current namespace.
|
313
321
|
def with_obj(obj, namespace=nil)
|
@@ -338,53 +346,40 @@ module Forme
|
|
338
346
|
end
|
339
347
|
end
|
340
348
|
|
341
|
-
# Return
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
hidden_tags.each do |hidden_tag|
|
347
|
-
hidden_tag = hidden_tag.call(form_tag) if hidden_tag.respond_to?(:call)
|
348
|
-
tags.concat(parse_hidden_tags(hidden_tag))
|
349
|
-
end
|
350
|
-
tags
|
351
|
-
end
|
352
|
-
end
|
353
|
-
|
354
|
-
# Handle various types of hidden tags for the form.
|
355
|
-
def parse_hidden_tags(hidden_tag)
|
356
|
-
case hidden_tag
|
357
|
-
when Array
|
358
|
-
hidden_tag
|
359
|
-
when Tag, String
|
360
|
-
[hidden_tag]
|
361
|
-
when Hash
|
362
|
-
hidden_tag.map{|k,v| _tag(:input, :type=>:hidden, :name=>k, :value=>v)}
|
363
|
-
when nil
|
364
|
-
[]
|
365
|
-
else
|
366
|
-
raise Error, "unhandled hidden_tag response: #{hidden_tag.inspect}"
|
367
|
-
end
|
368
|
-
end
|
369
|
-
|
370
|
-
# Make the given tag the currently open tag, and yield. After the
|
371
|
-
# block returns, make the previously open tag the currently open
|
372
|
-
# tag.
|
373
|
-
def nest(tag)
|
374
|
-
@nesting << tag
|
375
|
-
yield self
|
376
|
-
ensure
|
377
|
-
@nesting.pop
|
349
|
+
# Return the HTML content added by the block.
|
350
|
+
def content_added
|
351
|
+
offset = @to_s.length
|
352
|
+
yield
|
353
|
+
@to_s[offset, @to_s.length]
|
378
354
|
end
|
379
355
|
|
380
356
|
# Return a serialized opening tag for the given tag.
|
381
357
|
def serialize_open(tag)
|
382
|
-
|
358
|
+
serializer.serialize_open(tag) if serializer.respond_to?(:serialize_open)
|
383
359
|
end
|
384
360
|
|
385
361
|
# Return a serialized closing tag for the given tag.
|
386
362
|
def serialize_close(tag)
|
387
|
-
|
363
|
+
serializer.serialize_close(tag) if serializer.respond_to?(:serialize_close)
|
364
|
+
end
|
365
|
+
|
366
|
+
# Call before hooks if defined.
|
367
|
+
def before_form_yield
|
368
|
+
# _before_post and _before hooks are only for internal use
|
369
|
+
opts[:_before_post].call(self) if opts[:_before_post] && post?
|
370
|
+
opts[:_before].call(self) if opts[:_before]
|
371
|
+
|
372
|
+
# before hook is for external use
|
373
|
+
opts[:before].call(self) if opts[:before]
|
374
|
+
end
|
375
|
+
|
376
|
+
# Call after hooks if defined.
|
377
|
+
def after_form_yield
|
378
|
+
# after hook is for external use
|
379
|
+
opts[:after].call(self) if opts[:after]
|
380
|
+
|
381
|
+
# _after hook is only for internal use
|
382
|
+
opts[:_after].call(self) if opts[:_after]
|
388
383
|
end
|
389
384
|
end
|
390
385
|
end
|
data/lib/forme/input.rb
CHANGED
@@ -32,7 +32,7 @@ module Forme
|
|
32
32
|
|
33
33
|
# Return a string containing the serialized content of the receiver.
|
34
34
|
def to_s
|
35
|
-
|
35
|
+
Forme.transform(:serializer, @opts, @form_opts, self)
|
36
36
|
end
|
37
37
|
|
38
38
|
# Transform the receiver into a lower level +Tag+ form (or an array
|