form_input 0.9.0.pre1

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.
Files changed (53) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +5 -0
  3. data/LICENSE +19 -0
  4. data/README.md +3160 -0
  5. data/Rakefile +19 -0
  6. data/example/controllers/ramaze/press_release.rb +104 -0
  7. data/example/controllers/ramaze/profile.rb +38 -0
  8. data/example/controllers/sinatra/press_release.rb +114 -0
  9. data/example/controllers/sinatra/profile.rb +39 -0
  10. data/example/forms/change_password_form.rb +17 -0
  11. data/example/forms/login_form.rb +14 -0
  12. data/example/forms/lost_password_form.rb +14 -0
  13. data/example/forms/new_password_form.rb +15 -0
  14. data/example/forms/password_form.rb +18 -0
  15. data/example/forms/press_release_form.rb +153 -0
  16. data/example/forms/profile_form.rb +21 -0
  17. data/example/forms/signup_form.rb +25 -0
  18. data/example/views/press_release.slim +65 -0
  19. data/example/views/profile.slim +28 -0
  20. data/example/views/snippets/form_block.slim +27 -0
  21. data/example/views/snippets/form_chunked.slim +25 -0
  22. data/example/views/snippets/form_hidden.slim +21 -0
  23. data/example/views/snippets/form_panel.slim +89 -0
  24. data/form_input.gemspec +32 -0
  25. data/lib/form_input/core.rb +1165 -0
  26. data/lib/form_input/localize.rb +49 -0
  27. data/lib/form_input/r18n/cs.yml +97 -0
  28. data/lib/form_input/r18n/en.yml +70 -0
  29. data/lib/form_input/r18n/pl.yml +122 -0
  30. data/lib/form_input/r18n/sk.yml +120 -0
  31. data/lib/form_input/r18n.rb +163 -0
  32. data/lib/form_input/steps.rb +365 -0
  33. data/lib/form_input/types.rb +176 -0
  34. data/lib/form_input/version.rb +12 -0
  35. data/lib/form_input.rb +5 -0
  36. data/test/helper.rb +21 -0
  37. data/test/localize/en.yml +63 -0
  38. data/test/r18n/cs.yml +60 -0
  39. data/test/r18n/xx.yml +51 -0
  40. data/test/reference/cs.txt +352 -0
  41. data/test/reference/cs.yml +14 -0
  42. data/test/reference/en.txt +76 -0
  43. data/test/reference/en.yml +8 -0
  44. data/test/reference/pl.txt +440 -0
  45. data/test/reference/pl.yml +16 -0
  46. data/test/reference/sk.txt +352 -0
  47. data/test/reference/sk.yml +14 -0
  48. data/test/test_core.rb +1272 -0
  49. data/test/test_localize.rb +27 -0
  50. data/test/test_r18n.rb +373 -0
  51. data/test/test_steps.rb +482 -0
  52. data/test/test_types.rb +307 -0
  53. metadata +145 -0
@@ -0,0 +1,365 @@
1
+ # Support for multi-step forms.
2
+
3
+ class FormInput
4
+
5
+ # Turn this form into multi-step form using given steps.
6
+ # Returns self for chaining.
7
+ def self.define_steps( steps )
8
+ @steps = steps = steps.to_hash.dup.freeze
9
+
10
+ self.send( :include, StepMethods )
11
+
12
+ opts = { filter: ->{ steps.keys.find{ |x| x.to_s == self } }, class: Symbol }
13
+
14
+ param :step, opts, type: :hidden
15
+ param :next, opts, type: :ignore
16
+ param :last, opts, type: :hidden
17
+ param :seen, opts, type: :hidden
18
+
19
+ self
20
+ end
21
+
22
+ # Get hash mapping defined steps to their names, or nil if there are none.
23
+ def self.form_steps
24
+ @steps
25
+ end
26
+
27
+ # Additional methods used for multi-step form processing.
28
+ module StepMethods
29
+
30
+ # Initialize new instance.
31
+ def initialize( *args )
32
+ super
33
+ self.seen = last_step( seen, step )
34
+ self.step ||= steps.first
35
+ self.next ||= step
36
+ self.last ||= step
37
+ if correct_step?
38
+ self.step = self.next
39
+ self.seen = last_step( seen, previous_step( step ) )
40
+ end
41
+ self.last = last_step( step, last )
42
+ end
43
+
44
+ # Make all steps instantly available.
45
+ # Returns self for chaining.
46
+ def unlock_steps
47
+ self.last = self.seen = steps.last
48
+ self
49
+ end
50
+
51
+ # Get parameters relevant for given step.
52
+ def step_params( step )
53
+ fail( ArgumentError, "invalid step name #{step}" ) unless form_steps.key?( step )
54
+ tagged_params( step )
55
+ end
56
+
57
+ # Get the parameters relevant for the current step.
58
+ def current_params
59
+ tagged_params( step )
60
+ end
61
+
62
+ # Get the parameters irrelevant for the current step.
63
+ def other_params
64
+ untagged_params( step )
65
+ end
66
+
67
+ # Get hash mapping defined steps to their names.
68
+ # Note that this is never localized. See step_names instead.
69
+ def form_steps
70
+ self.class.form_steps
71
+ end
72
+
73
+ # Get allowed form steps as list of symbols.
74
+ def steps
75
+ form_steps.keys
76
+ end
77
+
78
+ # Get name of current or given step, if any.
79
+ def step_name( step = self.step )
80
+ form_steps[ step ]
81
+ end
82
+ alias raw_step_name step_name
83
+
84
+ # Get hash of steps along with their names, for use in a sidebar.
85
+ def step_names
86
+ form_steps.reject{ |k,v| v.nil? }
87
+ end
88
+ alias raw_step_names step_names
89
+
90
+ # Get index of given/current step among all steps.
91
+ def step_index( step = self.step )
92
+ steps.index( step ) or fail( ArgumentError, "invalid step name #{step}" )
93
+ end
94
+
95
+ # Test if current step is before given step.
96
+ def step_before?( step )
97
+ step_index < step_index( step )
98
+ end
99
+
100
+ # Test if current step is after given step.
101
+ def step_after?( step )
102
+ step_index > step_index( step )
103
+ end
104
+
105
+ # Get first step, or first step among given list of steps, if any.
106
+ def first_step( *args )
107
+ if args.empty?
108
+ steps.first
109
+ else
110
+ args.flatten.compact.min_by{ |x| step_index( x ) }
111
+ end
112
+ end
113
+
114
+ # Get last step, or last step among given list of steps, if any.
115
+ def last_step( *args )
116
+ if args.empty?
117
+ steps.last
118
+ else
119
+ args.flatten.compact.max_by{ |x| step_index( x ) }
120
+ end
121
+ end
122
+
123
+ # Test if given/current step is the first step.
124
+ def first_step?( step = self.step )
125
+ step == first_step
126
+ end
127
+
128
+ # Test if given/current step is the last step.
129
+ def last_step?( step = self.step )
130
+ step == last_step
131
+ end
132
+
133
+ # Get steps before given/current step.
134
+ def previous_steps( step = self.step )
135
+ index = steps.index( step ) || 0
136
+ steps.first( index )
137
+ end
138
+
139
+ # Get steps after given/current step.
140
+ def next_steps( step = self.step )
141
+ index = steps.index( step ) || -1
142
+ steps[ index + 1 .. -1 ]
143
+ end
144
+
145
+ # Get the next step, or nil if there is none.
146
+ def next_step( step = self.step )
147
+ next_steps( step ).first
148
+ end
149
+
150
+ # Get the previous step, or nil if there is none.
151
+ def previous_step( step = self.step )
152
+ previous_steps( step ).last
153
+ end
154
+
155
+ # Get name of the next step, if any.
156
+ def next_step_name
157
+ step_name( next_step )
158
+ end
159
+
160
+ # Get name of the previous step, if any.
161
+ def previous_step_name
162
+ step_name( previous_step )
163
+ end
164
+
165
+ # Test if the current/given step has no parameters defined.
166
+ def extra_step?( step = self.step )
167
+ step_params( step ).empty?
168
+ end
169
+
170
+ # Test if the current/given step has some parameters defined.
171
+ def regular_step?( step = self.step )
172
+ not extra_step?( step )
173
+ end
174
+
175
+ # Get steps with no parameters defined.
176
+ def extra_steps
177
+ steps.select{ |step| extra_step?( step ) }
178
+ end
179
+
180
+ # Get steps with some parameters defined.
181
+ def regular_steps
182
+ steps.select{ |step| regular_step?( step ) }
183
+ end
184
+
185
+ # Filter steps by testing their corresponding parameters with given block. Excludes steps without parameters.
186
+ def filter_steps
187
+ steps.select do |step|
188
+ params = step_params( step )
189
+ yield params unless params.empty?
190
+ end
191
+ end
192
+
193
+ # Get steps which have required parameters. Excludes steps without parameters.
194
+ def required_steps
195
+ filter_steps{ |params| params.any?{ |p| p.required? } }
196
+ end
197
+
198
+ # Get steps which have no required parameters. Excludes steps without parameters.
199
+ def optional_steps
200
+ filter_steps{ |params| params.none?{ |p| p.required? } }
201
+ end
202
+
203
+ # Test if given/current has some required parameters. Considered false for steps without parameters.
204
+ def required_step?( step = self.step )
205
+ step_params( step ).any?{ |p| p.required? }
206
+ end
207
+
208
+ # Test if given/current step has no required parameters. Considered true for steps without parameters.
209
+ def optional_step?( step = self.step )
210
+ not required_step?( step )
211
+ end
212
+
213
+ # Get steps which have some data filled in. Excludes steps without parameters.
214
+ def filled_steps
215
+ filter_steps{ |params| params.any?{ |p| p.filled? } }
216
+ end
217
+
218
+ # Get steps which have no data filled in. Excludes steps without parameters.
219
+ def unfilled_steps
220
+ filter_steps{ |params| params.none?{ |p| p.filled? } }
221
+ end
222
+
223
+ # Test if given/current step has some data filled in. Considered true for steps without parameters.
224
+ def filled_step?( step = self.step )
225
+ params = step_params( step )
226
+ params.empty? or params.any?{ |p| p.filled? }
227
+ end
228
+
229
+ # Test if given/current step has no data filled in. Considered false for steps without parameters.
230
+ def unfilled_step?( step = self.step )
231
+ not filled_step?( step )
232
+ end
233
+
234
+ # Get steps which have all data filled in correctly. Excludes steps without parameters.
235
+ def correct_steps
236
+ filter_steps{ |params| valid?( params ) }
237
+ end
238
+
239
+ # Get steps which have some invalid data filled in. Excludes steps without parameters.
240
+ def incorrect_steps
241
+ filter_steps{ |params| invalid?( params ) }
242
+ end
243
+
244
+ # Get first step with invalid data, or nil if there is none.
245
+ def incorrect_step
246
+ incorrect_steps.first
247
+ end
248
+
249
+ # Test if the current/given step has all data filled in correctly. Considered true for steps without parameters.
250
+ def correct_step?( step = self.step )
251
+ valid?( step_params( step ) )
252
+ end
253
+
254
+ # Test if the current/given step has some invalid data filled in. Considered false for steps without parameters.
255
+ def incorrect_step?( step = self.step )
256
+ invalid?( step_params( step ) )
257
+ end
258
+
259
+ # Get steps with some parameters enabled. Excludes steps without parameters.
260
+ def enabled_steps
261
+ filter_steps{ |params| params.any?{ |p| p.enabled? } }
262
+ end
263
+
264
+ # Get steps with all parameters disabled. Excludes steps without parameters.
265
+ def disabled_steps
266
+ filter_steps{ |params| params.all?{ |p| p.disabled? } }
267
+ end
268
+
269
+ # Test if given/current step has some parameters enabled. Considered true for steps without parameters.
270
+ def enabled_step?( step = self.step )
271
+ params = step_params( step )
272
+ params.empty? or params.any?{ |p| p.enabled? }
273
+ end
274
+
275
+ # Test if given/current step has all parameters disabled. Considered false for steps without parameters.
276
+ def disabled_step?( step = self.step )
277
+ not enabled_step?( step )
278
+ end
279
+
280
+ # Get unfinished steps, those we have not yet visited or visited for the first time.
281
+ def unfinished_steps
282
+ next_steps( seen )
283
+ end
284
+
285
+ # Get finished steps, those we have visited or skipped over before.
286
+ def finished_steps
287
+ steps - unfinished_steps
288
+ end
289
+
290
+ # Test if given/current step was not yet visited or was visited for the first time.
291
+ def unfinished_step?( step = self.step )
292
+ index = seen ? step_index( seen ) : -1
293
+ step_index( step ) > index
294
+ end
295
+
296
+ # Test if given/current step was visited or skipped over before.
297
+ def finished_step?( step = self.step )
298
+ not unfinished_step?( step )
299
+ end
300
+
301
+ # Get yet inaccessible steps, excluding the last accessed step.
302
+ def inaccessible_steps
303
+ next_steps( last )
304
+ end
305
+
306
+ # Get already accessible steps, including the last accessed step.
307
+ def accessible_steps
308
+ steps - inaccessible_steps
309
+ end
310
+
311
+ # Test if given/current step is inaccessible.
312
+ def inaccessible_step?( step = self.step )
313
+ step_index( step ) > step_index( last )
314
+ end
315
+
316
+ # Test if given/current step is accessible.
317
+ def accessible_step?( step = self.step )
318
+ not inaccessible_step?( step )
319
+ end
320
+
321
+ # Get correct finished steps. Includes finished steps without parameters.
322
+ def complete_steps
323
+ finished_steps.select{ |step| correct_step?( step ) }
324
+ end
325
+
326
+ # Get incorrect finished steps. Excludes steps without parameters.
327
+ def incomplete_steps
328
+ finished_steps.select{ |step| incorrect_step?( step ) }
329
+ end
330
+
331
+ # Test if given/current step is one of the complete steps.
332
+ def complete_step?( step = self.step )
333
+ finished_step?( step ) and correct_step?( step )
334
+ end
335
+
336
+ # Test if given/current step is one of the incomplete steps.
337
+ def incomplete_step?( step = self.step )
338
+ finished_step?( step ) and incorrect_step?( step )
339
+ end
340
+
341
+ # Get steps which shell be displayed as correct.
342
+ def good_steps
343
+ steps.select{ |step| good_step?( step ) }
344
+ end
345
+
346
+ # Get steps which shell be displayed as incorrect.
347
+ def bad_steps
348
+ steps.select{ |step| bad_step?( step ) }
349
+ end
350
+
351
+ # Test if given/current step shell be displayed as correct.
352
+ def good_step?( step = self.step )
353
+ complete_step?( step ) and filled_step?( step ) and regular_step?( step )
354
+ end
355
+
356
+ # Test if given/current step shell be displayed as incorrect.
357
+ def bad_step?( step = self.step )
358
+ incomplete_step?( step )
359
+ end
360
+
361
+ end
362
+
363
+ end
364
+
365
+ # EOF #
@@ -0,0 +1,176 @@
1
+ # Common form types.
2
+
3
+ require 'time'
4
+ require 'date'
5
+
6
+ # Extend forms with arguments for form parameter types which are used often.
7
+ class FormInput
8
+
9
+ # Regular expressions commonly used to validate input arguments.
10
+
11
+ # Matches names using latin alphabet.
12
+ LATIN_NAMES_RE = /\A[\p{Latin}\-\. ]+\z/u
13
+
14
+ # Matches common email addresses. Note that it doesn't match all addresses allowed by RFC, though.
15
+ SIMPLE_EMAIL_RE = /\A[-_.=+%a-z0-9]+@(?:[-_a-z0-9]+\.)+[a-z]{2,4}\z/i
16
+
17
+ # Matches generic ZIP code. Note that the real format changes for each country.
18
+ ZIP_CODE_RE = /\A[A-Z\d]++(?:[- ]?[A-Z\d]+)*+\z/i
19
+
20
+ # Filter for phone numbers.
21
+ PHONE_NUMBER_FILTER = ->{ gsub( /\s*[-\/\.]\s*/, '-' ).gsub( /\s+/, ' ' ).strip }
22
+
23
+ # Matches generic phone number.
24
+ PHONE_NUMBER_RE = /\A\+?\d++(?:[- ]?(?:\d+|\(\d+\)))*+(?:[- ]?[A-Z\d]+)*+\z/i
25
+
26
+ # Basic types.
27
+
28
+ # Integer number.
29
+ INTEGER_ARGS = {
30
+ filter: ->{ ( Integer( self, 10 ) rescue self ) unless empty? },
31
+ class: Integer,
32
+ }
33
+
34
+ # Float number.
35
+ FLOAT_ARGS = {
36
+ filter: ->{ ( Float( self ) rescue self ) unless empty? },
37
+ class: Float,
38
+ }
39
+
40
+ # Boolean value, displayed as a select menu.
41
+ BOOL_ARGS = {
42
+ type: :select,
43
+ data: [ [ true, 'Yes' ], [ false, 'No' ] ],
44
+ filter: ->{ self == 'true' unless empty? },
45
+ class: [ TrueClass, FalseClass ],
46
+ }
47
+
48
+ # Boolean value, displayed as a checkbox.
49
+ CHECKBOX_ARGS = {
50
+ type: :checkbox,
51
+ filter: ->{ not empty? },
52
+ format: ->{ self if self },
53
+ class: [ TrueClass, FalseClass ],
54
+ }
55
+
56
+ # Address fields.
57
+
58
+ # Email.
59
+ EMAIL_ARGS = {
60
+ match: SIMPLE_EMAIL_RE,
61
+ }
62
+
63
+ # Zip code.
64
+ ZIP_ARGS = {
65
+ match: ZIP_CODE_RE,
66
+ }
67
+
68
+ # Phone number.
69
+ PHONE_ARGS = {
70
+ filter: PHONE_NUMBER_FILTER,
71
+ match: PHONE_NUMBER_RE,
72
+ }
73
+
74
+ # Date and time.
75
+
76
+ # Full time format.
77
+ TIME_FORMAT = "%Y-%m-%d %H:%M:%S".freeze
78
+ # Full time format example.
79
+ TIME_FORMAT_EXAMPLE = "YYYY-MM-DD HH:MM:SS".freeze
80
+
81
+ # Full time.
82
+ TIME_ARGS = {
83
+ placeholder: TIME_FORMAT_EXAMPLE,
84
+ filter: ->{ ( FormInput.parse_time!( self, TIME_FORMAT ) rescue self ) unless empty? },
85
+ format: ->{ utc.strftime( TIME_FORMAT ) rescue self },
86
+ class: Time,
87
+ }
88
+
89
+ # US date format.
90
+ US_DATE_FORMAT = "%m/%d/%Y".freeze
91
+ # US date format example.
92
+ US_DATE_FORMAT_EXAMPLE = "MM/DD/YYYY".freeze
93
+
94
+ # Time in US date format.
95
+ US_DATE_ARGS = {
96
+ placeholder: US_DATE_FORMAT_EXAMPLE,
97
+ filter: ->{ ( FormInput.parse_time!( self, US_DATE_FORMAT ) rescue self ) unless empty? },
98
+ format: ->{ utc.strftime( US_DATE_FORMAT ) rescue self },
99
+ class: Time,
100
+ }
101
+
102
+ # UK date format.
103
+ UK_DATE_FORMAT = "%d/%m/%Y".freeze
104
+ # UK date format example.
105
+ UK_DATE_FORMAT_EXAMPLE = "DD/MM/YYYY".freeze
106
+
107
+ # Time in UK date format.
108
+ UK_DATE_ARGS = {
109
+ placeholder: UK_DATE_FORMAT_EXAMPLE,
110
+ filter: ->{ ( FormInput.parse_time!( self, UK_DATE_FORMAT ) rescue self ) unless empty? },
111
+ format: ->{ utc.strftime( UK_DATE_FORMAT ) rescue self },
112
+ class: Time,
113
+ }
114
+
115
+ # EU date format.
116
+ EU_DATE_FORMAT = "%-d.%-m.%Y".freeze
117
+ # EU date format example.
118
+ EU_DATE_FORMAT_EXAMPLE = "D.M.YYYY".freeze
119
+
120
+ # Time in EU date format.
121
+ EU_DATE_ARGS = {
122
+ placeholder: EU_DATE_FORMAT_EXAMPLE,
123
+ filter: ->{ ( FormInput.parse_time!( self, EU_DATE_FORMAT ) rescue self ) unless empty? },
124
+ format: ->{ utc.strftime( EU_DATE_FORMAT ) rescue self },
125
+ class: Time,
126
+ }
127
+
128
+ # Hours format.
129
+ HOURS_FORMAT = "%H:%M".freeze
130
+ # Hours format example.
131
+ HOURS_FORMAT_EXAMPLE = "HH:MM".freeze
132
+
133
+ # Seconds since midnight in hours:minutes format.
134
+ HOURS_ARGS = {
135
+ placeholder: HOURS_FORMAT_EXAMPLE,
136
+ filter: ->{ ( FormInput.parse_time( self, HOURS_FORMAT ).to_i % 86400 rescue self ) unless empty? },
137
+ format: ->{ Time.at( self ).utc.strftime( HOURS_FORMAT ) rescue self },
138
+ class: Integer,
139
+ }
140
+
141
+ # Parse time like Time#strptime but raise on trailing garbage.
142
+ # Also ignores -, _ and ^ % modifiers, so the same format can be used for both parsing and formatting.
143
+ def self.parse_time( string, format )
144
+ format = format.gsub( /%[-_^]?(.)/, '%\1' )
145
+ # Rather than using _strptime and checking the leftover field,
146
+ # add required trailing character to both the string and format parameters.
147
+ suffix = ( string[ -1 ] == "\1" ? "\2" : "\1" )
148
+ Time.strptime( "+0000 #{string}#{suffix}", "%z #{format}#{suffix}" ).utc
149
+ end
150
+
151
+ # Like parse_time, but falls back to DateTime.parse heuristics when the date/time can't be parsed.
152
+ def self.parse_time!( string, format )
153
+ parse_time( string, format )
154
+ rescue
155
+ DateTime.parse( string ).to_time.utc
156
+ end
157
+
158
+ # Transformation which drops empty values from hashes and arrays and turns empty string into nil.
159
+ PRUNED_ARGS = {
160
+ transform: ->{
161
+ case self
162
+ when Array
163
+ reject{ |v| v.nil? or ( v.respond_to?( :empty? ) && v.empty? ) }
164
+ when Hash
165
+ reject{ |k,v| v.nil? or ( v.respond_to?( :empty? ) && v.empty? ) }
166
+ when String
167
+ self unless empty?
168
+ else
169
+ self
170
+ end
171
+ }
172
+ }
173
+
174
+ end
175
+
176
+ # EOF #
@@ -0,0 +1,12 @@
1
+ # Version number.
2
+
3
+ class FormInput
4
+ module Version
5
+ MAJOR = 0
6
+ MINOR = 9
7
+ PATCH = 0
8
+ STRING = [ MAJOR, MINOR, PATCH ].join( '.' ).freeze
9
+ end
10
+ end
11
+
12
+ # EOF #
data/lib/form_input.rb ADDED
@@ -0,0 +1,5 @@
1
+ require 'form_input/core'
2
+ require 'form_input/steps'
3
+ require 'form_input/types'
4
+ require 'form_input/version'
5
+ require 'form_input/r18n' if defined? R18n
data/test/helper.rb ADDED
@@ -0,0 +1,21 @@
1
+ # Test helper.
2
+
3
+ # Test coverage if enabled.
4
+
5
+ def jruby?
6
+ defined?( RUBY_ENGINE ) and RUBY_ENGINE == 'jruby'
7
+ end
8
+
9
+ if ENV[ 'COVERAGE' ]
10
+ require 'simplecov'
11
+ SimpleCov.start
12
+ end
13
+
14
+ begin
15
+ require 'codeclimate-test-reporter'
16
+ CodeClimate::TestReporter.start
17
+ ENV[ 'COVERAGE' ] = 'on'
18
+ rescue LoadError
19
+ end unless jruby?
20
+
21
+ # EOF #
@@ -0,0 +1,63 @@
1
+ ---
2
+ forms:
3
+ test_form:
4
+ email:
5
+ title: Email
6
+ form_title: Your email
7
+ error_title: email address
8
+ password:
9
+ title: Password
10
+ msg: Password must contain one lowercase and one uppercase letter and one digit
11
+ test_inflection_form:
12
+ name:
13
+ title: Name
14
+ address:
15
+ title: Address
16
+ state:
17
+ title: State
18
+ author:
19
+ title: Author
20
+ friends:
21
+ title: Friends
22
+ chars:
23
+ title: Characters
24
+ keywords:
25
+ title: Keywords
26
+ notes:
27
+ title: Notes
28
+ test_localize_form:
29
+ simple:
30
+ title: String
31
+ utf:
32
+ title: "ěščřžýáíéúůďťň"
33
+ yaml:
34
+ title: "%"
35
+ msg: "{}"
36
+ test_localized_steps_form:
37
+ steps:
38
+ one: First
39
+ two: Second
40
+ three: Third
41
+ test_r18n_form:
42
+ msg:
43
+ title: Message
44
+ msg2:
45
+ title: Second Message
46
+ test_steps_form:
47
+ steps:
48
+ intro: Intro
49
+ email: Email
50
+ name: Name
51
+ address: Address
52
+ message: Message
53
+ test_time_types_form:
54
+ time:
55
+ placeholder: YYYY-MM-DD HH:MM:SS
56
+ us_date:
57
+ placeholder: MM/DD/YYYY
58
+ uk_date:
59
+ placeholder: DD/MM/YYYY
60
+ eu_date:
61
+ placeholder: D.M.YYYY
62
+ hours:
63
+ placeholder: HH:MM
data/test/r18n/cs.yml ADDED
@@ -0,0 +1,60 @@
1
+ # Form input localization testing messages.
2
+
3
+ forms:
4
+ test_r18n_form:
5
+ msg:
6
+ title: Zpráva
7
+ form_title: Vaše zpráva
8
+ error_title: Parametr Zpráva
9
+ msg: '%p není správně vyplněn'
10
+ match_msg: '%p není ve správném tvaru'
11
+ reject_msg: '%p obsahuje nepovolené znaky'
12
+ required_msg: '%p musí být vyplněn'
13
+ msg2:
14
+ title: Druhá zpráva
15
+ error_title: Parametr druhá zpráva
16
+ msg3:
17
+ title: Třetí zpráva
18
+ test_msg: Argument %1
19
+ inflected_msg: !!inflect
20
+ s: Singular
21
+ p: Plural
22
+ texts:
23
+ test: Test
24
+
25
+ test_inflection_form:
26
+ name:
27
+ title: Jméno
28
+ gender: n
29
+ address:
30
+ title: Adresa
31
+ gender: f
32
+ state:
33
+ title: Stát
34
+ gender: mi
35
+ author:
36
+ title: Autor
37
+ gender: ma
38
+ keywords:
39
+ title: Klíčová slova
40
+ gender: n
41
+ notes:
42
+ title: Poznámky
43
+ gender: f
44
+ chars:
45
+ title: Znaky
46
+ gender: mi
47
+ friends:
48
+ title: Přátelé
49
+ gender: ma
50
+ test:
51
+ inflect: invalid
52
+
53
+ test_localized_steps_form:
54
+ steps:
55
+ one: První
56
+ two: Druhý
57
+ three: Třetí
58
+ four: Should not be here.
59
+
60
+ # EOF #