sinatra-formkeeper 0.0.4 → 0.0.5
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/Gemfile +1 -1
- data/README.md +309 -237
- data/lib/sinatra/formkeeper/version.rb +1 -1
- metadata +1 -1
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -20,47 +20,58 @@ Or install it yourself as:
|
|
20
20
|
|
21
21
|
### Synopsis
|
22
22
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
23
|
+
```ruby
|
24
|
+
require 'sinatra/formkeeper'
|
25
|
+
|
26
|
+
get '/sign_up' do
|
27
|
+
form do
|
28
|
+
filters :strip, :my_filter
|
29
|
+
field :username, :present => true, :length => 4..8
|
30
|
+
field :age, :present => true, :int => { :gte => 18 }
|
31
|
+
field :password01, :present => true, :length => 4..8
|
32
|
+
field :password02, :present => true, :length => 4..8
|
33
|
+
same :same_password, [:password01, :password02]
|
34
|
+
end
|
35
|
+
if form.failed?
|
36
|
+
"signup failed"
|
37
|
+
else
|
38
|
+
"singup success " + form[:username]
|
39
|
+
end
|
40
|
+
end
|
41
|
+
```
|
37
42
|
|
38
43
|
### 0: Preparation
|
39
44
|
|
40
45
|
At your application file's header, add 'require' line for this library.
|
41
46
|
|
42
|
-
|
47
|
+
```ruby
|
48
|
+
require 'sinatra/formkeeper'
|
49
|
+
```
|
43
50
|
|
44
51
|
And if your application is Sinatra::Base inheritance type, register Sinatra::FormKeeper
|
45
52
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
53
|
+
```ruby
|
54
|
+
class MyApp < Sinatra::Base
|
55
|
+
register Sinatra::FormKeeper
|
56
|
+
#...
|
57
|
+
end
|
58
|
+
```
|
50
59
|
|
51
60
|
### 1: Building rules
|
52
61
|
|
53
62
|
In your routing block, you should build a form-rule at first,
|
54
63
|
like following
|
55
64
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
65
|
+
```ruby
|
66
|
+
post '/entry' do
|
67
|
+
form do
|
68
|
+
filters :strip
|
69
|
+
field :title, :present => true, :length => 4..20
|
70
|
+
field :message, :present => true, :length => 0..200
|
71
|
+
end
|
72
|
+
#...
|
73
|
+
end
|
74
|
+
```
|
64
75
|
|
65
76
|
Calling 'form' with block which includes rule-setting,
|
66
77
|
you can build a form-rule.
|
@@ -71,17 +82,21 @@ There are some DSL-method to build rules. In this example, 'filters' and 'field'
|
|
71
82
|
You can set 'filters'. All input parameters are filtered by indicated filtering feature
|
72
83
|
The filtering process is executed before validation.
|
73
84
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
85
|
+
```ruby
|
86
|
+
form do
|
87
|
+
filters :strip
|
88
|
+
#...
|
89
|
+
end
|
90
|
+
```
|
78
91
|
|
79
92
|
You can set multiple filters at once
|
80
93
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
94
|
+
```ruby
|
95
|
+
form do
|
96
|
+
filters :strip, :downcase
|
97
|
+
#...
|
98
|
+
end
|
99
|
+
```
|
85
100
|
|
86
101
|
All preset filters are described at [8: Preset Filters]
|
87
102
|
|
@@ -89,14 +104,18 @@ All preset filters are described at [8: Preset Filters]
|
|
89
104
|
|
90
105
|
You can add a setting for each field
|
91
106
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
107
|
+
```ruby
|
108
|
+
form do
|
109
|
+
field :field_name, :present => true, length => 0..10
|
110
|
+
#...
|
111
|
+
end
|
112
|
+
```
|
96
113
|
|
97
114
|
This constraint works for an input form named as "field_name", for instance
|
98
115
|
|
99
|
-
|
116
|
+
```html
|
117
|
+
<input type="text" name="field_name" />
|
118
|
+
```
|
100
119
|
|
101
120
|
And key-value pares are following the field name.
|
102
121
|
They are constraints set for the field.
|
@@ -105,61 +124,91 @@ You can add your favorite constraints here.
|
|
105
124
|
All preset constraints are described at [9: Preset Constraints]
|
106
125
|
Read the chapter for more detail.
|
107
126
|
|
127
|
+
:present is a special constraint. if parameter not found for the field which
|
128
|
+
set :present constraint, the field will be marked as 'not present',
|
129
|
+
and other validation for rest constraints won't be executed.
|
130
|
+
|
131
|
+
You also can set :default
|
132
|
+
|
133
|
+
```ruby
|
134
|
+
form do
|
135
|
+
field :field_name, :default => 'Default Value', :length => 0..10
|
136
|
+
#...
|
137
|
+
end
|
138
|
+
```
|
139
|
+
|
140
|
+
When it's set, if parameter not found, the indicated value will be set
|
141
|
+
and other validation for rest constraints won't be executed.
|
142
|
+
|
143
|
+
You aren't allowed to set both :present and :default at same time.
|
144
|
+
|
108
145
|
And you can set filters here,
|
109
146
|
if you don't want to filter all the parameters included in the request.
|
110
147
|
This filtering setting only affets on :field_name.
|
111
148
|
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
149
|
+
```ruby
|
150
|
+
form do
|
151
|
+
field :field_name, :present => true, filters => [:strip, :downcase]
|
152
|
+
#...
|
153
|
+
end
|
154
|
+
```
|
116
155
|
|
117
156
|
You can set as just one single symbol, if you don't need multiple filters.
|
118
157
|
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
158
|
+
```ruby
|
159
|
+
form do
|
160
|
+
field :field_name, :present => true, filters => :strip
|
161
|
+
#...
|
162
|
+
end
|
163
|
+
```
|
123
164
|
|
124
|
-
####
|
165
|
+
#### selection
|
125
166
|
|
126
167
|
You also can set the rule like this.
|
127
168
|
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
169
|
+
```ruby
|
170
|
+
form do
|
171
|
+
selection :field_name, :count => 1..3, int => true
|
172
|
+
#...
|
173
|
+
end
|
174
|
+
```
|
132
175
|
|
133
176
|
This is just for field which has multiple values.
|
134
177
|
For instance,
|
135
178
|
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
179
|
+
```html
|
180
|
+
<input type="checkbox" name="field_name[]" value="1" checked>
|
181
|
+
<label>check1</label>
|
182
|
+
<input type="checkbox" name="field_name[]" value="2" checked>
|
183
|
+
<label>check2</label>
|
184
|
+
<input type="checkbox" name="field_name[]" value="3" checked>
|
185
|
+
<label>check3</label>
|
186
|
+
```
|
142
187
|
|
143
188
|
Or
|
144
189
|
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
190
|
+
```html
|
191
|
+
<select name="favorite[]" multiple>
|
192
|
+
<option value="1" selected="selected">white</option>
|
193
|
+
<option value="2">black</option>
|
194
|
+
<option value="3">blue</option>
|
195
|
+
</select>
|
196
|
+
```
|
150
197
|
|
151
198
|
Rack request handle such type of name (exp: field_name[]) as Array.
|
152
|
-
For this type of input, use '
|
199
|
+
For this type of input, use 'selection' method.
|
153
200
|
In this case, you must use :count constraints instead of :present.
|
154
201
|
|
155
202
|
#### combination
|
156
203
|
|
157
204
|
There is another special rule, 'Combination'
|
158
205
|
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
206
|
+
```ruby
|
207
|
+
form do
|
208
|
+
combination :same_address, :fields => ["email01", "email02"], :same => true
|
209
|
+
combination :favorite_color, :fields => ["white", "black", "blue"], :any => true
|
210
|
+
end
|
211
|
+
```
|
163
212
|
|
164
213
|
Set rule-name as a first argument.
|
165
214
|
And you should set multiple target fields.
|
@@ -168,10 +217,12 @@ And one constraint like (:same => true), or (:any => true).
|
|
168
217
|
:same and :any are called as 'Combination Constraint'
|
169
218
|
For this purpose, formkeeper provides you a simple way to do same things.
|
170
219
|
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
220
|
+
```ruby
|
221
|
+
form do
|
222
|
+
same :same_address, ["email01", "email02"]
|
223
|
+
any :favorite_color, ["white", "black", "blue"]
|
224
|
+
end
|
225
|
+
```
|
175
226
|
|
176
227
|
You can call a name of 'Combination Constraints' as a method.
|
177
228
|
Followed by rule-name and target-fields.
|
@@ -182,16 +233,18 @@ All preset constraints are described at [10: Preset Combination Constraints]
|
|
182
233
|
|
183
234
|
'form.failed?' can be used to judge if user's input is valid for the rule you build.
|
184
235
|
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
236
|
+
```ruby
|
237
|
+
post '/entry' do
|
238
|
+
form do
|
239
|
+
#...
|
240
|
+
end
|
241
|
+
if form.failed?
|
242
|
+
# user's input is invalid
|
243
|
+
else
|
244
|
+
# user's input is valid!
|
245
|
+
end
|
246
|
+
end
|
247
|
+
```
|
195
248
|
|
196
249
|
### 3: Pick up valid data
|
197
250
|
|
@@ -202,17 +255,19 @@ you can implement your domain logic with valid parameters.
|
|
202
255
|
This data you can obtain through this method is a filtered data
|
203
256
|
according to the rule you build (if you set a 'filters' rule).
|
204
257
|
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
258
|
+
```ruby
|
259
|
+
post '/entry' do
|
260
|
+
form do
|
261
|
+
#...
|
262
|
+
end
|
263
|
+
if form.failed?
|
264
|
+
#...
|
265
|
+
else
|
266
|
+
# do something with valid data
|
267
|
+
Database.insert( :title => form[:field], :message => form[:message] )
|
268
|
+
end
|
269
|
+
end
|
270
|
+
```
|
216
271
|
|
217
272
|
### 4: Check if what field has failed?
|
218
273
|
|
@@ -220,159 +275,173 @@ When validation is failed, you might want to provide user
|
|
220
275
|
same form again, with error message that describes what fields was invalid.
|
221
276
|
For this purpose, use 'failed_on?' method.
|
222
277
|
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
278
|
+
```ruby
|
279
|
+
post '/entry' do
|
280
|
+
form do
|
281
|
+
#...
|
282
|
+
end
|
283
|
+
if form.failed?
|
284
|
+
erb :entry
|
285
|
+
else
|
286
|
+
#...
|
287
|
+
end
|
288
|
+
end
|
289
|
+
__END__
|
290
|
+
@@ entry
|
291
|
+
<html>
|
292
|
+
<head><title>Entry</title></head>
|
293
|
+
<body>
|
294
|
+
<% if form.failed? %>
|
295
|
+
<% if form.failed_on?(:title) %>
|
296
|
+
<p>Title is invalid</p>
|
297
|
+
<% end %>
|
298
|
+
<% if form.failed_on?(:message) %>
|
299
|
+
<p>Message is invalid</p>
|
300
|
+
<% end %>
|
301
|
+
<% end %>
|
302
|
+
<form action="/entry" method="post">
|
303
|
+
<label>Title</label><input type="text" name="title"><br />
|
304
|
+
<label>Message</label><textarea name="message"></textarea>
|
305
|
+
<input type="submit" value="Post this entry">
|
306
|
+
</form>
|
307
|
+
</body>
|
308
|
+
</html>
|
309
|
+
```
|
253
310
|
|
254
311
|
### 5: Check if what field and constraint has failed?
|
255
312
|
|
256
313
|
You can pass constraint-type to 'failed_on?' as a second argument.
|
257
314
|
This provides you a way to show detailed error-messages.
|
258
315
|
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
316
|
+
```ruby
|
317
|
+
post '/entry' do
|
318
|
+
form do
|
319
|
+
#...
|
320
|
+
end
|
321
|
+
if form.failed?
|
322
|
+
erb :entry
|
323
|
+
else
|
324
|
+
#...
|
325
|
+
end
|
326
|
+
end
|
327
|
+
__END__
|
328
|
+
@@ entry
|
329
|
+
<html>
|
330
|
+
<head><title>Entry</title></head>
|
331
|
+
<body>
|
332
|
+
<% if form.failed? %>
|
333
|
+
<% if form.failed_on?(:title, :present) %>
|
334
|
+
<p>Title not found</p>
|
335
|
+
<% end %>
|
336
|
+
<% if form.failed_on?(:title, :length) %>
|
337
|
+
<p>Title's length is invalid </p>
|
338
|
+
<% end %>
|
339
|
+
<% if form.failed_on?(:message, :present) %>
|
340
|
+
<p>Message not found</p>
|
341
|
+
<% end %>
|
342
|
+
<% end %>
|
343
|
+
<form action="/entry" method="post">
|
344
|
+
<label>Title</label><input type="text" name="title"><br />
|
345
|
+
<label>Message</label><textarea name="message"></textarea>
|
346
|
+
<input type="submit" value="Post this entry">
|
347
|
+
</form>
|
348
|
+
</body>
|
349
|
+
</html>
|
350
|
+
```
|
292
351
|
|
293
352
|
### 6: Fill in form
|
294
353
|
|
295
354
|
In many case you might want to fill in form with user's last input.
|
296
355
|
Do like following. 'fill_in_form' automatically fill the fields with 'params'
|
297
356
|
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
357
|
+
```ruby
|
358
|
+
post '/entry' do
|
359
|
+
form do
|
360
|
+
#...
|
361
|
+
end
|
362
|
+
if form.failed?
|
363
|
+
output = erb :entry
|
364
|
+
fill_in_form(output)
|
365
|
+
else
|
366
|
+
#...
|
367
|
+
end
|
368
|
+
end
|
369
|
+
```
|
309
370
|
|
310
371
|
### 7: Message Handling
|
311
372
|
|
312
373
|
You can aggregate a error messages into external yaml file.
|
313
374
|
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
375
|
+
```yaml
|
376
|
+
--- messages.yaml
|
377
|
+
login:
|
378
|
+
username:
|
379
|
+
present: input name!
|
380
|
+
length: intput name (length should be between 0 and 10)
|
381
|
+
email:
|
382
|
+
DEFAULT: input correct email address
|
383
|
+
post_entry:
|
384
|
+
title:
|
385
|
+
present: Title not found
|
386
|
+
DEFAULT:
|
387
|
+
username:
|
388
|
+
present: username not found
|
389
|
+
-- ...
|
390
|
+
```
|
328
391
|
|
329
392
|
DEFAULT is a special type. If it can't find setting for indicated validation-type, it uses message set for DEFAULT.
|
330
393
|
After you prepare a yaml file, load it.
|
331
394
|
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
395
|
+
```ruby
|
396
|
+
form_messages File.expand_path(File.join(File.dirname(__FILE__), 'config', 'form_messages.yaml'))
|
397
|
+
post '/entry' do
|
398
|
+
#...
|
399
|
+
end
|
400
|
+
```
|
336
401
|
|
337
402
|
You can show messages bound to indicated action-name you set in yaml.
|
338
403
|
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
404
|
+
```html
|
405
|
+
<html>
|
406
|
+
<head><title>Entry</title></head>
|
407
|
+
<body>
|
408
|
+
<% if form.failed? %>
|
409
|
+
<ul>
|
410
|
+
<% form.messages(:post_entry).each do |message| %>
|
411
|
+
<li><%= message %></li>
|
412
|
+
<% end %>
|
413
|
+
</ul>
|
414
|
+
<% end %>
|
415
|
+
</body>
|
416
|
+
</html>
|
417
|
+
```
|
351
418
|
|
352
419
|
If you want to show messages for each field, separately, of course you can.
|
353
420
|
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
421
|
+
```html
|
422
|
+
<html>
|
423
|
+
<head><title>Entry</title></head>
|
424
|
+
<body>
|
425
|
+
<form>
|
426
|
+
<% if form.failed? %>
|
427
|
+
<ul>
|
428
|
+
<% form.messages(:login, :username).each do |message| %>
|
429
|
+
<li><%= message %></li>
|
430
|
+
<% end %>
|
431
|
+
</ul>
|
432
|
+
<% end %>
|
433
|
+
<label>username</label><input type="text" name="username">
|
434
|
+
<% if form.failed? %>
|
435
|
+
<ul>
|
436
|
+
<% form.messages(:login, :password).each do |message| %>
|
437
|
+
<li><%= message %></li>
|
438
|
+
<% end %>
|
439
|
+
</ul>
|
440
|
+
<% end %>
|
441
|
+
<label>password</label><input type="text" name="password">
|
442
|
+
</body>
|
443
|
+
</html>
|
444
|
+
```
|
376
445
|
|
377
446
|
### 8: Preset Filters
|
378
447
|
|
@@ -405,33 +474,36 @@ If you want to show messages for each field, separately, of course you can.
|
|
405
474
|
|
406
475
|
### 11: Utilize Plugins
|
407
476
|
|
408
|
-
|
477
|
+
```ruby
|
478
|
+
require 'formkeeper/japanese'
|
409
479
|
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
480
|
+
post '/entry' do
|
481
|
+
form do
|
482
|
+
filters :zenkaku2hankaku
|
483
|
+
end
|
484
|
+
end
|
485
|
+
```
|
415
486
|
|
416
487
|
### 12: Custom Filter
|
417
488
|
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
post '/entry' do
|
423
|
-
form do
|
424
|
-
filters :my_capitalize_filter
|
425
|
-
end
|
426
|
-
end
|
489
|
+
```ruby
|
490
|
+
form_filter :my_capitalize_filter do |value|
|
491
|
+
value.capitalize
|
492
|
+
end
|
427
493
|
|
494
|
+
post '/entry' do
|
495
|
+
form do
|
496
|
+
filters :my_capitalize_filter
|
497
|
+
end
|
498
|
+
end
|
499
|
+
```
|
428
500
|
|
429
501
|
### 13: Custom Constraint
|
430
502
|
|
431
503
|
## See Also
|
432
504
|
|
433
|
-
https://github.com/lyokato/formkeeper/
|
434
|
-
https://github.com/lyokato/formkeeper-japanese/
|
505
|
+
* https://github.com/lyokato/formkeeper/
|
506
|
+
* https://github.com/lyokato/formkeeper-japanese/
|
435
507
|
|
436
508
|
## Contributing
|
437
509
|
|