forme 2.2.0 → 2.4.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 +16 -0
- data/MIT-LICENSE +1 -1
- data/README.rdoc +8 -3
- data/lib/forme/bs5.rb +213 -0
- data/lib/forme/transformers/formatter.rb +2 -1
- data/lib/forme/transformers/helper.rb +1 -1
- data/lib/forme/version.rb +1 -1
- data/lib/forme.rb +24 -18
- data/lib/roda/plugins/forme_set.rb +17 -3
- data/lib/sequel/plugins/forme.rb +6 -1
- data/lib/sequel/plugins/forme_set.rb +17 -0
- metadata +8 -25
- data/Rakefile +0 -82
- data/spec/all.rb +0 -2
- data/spec/bs3_reference_spec.rb +0 -335
- data/spec/bs3_sequel_plugin_spec.rb +0 -523
- data/spec/bs3_spec.rb +0 -751
- data/spec/erb_helper.rb +0 -198
- data/spec/erubi_capture_helper.rb +0 -198
- data/spec/forme_coverage.rb +0 -14
- data/spec/forme_spec.rb +0 -1292
- data/spec/rails_integration_spec.rb +0 -286
- data/spec/roda_integration_spec.rb +0 -541
- data/spec/sequel_helper.rb +0 -103
- data/spec/sequel_i18n_helper.rb +0 -40
- data/spec/sequel_i18n_plugin_spec.rb +0 -31
- data/spec/sequel_plugin_spec.rb +0 -703
- data/spec/sequel_set_plugin_spec.rb +0 -238
- data/spec/shared_erb_specs.rb +0 -71
- data/spec/sinatra_integration_spec.rb +0 -71
- data/spec/spec_helper.rb +0 -31
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7427b1117f14a93c292826f8d5d25ceacc3d8948d720176a4a5c131b40875284
|
|
4
|
+
data.tar.gz: 8d992d583b50af76e3abf54ca3bcbd385f23bf3434d4d6bd761ee0c82ec75975
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a6fab6a2f89db35fea78cfa851bc6632d8c88d56bc683ebdd5af7f674325f71ab57efa8f327c00150afc5e24cdb7a39b8e4d2a734dafe228bca1794bf5a70514
|
|
7
|
+
data.tar.gz: fb11b777c89ac1ffdf18265ddc563d527cfd531505d23748957b233f87abd3e14ff5a52e43b335969ae41d71502e7bb5dec8fb12280bf3869ffc3159f7b688dc
|
data/CHANGELOG
CHANGED
|
@@ -1,3 +1,19 @@
|
|
|
1
|
+
=== 2.4.0 (2023-04-05)
|
|
2
|
+
|
|
3
|
+
* Support Sequel::Model#forme_use_required_abbr? to control whether to add abbr * tag for required inputs (jeremyevans) (#105)
|
|
4
|
+
|
|
5
|
+
* Make select input with option groups and a :value option correctly set selected attribute on options in all optgroups (v-kolesnikov) (#111, #110)
|
|
6
|
+
|
|
7
|
+
* Make Roda forme_set plugin only include metadata for inputs in the same form, and not inputs on other forms on the same page (jeremyevans) (#109)
|
|
8
|
+
|
|
9
|
+
* Use erb/escape for faster HTML escaping if available (jeremyevans)
|
|
10
|
+
|
|
11
|
+
=== 2.3.0 (2022-11-15)
|
|
12
|
+
|
|
13
|
+
* Add forme/bs5 for Bootstrap 5 support (janko) (#106)
|
|
14
|
+
|
|
15
|
+
* Raise exception if attempting to load Roda forme_set plugin without setting :secret option (janko) (#104)
|
|
16
|
+
|
|
1
17
|
=== 2.2.0 (2022-06-28)
|
|
2
18
|
|
|
3
19
|
* Use inputmode and pattern attributes instead of type=number for integer fields in the Sequel forme plugin (jeremyevans)
|
data/MIT-LICENSE
CHANGED
data/README.rdoc
CHANGED
|
@@ -53,7 +53,7 @@ This results in the following HTML:
|
|
|
53
53
|
</label>
|
|
54
54
|
</form>
|
|
55
55
|
|
|
56
|
-
In addition to integrating with Sequel,
|
|
56
|
+
In addition to integrating with Sequel, Forme also integrates into
|
|
57
57
|
three separate web frameworks, Roda, Rails, and Sinatra, allowing
|
|
58
58
|
use of forms inside templates. This is the most common usage of Forme.
|
|
59
59
|
|
|
@@ -1264,12 +1264,17 @@ You can mark a configuration as the default using:
|
|
|
1264
1264
|
|
|
1265
1265
|
Forme.default_config = :mine
|
|
1266
1266
|
|
|
1267
|
-
=== Bootstrap
|
|
1267
|
+
=== Bootstrap Support
|
|
1268
1268
|
|
|
1269
|
-
Forme ships with support for Bootstrap
|
|
1269
|
+
Forme ships with support for Bootstrap 5 HTML formatting. This support is shipped in
|
|
1270
1270
|
it's own file, so if you don't use it, you don't pay the memory penalty for loading
|
|
1271
1271
|
it.
|
|
1272
1272
|
|
|
1273
|
+
require 'forme/bs5'
|
|
1274
|
+
Forme.default_config = :bs5
|
|
1275
|
+
|
|
1276
|
+
There is also support for Bootstrap versions 3-4:
|
|
1277
|
+
|
|
1273
1278
|
require 'forme/bs3'
|
|
1274
1279
|
Forme.default_config = :bs3
|
|
1275
1280
|
|
data/lib/forme/bs5.rb
ADDED
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
# frozen-string-literal: true
|
|
2
|
+
|
|
3
|
+
module Forme
|
|
4
|
+
register_config(:bs5, formatter: :bs5, wrapper: :bs5, error_handler: :bs5, serializer: :bs5, labeler: :bs5, helper: :bs5, tag_wrapper: :bs5, set_wrapper: :div)
|
|
5
|
+
|
|
6
|
+
# Update the <tt>:class</tt> entry in the +attr+ hash with the given +classes+,
|
|
7
|
+
# adding the classes before any existing classes.
|
|
8
|
+
def self.attr_classes_after(attr, *classes)
|
|
9
|
+
attr[:class] = merge_classes(*classes, attr[:class])
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
class ErrorHandler::Bootstrap5
|
|
13
|
+
Forme.register_transformer(:error_handler, :bs5, new)
|
|
14
|
+
|
|
15
|
+
def call(tags, input)
|
|
16
|
+
attr = input.opts[:error_attr]
|
|
17
|
+
attr = attr ? attr.dup : {}
|
|
18
|
+
|
|
19
|
+
unless attr[:class] && attr[:class].include?("invalid-tooltip")
|
|
20
|
+
Forme.attr_classes(attr, "invalid-feedback")
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
attr[:id] ||= input.opts[:error_id]
|
|
24
|
+
|
|
25
|
+
[tags, input.tag(:div, attr, input.opts[:error])]
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
class Formatter::Bootstrap5 < Formatter
|
|
30
|
+
Forme.register_transformer(:formatter, :bs5, self)
|
|
31
|
+
|
|
32
|
+
private
|
|
33
|
+
|
|
34
|
+
def normalize_options
|
|
35
|
+
super
|
|
36
|
+
|
|
37
|
+
if @opts[:error]
|
|
38
|
+
# remove "error" class
|
|
39
|
+
@attr[:class] = @attr[:class].to_s.sub(/\s*error$/,'')
|
|
40
|
+
@attr.delete(:class) if @attr[:class].to_s == ''
|
|
41
|
+
|
|
42
|
+
Forme.attr_classes(@attr, "is-invalid")
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
if @opts[:help]
|
|
46
|
+
if @opts[:helper_attr] && @opts[:helper_attr][:id]
|
|
47
|
+
@attr["aria-describedby"] ||= @opts[:helper_attr][:id]
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Formatter that adds "readonly" for most input types,
|
|
54
|
+
# and disables select/radio/checkbox inputs.
|
|
55
|
+
#
|
|
56
|
+
# Registered as :bs5_readonly.
|
|
57
|
+
class Formatter::Bs5ReadOnly < Formatter
|
|
58
|
+
Forme.register_transformer(:formatter, :bs5_readonly, self)
|
|
59
|
+
|
|
60
|
+
private
|
|
61
|
+
|
|
62
|
+
# Disabled checkbox inputs.
|
|
63
|
+
def format_checkbox
|
|
64
|
+
@attr[:disabled] = :disabled
|
|
65
|
+
super
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# Use a span with text instead of an input field.
|
|
69
|
+
def _format_input(type)
|
|
70
|
+
@attr[:readonly] = :readonly
|
|
71
|
+
super
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# Disabled radio button inputs.
|
|
75
|
+
def format_radio
|
|
76
|
+
@attr[:disabled] = :disabled
|
|
77
|
+
super
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# Use a span with text of the selected values instead of a select box.
|
|
81
|
+
def format_select
|
|
82
|
+
@attr[:disabled] = :disabled
|
|
83
|
+
super
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# Use a span with text instead of a text area.
|
|
87
|
+
def format_textarea
|
|
88
|
+
@attr[:readonly] = :readonly
|
|
89
|
+
super
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# Use a <table class="table"> tag to wrap the inputs.
|
|
94
|
+
#
|
|
95
|
+
# Registered as :bs5_table.
|
|
96
|
+
class InputsWrapper::Bs5Table
|
|
97
|
+
Forme.register_transformer(:inputs_wrapper, :bs5_table, new)
|
|
98
|
+
|
|
99
|
+
# Wrap the inputs in a <table> tag.
|
|
100
|
+
def call(form, opts, &block)
|
|
101
|
+
attr = opts[:attr] ? opts[:attr].dup : { :class=>'table table-bordered'}
|
|
102
|
+
form.tag(:table, attr) do
|
|
103
|
+
if legend = opts[:legend]
|
|
104
|
+
form.tag(:caption, opts[:legend_attr], legend)
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
if (labels = opts[:labels]) && !labels.empty?
|
|
108
|
+
form.tag(:tr, {}, labels.map{|l| form._tag(:th, {}, l)})
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
yield
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
class Labeler::Bootstrap5 < Labeler::Explicit
|
|
117
|
+
Forme.register_transformer(:labeler, :bs5, new)
|
|
118
|
+
|
|
119
|
+
def call(tag, input)
|
|
120
|
+
floating_label = (input.opts[:wrapper_attr] || {})[:class].to_s.include?("form-floating")
|
|
121
|
+
input.opts[:label_position] ||= :after if floating_label
|
|
122
|
+
|
|
123
|
+
tags = super
|
|
124
|
+
return tags if floating_label
|
|
125
|
+
|
|
126
|
+
attr = tags.find { |tag| tag.is_a?(Tag) && tag.type == :label }.attr
|
|
127
|
+
|
|
128
|
+
label_class = case input.type
|
|
129
|
+
when :radio, :checkbox
|
|
130
|
+
"form-check-label"
|
|
131
|
+
else
|
|
132
|
+
"form-label"
|
|
133
|
+
end
|
|
134
|
+
Forme.attr_classes_after(attr, label_class)
|
|
135
|
+
|
|
136
|
+
tags
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
class Helper::Bootstrap5
|
|
141
|
+
Forme.register_transformer(:helper, :bs5, new)
|
|
142
|
+
|
|
143
|
+
def call(tag, input)
|
|
144
|
+
attr = input.opts[:helper_attr]
|
|
145
|
+
attr = attr ? attr.dup : {}
|
|
146
|
+
Forme.attr_classes(attr, 'form-text')
|
|
147
|
+
[tag, input.tag(:div, attr, input.opts[:help])]
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
class Wrapper::Bootstrap5 < Wrapper
|
|
152
|
+
Forme.register_transformer(:wrapper, :bs5, new)
|
|
153
|
+
|
|
154
|
+
def call(tag, input)
|
|
155
|
+
attr = input.opts[:wrapper_attr] ? input.opts[:wrapper_attr].dup : { }
|
|
156
|
+
|
|
157
|
+
case input.type
|
|
158
|
+
when :submit, :reset, :hidden
|
|
159
|
+
super
|
|
160
|
+
when :radio, :checkbox
|
|
161
|
+
Forme.attr_classes_after(attr, "form-check")
|
|
162
|
+
input.tag(:div, attr, super)
|
|
163
|
+
else
|
|
164
|
+
input.tag(:div, attr, super)
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
class Serializer::Bootstrap5 < Serializer
|
|
170
|
+
Forme.register_transformer(:serializer, :bs5, new)
|
|
171
|
+
|
|
172
|
+
BUTTON_STYLES = %w[
|
|
173
|
+
btn-primary btn-secondary btn-success btn-danger btn-warning btn-info btn-light btn-dark btn-link
|
|
174
|
+
btn-outline-primary btn-outline-secondary btn-outline-success btn-outline-danger btn-outline-warning btn-outline-info btn-outline-light btn-outline-dark
|
|
175
|
+
].freeze
|
|
176
|
+
|
|
177
|
+
def call(tag)
|
|
178
|
+
return super unless tag.is_a?(Tag)
|
|
179
|
+
|
|
180
|
+
attr_class = case tag.type
|
|
181
|
+
when :input
|
|
182
|
+
# default to <input type="text"...> if not set
|
|
183
|
+
tag.attr[:type] = :text if tag.attr[:type].nil?
|
|
184
|
+
|
|
185
|
+
case tag.attr[:type].to_sym
|
|
186
|
+
when :checkbox, :radio
|
|
187
|
+
"form-check-input"
|
|
188
|
+
when :range
|
|
189
|
+
"form-range"
|
|
190
|
+
when :color
|
|
191
|
+
%w"form-control form-control-color"
|
|
192
|
+
when :submit, :reset
|
|
193
|
+
classes = ["btn"]
|
|
194
|
+
classes << "btn-primary" if (tag.attr[:class].to_s.split(" ") & BUTTON_STYLES).empty?
|
|
195
|
+
classes
|
|
196
|
+
when :hidden
|
|
197
|
+
# nothing
|
|
198
|
+
else
|
|
199
|
+
unless tag.attr[:class] && tag.attr[:class].include?("form-control-plaintext")
|
|
200
|
+
"form-control"
|
|
201
|
+
end
|
|
202
|
+
end
|
|
203
|
+
when :textarea
|
|
204
|
+
"form-control"
|
|
205
|
+
when :select
|
|
206
|
+
"form-select"
|
|
207
|
+
end
|
|
208
|
+
Forme.attr_classes_after(tag.attr, *attr_class) if attr_class
|
|
209
|
+
|
|
210
|
+
super
|
|
211
|
+
end
|
|
212
|
+
end
|
|
213
|
+
end
|
|
@@ -417,6 +417,7 @@ module Forme
|
|
|
417
417
|
return unless @opts[:options]
|
|
418
418
|
process_select_options(@opts[:options], &block)
|
|
419
419
|
end
|
|
420
|
+
@attr.delete(:value)
|
|
420
421
|
|
|
421
422
|
if prompt = @opts[:add_blank]
|
|
422
423
|
unless prompt.is_a?(String)
|
|
@@ -434,7 +435,7 @@ module Forme
|
|
|
434
435
|
def process_select_options(os)
|
|
435
436
|
vm = @opts[:value_method]
|
|
436
437
|
tm = @opts[:text_method]
|
|
437
|
-
sel = @opts[:selected] || @attr
|
|
438
|
+
sel = @opts[:selected] || @attr[:value]
|
|
438
439
|
|
|
439
440
|
if @opts[:multiple]
|
|
440
441
|
sel = Array(sel)
|
|
@@ -7,7 +7,7 @@ module Forme
|
|
|
7
7
|
class Helper
|
|
8
8
|
Forme.register_transformer(:helper, :default, new)
|
|
9
9
|
|
|
10
|
-
# Return tag with
|
|
10
|
+
# Return tag with help message span tag after it.
|
|
11
11
|
def call(tag, input)
|
|
12
12
|
attr = input.opts[:helper_attr]
|
|
13
13
|
attr = attr ? attr.dup : {}
|
data/lib/forme/version.rb
CHANGED
data/lib/forme.rb
CHANGED
|
@@ -9,27 +9,32 @@ module Forme
|
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
begin
|
|
12
|
-
require '
|
|
12
|
+
require 'erb/escape'
|
|
13
|
+
define_singleton_method(:h, ERB::Escape.instance_method(:html_escape))
|
|
13
14
|
# :nocov:
|
|
14
|
-
unless CGI.respond_to?(:escapeHTML) # work around for JRuby 9.1
|
|
15
|
-
CGI = Object.new
|
|
16
|
-
CGI.extend(defined?(::CGI::Escape) ? ::CGI::Escape : ::CGI::Util)
|
|
17
|
-
end
|
|
18
|
-
def self.h(value)
|
|
19
|
-
CGI.escapeHTML(value.to_s)
|
|
20
|
-
end
|
|
21
15
|
rescue LoadError
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
def self.h(value)
|
|
28
|
-
value.to_s.gsub(/[&<>"']/, ESCAPE_TABLE)
|
|
16
|
+
begin
|
|
17
|
+
require 'cgi/escape'
|
|
18
|
+
unless CGI.respond_to?(:escapeHTML) # work around for JRuby 9.1
|
|
19
|
+
CGI = Object.new
|
|
20
|
+
CGI.extend(defined?(::CGI::Escape) ? ::CGI::Escape : ::CGI::Util)
|
|
29
21
|
end
|
|
30
|
-
else
|
|
31
22
|
def self.h(value)
|
|
32
|
-
value.to_s
|
|
23
|
+
CGI.escapeHTML(value.to_s)
|
|
24
|
+
end
|
|
25
|
+
rescue LoadError
|
|
26
|
+
ESCAPE_TABLE = {'&' => '&', '<' => '<', '>' => '>', '"' => '"', "'" => '''}.freeze
|
|
27
|
+
ESCAPE_TABLE.each_value(&:freeze)
|
|
28
|
+
if RUBY_VERSION >= '1.9'
|
|
29
|
+
# Escape the following characters with their HTML/XML
|
|
30
|
+
# equivalents.
|
|
31
|
+
def self.h(value)
|
|
32
|
+
value.to_s.gsub(/[&<>"']/, ESCAPE_TABLE)
|
|
33
|
+
end
|
|
34
|
+
else
|
|
35
|
+
def self.h(value)
|
|
36
|
+
value.to_s.gsub(/[&<>"']/){|s| ESCAPE_TABLE[s]}
|
|
37
|
+
end
|
|
33
38
|
end
|
|
34
39
|
end
|
|
35
40
|
end
|
|
@@ -96,7 +101,8 @@ module Forme
|
|
|
96
101
|
Form.form(*a, &block)
|
|
97
102
|
end
|
|
98
103
|
|
|
99
|
-
# Update the <tt>:class</tt> entry in the +attr+ hash with the given +classes
|
|
104
|
+
# Update the <tt>:class</tt> entry in the +attr+ hash with the given +classes+,
|
|
105
|
+
# adding the classes after any existing classes.
|
|
100
106
|
def self.attr_classes(attr, *classes)
|
|
101
107
|
attr[:class] = merge_classes(attr[:class], *classes)
|
|
102
108
|
end
|
|
@@ -13,7 +13,9 @@ class Roda
|
|
|
13
13
|
|
|
14
14
|
# Set the HMAC secret.
|
|
15
15
|
def self.configure(app, opts = OPTS, &block)
|
|
16
|
-
app.opts[:forme_set_hmac_secret] = opts[:secret] || app.opts[:forme_set_hmac_secret]
|
|
16
|
+
unless app.opts[:forme_set_hmac_secret] = opts[:secret] || app.opts[:forme_set_hmac_secret]
|
|
17
|
+
raise RodaError, "must provide :secret option to forme_set plugin"
|
|
18
|
+
end
|
|
17
19
|
|
|
18
20
|
if block
|
|
19
21
|
app.send(:define_method, :_forme_set_handle_error, &block)
|
|
@@ -27,14 +29,26 @@ class Roda
|
|
|
27
29
|
|
|
28
30
|
# Map of error types to error messages
|
|
29
31
|
ERROR_MESSAGES = {
|
|
30
|
-
:missing_data=>"_forme_set_data parameter not submitted",
|
|
31
|
-
:missing_hmac=>"_forme_set_data_hmac parameter not submitted",
|
|
32
|
+
:missing_data=>"_forme_set_data parameter not submitted, make sure the forme_set Sequel plugin is loaded",
|
|
33
|
+
:missing_hmac=>"_forme_set_data_hmac parameter not submitted, make sure the forme_set Sequel plugin is loaded",
|
|
32
34
|
:hmac_mismatch=>"_forme_set_data_hmac does not match _forme_set_data",
|
|
33
35
|
:csrf_mismatch=>"_forme_set_data CSRF token does not match submitted CSRF token",
|
|
34
36
|
:missing_namespace=>"no content in expected namespace"
|
|
35
37
|
}.freeze
|
|
36
38
|
|
|
37
39
|
module InstanceMethods
|
|
40
|
+
# If a Sequel::Model object that supports forme_set is passed,
|
|
41
|
+
# isolate the inputs so that each form only includes metadata
|
|
42
|
+
# for inputs on the form, and not inputs for earlier forms on
|
|
43
|
+
# the same page.
|
|
44
|
+
def form(obj=nil, attr={}, opts={}, &block)
|
|
45
|
+
if obj.is_a?(Sequel::Plugins::FormeSet::InstanceMethods)
|
|
46
|
+
obj.isolate_forme_inputs{super}
|
|
47
|
+
else
|
|
48
|
+
super
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
38
52
|
# Return hash based on submitted parameters, with :values key
|
|
39
53
|
# being submitted values for the object, and :validations key
|
|
40
54
|
# being a hash of validation metadata for the object.
|
data/lib/sequel/plugins/forme.rb
CHANGED
|
@@ -207,7 +207,7 @@ module Sequel # :nodoc:
|
|
|
207
207
|
# is required.
|
|
208
208
|
def handle_label(f)
|
|
209
209
|
opts[:label] = humanize(field) unless opts.has_key?(:label)
|
|
210
|
-
opts[:label] = [opts[:label], form._tag(:abbr, {:title=>'required'}, '*')] if opts[:label] && opts[:required]
|
|
210
|
+
opts[:label] = [opts[:label], form._tag(:abbr, {:title=>'required'}, '*')] if opts[:label] && opts[:required] && obj.forme_use_required_abbr?
|
|
211
211
|
end
|
|
212
212
|
|
|
213
213
|
# Update the attributes and options for any recognized validations
|
|
@@ -492,6 +492,11 @@ module Sequel # :nodoc:
|
|
|
492
492
|
'post'
|
|
493
493
|
end
|
|
494
494
|
|
|
495
|
+
# Whether to set an abbr tag in labels for required inputs.
|
|
496
|
+
def forme_use_required_abbr?
|
|
497
|
+
true
|
|
498
|
+
end
|
|
499
|
+
|
|
495
500
|
# Use the underscored model name as the default namespace.
|
|
496
501
|
def forme_namespace
|
|
497
502
|
model.send(:underscore, model.name)
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# frozen-string-literal: true
|
|
2
2
|
|
|
3
|
+
require_relative '../../forme'
|
|
4
|
+
|
|
3
5
|
module Sequel # :nodoc:
|
|
4
6
|
module Plugins # :nodoc:
|
|
5
7
|
# The forme_set plugin makes the model instance keep track of which form
|
|
@@ -22,6 +24,21 @@ module Sequel # :nodoc:
|
|
|
22
24
|
@forme_inputs ||= {}
|
|
23
25
|
end
|
|
24
26
|
|
|
27
|
+
# Temporarily reset forme_inputs to the empty hash before yielding to the block.
|
|
28
|
+
# Used by the Roda forme_set plugin to make sure each form only includes metadata
|
|
29
|
+
# for inputs in that form, and not metadata for inputs for earlier forms on the same page.
|
|
30
|
+
def isolate_forme_inputs
|
|
31
|
+
return yield if frozen?
|
|
32
|
+
|
|
33
|
+
forme_inputs = self.forme_inputs
|
|
34
|
+
begin
|
|
35
|
+
@forme_inputs = {}
|
|
36
|
+
yield
|
|
37
|
+
ensure
|
|
38
|
+
@forme_inputs = forme_inputs.merge(@forme_inputs)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
25
42
|
# Hash with column name symbol keys and <tt>[subset, allowed_values]</tt> values. +subset+
|
|
26
43
|
# is a boolean flag, if true, the uploaded values should be a subset of the allowed values,
|
|
27
44
|
# otherwise, there should be a single uploaded value that is a member of the allowed values.
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: forme
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.
|
|
4
|
+
version: 2.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Jeremy Evans
|
|
8
|
-
autorequire:
|
|
8
|
+
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2023-04-05 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: minitest
|
|
@@ -157,6 +157,7 @@ description: |
|
|
|
157
157
|
2) Have a simple API
|
|
158
158
|
3) Support forms both with and without related objects
|
|
159
159
|
4) Allow compiling down to different types of output
|
|
160
|
+
5) Integrate easily into web frameworks
|
|
160
161
|
email: code@jeremyevans.net
|
|
161
162
|
executables: []
|
|
162
163
|
extensions: []
|
|
@@ -168,9 +169,9 @@ files:
|
|
|
168
169
|
- CHANGELOG
|
|
169
170
|
- MIT-LICENSE
|
|
170
171
|
- README.rdoc
|
|
171
|
-
- Rakefile
|
|
172
172
|
- lib/forme.rb
|
|
173
173
|
- lib/forme/bs3.rb
|
|
174
|
+
- lib/forme/bs5.rb
|
|
174
175
|
- lib/forme/erb.rb
|
|
175
176
|
- lib/forme/form.rb
|
|
176
177
|
- lib/forme/input.rb
|
|
@@ -193,24 +194,6 @@ files:
|
|
|
193
194
|
- lib/sequel/plugins/forme.rb
|
|
194
195
|
- lib/sequel/plugins/forme_i18n.rb
|
|
195
196
|
- lib/sequel/plugins/forme_set.rb
|
|
196
|
-
- spec/all.rb
|
|
197
|
-
- spec/bs3_reference_spec.rb
|
|
198
|
-
- spec/bs3_sequel_plugin_spec.rb
|
|
199
|
-
- spec/bs3_spec.rb
|
|
200
|
-
- spec/erb_helper.rb
|
|
201
|
-
- spec/erubi_capture_helper.rb
|
|
202
|
-
- spec/forme_coverage.rb
|
|
203
|
-
- spec/forme_spec.rb
|
|
204
|
-
- spec/rails_integration_spec.rb
|
|
205
|
-
- spec/roda_integration_spec.rb
|
|
206
|
-
- spec/sequel_helper.rb
|
|
207
|
-
- spec/sequel_i18n_helper.rb
|
|
208
|
-
- spec/sequel_i18n_plugin_spec.rb
|
|
209
|
-
- spec/sequel_plugin_spec.rb
|
|
210
|
-
- spec/sequel_set_plugin_spec.rb
|
|
211
|
-
- spec/shared_erb_specs.rb
|
|
212
|
-
- spec/sinatra_integration_spec.rb
|
|
213
|
-
- spec/spec_helper.rb
|
|
214
197
|
homepage: http://github.com/jeremyevans/forme
|
|
215
198
|
licenses:
|
|
216
199
|
- MIT
|
|
@@ -220,7 +203,7 @@ metadata:
|
|
|
220
203
|
documentation_uri: http://forme.jeremyevans.net
|
|
221
204
|
mailing_list_uri: https://github.com/jeremyevans/forme/discussions
|
|
222
205
|
source_code_uri: https://github.com/jeremyevans/forme
|
|
223
|
-
post_install_message:
|
|
206
|
+
post_install_message:
|
|
224
207
|
rdoc_options:
|
|
225
208
|
- "--quiet"
|
|
226
209
|
- "--line-numbers"
|
|
@@ -242,8 +225,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
242
225
|
- !ruby/object:Gem::Version
|
|
243
226
|
version: '0'
|
|
244
227
|
requirements: []
|
|
245
|
-
rubygems_version: 3.
|
|
246
|
-
signing_key:
|
|
228
|
+
rubygems_version: 3.4.10
|
|
229
|
+
signing_key:
|
|
247
230
|
specification_version: 4
|
|
248
231
|
summary: HTML forms library
|
|
249
232
|
test_files: []
|
data/Rakefile
DELETED
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
require "rake"
|
|
2
|
-
require "rake/clean"
|
|
3
|
-
|
|
4
|
-
NAME = 'forme'
|
|
5
|
-
VERS = lambda do
|
|
6
|
-
require File.expand_path("../lib/forme/version", __FILE__)
|
|
7
|
-
Forme.version
|
|
8
|
-
end
|
|
9
|
-
CLEAN.include ["#{NAME}-*.gem", "rdoc", "coverage", '**/*.rbc']
|
|
10
|
-
|
|
11
|
-
# Gem Packaging and Release
|
|
12
|
-
|
|
13
|
-
desc "Packages #{NAME}"
|
|
14
|
-
task :package=>[:clean] do |p|
|
|
15
|
-
sh %{gem build #{NAME}.gemspec}
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
desc "Upload #{NAME} gem to rubygems"
|
|
19
|
-
task :release=>[:package] do
|
|
20
|
-
sh %{gem push ./#{NAME}-#{VERS.call}.gem}
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
### RDoc
|
|
24
|
-
|
|
25
|
-
RDOC_DEFAULT_OPTS = ["--line-numbers", "--inline-source", '--title', 'Forme']
|
|
26
|
-
|
|
27
|
-
begin
|
|
28
|
-
gem 'hanna-nouveau'
|
|
29
|
-
RDOC_DEFAULT_OPTS.concat(['-f', 'hanna'])
|
|
30
|
-
rescue Gem::LoadError
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
rdoc_task_class = begin
|
|
34
|
-
require "rdoc/task"
|
|
35
|
-
RDoc::Task
|
|
36
|
-
rescue LoadError
|
|
37
|
-
require "rake/rdoctask"
|
|
38
|
-
Rake::RDocTask
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
RDOC_OPTS = RDOC_DEFAULT_OPTS + ['--main', 'README.rdoc']
|
|
42
|
-
|
|
43
|
-
rdoc_task_class.new do |rdoc|
|
|
44
|
-
rdoc.rdoc_dir = "rdoc"
|
|
45
|
-
rdoc.options += RDOC_OPTS
|
|
46
|
-
rdoc.rdoc_files.add %w"README.rdoc CHANGELOG MIT-LICENSE lib/**/*.rb"
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
### Specs
|
|
50
|
-
|
|
51
|
-
desc "Run specs"
|
|
52
|
-
task :spec do
|
|
53
|
-
sh "#{FileUtils::RUBY} #{'-w' if RUBY_VERSION >= '3'} spec/all.rb"
|
|
54
|
-
end
|
|
55
|
-
task :default => :spec
|
|
56
|
-
|
|
57
|
-
desc "Run specs with coverage"
|
|
58
|
-
task :spec_cov do
|
|
59
|
-
ENV['COVERAGE'] = '1'
|
|
60
|
-
sh "#{FileUtils::RUBY} spec/all.rb"
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
### Other
|
|
64
|
-
|
|
65
|
-
desc "Print #{NAME} version"
|
|
66
|
-
task :version do
|
|
67
|
-
puts VERS.call
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
desc "Check syntax of all .rb files"
|
|
71
|
-
task :check_syntax do
|
|
72
|
-
Dir['**/*.rb'].each{|file| print `#{ENV['RUBY'] || :ruby} -c #{file} | fgrep -v "Syntax OK"`}
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
desc "Start an IRB shell using the extension"
|
|
76
|
-
task :irb do
|
|
77
|
-
require 'rbconfig'
|
|
78
|
-
ruby = ENV['RUBY'] || File.join(RbConfig::CONFIG['bindir'], RbConfig::CONFIG['ruby_install_name'])
|
|
79
|
-
irb = ENV['IRB'] || File.join(RbConfig::CONFIG['bindir'], File.basename(ruby).sub('ruby', 'irb'))
|
|
80
|
-
sh %{#{irb} -I lib -r forme}
|
|
81
|
-
end
|
|
82
|
-
|
data/spec/all.rb
DELETED