formula 1.1.1 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/formula.rb CHANGED
@@ -1,503 +1,20 @@
1
- module Formula
2
-
3
-
4
- require 'formula/railtie' if defined?(Rails)
5
-
6
- mattr_accessor :box_options
7
- mattr_accessor :area_options
8
- mattr_accessor :file_options
9
- mattr_accessor :field_options
10
- mattr_accessor :select_options
11
- @@box_options = {}
12
- @@area_options = {}
13
- @@file_options = {}
14
- @@field_options = {}
15
- @@select_options = {}
16
-
17
- # Default class assigned to block (<div class="block">...</div>).
18
- mattr_accessor :block_class
19
- @@block_class = 'block'
20
-
21
- # Default class assigned to input (<div class="input">...</div>).
22
- mattr_accessor :input_class
23
- @@input_class = 'input'
24
-
25
- # Default class assigned to association (<div class="association">...</div>).
26
- mattr_accessor :association_class
27
- @@association_class = 'association'
28
-
29
- # Default class assigned to block with errors (<div class="block errors">...</div>).
30
- mattr_accessor :block_error_class
31
- @@block_error_class = 'errors'
32
-
33
- # Default class assigned to input with errors (<div class="input errors">...</div>).
34
- mattr_accessor :input_error_class
35
- @@input_error_class = false
36
-
37
- # Default class assigned to input with errors (<div class="association errors">...</div>).
38
- mattr_accessor :association_error_class
39
- @@association_error_class = false
40
-
41
- # Default class assigned to error (<div class="error">...</div>).
42
- mattr_accessor :error_class
43
- @@error_class = 'error'
44
-
45
- # Default class assigned to hint (<div class="hint">...</div>).
46
- mattr_accessor :hint_class
47
- @@hint_class = 'hint'
48
-
49
- # Default tag assigned to block (<div class="input">...</div>).
50
- mattr_accessor :block_tag
51
- @@block_tag = :div
52
-
53
- # Default tag assigned to input (<div class="input">...</div>).
54
- mattr_accessor :input_tag
55
- @@input_tag = :div
56
-
57
- # Default tag assigned to association (<div class="association">...</div>).
58
- mattr_accessor :association_tag
59
- @@association_tag = :div
60
-
61
- # Default tag assigned to error (<div class="error">...</div>).
62
- mattr_accessor :error_tag
63
- @@error_tag = :div
64
-
65
- # Default tag assigned to hint (<div class="hint">...</div>).
66
- mattr_accessor :hint_tag
67
- @@hint_tag = :div
68
-
69
- # Method for file.
70
- mattr_accessor :file
71
- @@file = [:file?]
72
-
73
- # Default as.
74
- mattr_accessor :default_as
75
- @@default_as = :string
76
-
77
-
78
- class FormulaFormBuilder < ActionView::Helpers::FormBuilder
79
-
80
-
81
- # Generate a form button.
82
- #
83
- # Options:
84
- #
85
- # * :container - add custom options to the container
86
- # * :button - add custom options to the button
87
- #
88
- # Usage:
89
- #
90
- # f.button(:name)
91
- #
92
- # Equivalent:
93
- #
94
- # <div class="block">
95
- # <%= f.submit("Save")
96
- # </div>
97
-
98
- def button(value = nil, options = {})
99
- options[:button] ||= {}
100
-
101
- options[:container] ||= {}
102
- options[:container][:class] = arrayorize(options[:container][:class]) << ::Formula.block_class
103
-
104
-
105
- @template.content_tag(::Formula.block_tag, options[:container]) do
106
- submit value, options[:button]
107
- end
108
- end
109
-
110
-
111
- # Basic container generator for use with blocks.
112
- #
113
- # Options:
114
- #
115
- # * :hint - specify a hint to be displayed ('We promise not to spam you.', etc.)
116
- # * :label - override the default label used ('Name:', 'URL:', etc.)
117
- # * :error - override the default error used ('invalid', 'incorrect', etc.)
118
- #
119
- # Usage:
120
- #
121
- # f.block(:name, :label => "Name:", :hint => "Please use your full name.", :container => { :class => 'fill' }) do
122
- # ...
123
- # end
124
- #
125
- # Equivalent:
126
- #
127
- # <div class='block fill'>
128
- # <%= f.label(:name, "Name:") %>
129
- # ...
130
- # <div class="hint">Please use your full name.</div>
131
- # <div class="error">...</div>
132
- # </div>
133
-
134
- def block(method = nil, options = {}, &block)
135
- options[:error] ||= error(method) if method
136
-
137
- components = "".html_safe
138
-
139
- if method
140
- components << self.label(method, options[:label]) if options[:label] or options[:label].nil? and method
141
- end
142
-
143
- components << @template.capture(&block)
144
-
145
- options[:container] ||= {}
146
- options[:container][:class] = arrayorize(options[:container][:class]) << ::Formula.block_class << method
147
- options[:container][:class] << ::Formula.block_error_class if ::Formula.block_error_class.present? and error?(method)
148
-
149
- components << @template.content_tag(::Formula.hint_tag , options[:hint ], :class => ::Formula.hint_class ) if options[:hint ]
150
- components << @template.content_tag(::Formula.error_tag, options[:error], :class => ::Formula.error_class) if options[:error]
151
-
152
- @template.content_tag(::Formula.block_tag, options[:container]) do
153
- components
154
- end
155
- end
156
-
157
-
158
- # Generate a suitable form input for a given method by performing introspection on the type.
159
- #
160
- # Options:
161
- #
162
- # * :as - override the default type used (:url, :email, :phone, :password, :number, :text)
163
- # * :label - override the default label used ('Name:', 'URL:', etc.)
164
- # * :error - override the default error used ('invalid', 'incorrect', etc.)
165
- # * :input - add custom options to the input ({ :class => 'goregous' }, etc.)
166
- # * :container - add custom options to the container ({ :class => 'gorgeous' }, etc.)
167
- #
168
- # Usage:
169
- #
170
- # f.input(:name)
171
- # f.input(:email)
172
- # f.input(:password_a, :label => "Password", :hint => "It's a secret!", :container => { :class => "half" })
173
- # f.input(:password_b, :label => "Password", :hint => "It's a secret!", :container => { :class => "half" })
174
- #
175
- # Equivalent:
176
- #
177
- # <div class="block name">
178
- # <%= f.label(:name)
179
- # <div class="input string"><%= f.text_field(:name)</div>
180
- # <div class="error">...</div>
181
- # </div>
182
- # <div class="block email">
183
- # <%= f.label(:email)
184
- # <div class="input string"><%= f.email_field(:email)</div>
185
- # <div class="error">...</div>
186
- # </div>
187
- # <div class="block half password_a">
188
- # <div class="input">
189
- # <%= f.label(:password_a, "Password")
190
- # <%= f.password_field(:password_a)
191
- # <div class="hint">It's a secret!</div>
192
- # <div class="error">...</div>
193
- # </div>
194
- # </div>
195
- # <div class="block half password_b">
196
- # <div class="input">
197
- # <%= f.label(:password_b, "Password")
198
- # <%= f.password_field(:password_b)
199
- # <div class="hint">It's a secret!</div>
200
- # <div class="error">...</div>
201
- # </div>
202
- # </div>
203
-
204
- def input(method, options = {})
205
- options[:as] ||= as(method)
206
- options[:input] ||= {}
207
-
208
- return hidden_field method, options[:input] if options[:as] == :hidden
209
-
210
- klass = [::Formula.input_class, options[:as]]
211
- klass << ::Formula.input_error_class if ::Formula.input_error_class.present? and error?(method)
212
-
213
- self.block(method, options) do
214
- @template.content_tag(::Formula.input_tag, :class => klass) do
215
- case options[:as]
216
- when :text then text_area method, ::Formula.area_options.merge(options[:input] || {})
217
- when :file then file_field method, ::Formula.file_options.merge(options[:input] || {})
218
- when :string then text_field method, ::Formula.field_options.merge(options[:input] || {})
219
- when :password then password_field method, ::Formula.field_options.merge(options[:input] || {})
220
- when :url then url_field method, ::Formula.field_options.merge(options[:input] || {})
221
- when :email then email_field method, ::Formula.field_options.merge(options[:input] || {})
222
- when :phone then phone_field method, ::Formula.field_options.merge(options[:input] || {})
223
- when :number then number_field method, ::Formula.field_options.merge(options[:input] || {})
224
- when :boolean then check_box method, ::Formula.box_options.merge(options[:input] || {})
225
- when :country then country_select method, ::Formula.select_options.merge(options[:input] || {})
226
- when :date then date_select method, ::Formula.select_options.merge(options[:input] || {}), options[:input].delete(:html) || {}
227
- when :time then time_select method, ::Formula.select_options.merge(options[:input] || {}), options[:input].delete(:html) || {}
228
- when :datetime then datetime_select method, ::Formula.select_options.merge(options[:input] || {}), options[:input].delete(:html) || {}
229
- when :select then select method, options[:choices], ::Formula.select_options.merge(options[:input] || {}), options[:input].delete(:html) || {}
230
- end
231
- end
232
- end
233
- end
234
-
235
-
236
- # Generate a suitable form association for a given method by performing introspection on the type.
237
- #
238
- # Options:
239
- #
240
- # * :label - override the default label used ('Name:', 'URL:', etc.)
241
- # * :error - override the default error used ('invalid', 'incorrect', etc.)
242
- # * :association - add custom options to the input ({ :class => 'goregous' }, etc.)
243
- # * :container - add custom options to the container ({ :class => 'gorgeous' }, etc.)
244
- #
245
- # Usage:
246
- #
247
- # f.association(:category, Category.all, :id, :name, :hint => "What do you do?")
248
- # f.association(:category, Category.all, :id, :name, :association => { :prompt => "Category?" })
249
- # f.association(:category, Category.all, :id, :name, :association => { :html => { :class => "category" } })
250
- #
251
- # Equivalent:
252
- #
253
- # <div>
254
- # <div class="association category">
255
- # <%= f.label(:category)
256
- # <div class="association">
257
- # <%= f.collection_select(:category, Category.all, :id, :name) %>
258
- # </div>
259
- # <div class="hint">What do you do?</div>
260
- # <div class="error">...</div>
261
- # </div>
262
- # </div>
263
- # <div>
264
- # <div class="association category">
265
- # <%= f.label(:category)
266
- # <div class="association">
267
- # <%= f.collection_select(:category, Category.all, :id, :name, { :prompt => "Category") } %>
268
- # </div>
269
- # <div class="error">...</div>
270
- # </div>
271
- # </div>
272
- # <div>
273
- # <div class="association category">
274
- # <%= f.label(:category)
275
- # <div class="association">
276
- # <%= f.collection_select(:category, Category.all, :id, :name, {}, { :class => "category" } %>
277
- # </div>
278
- # <div class="error">...</div>
279
- # </div>
280
- # </div>
1
+ # frozen_string_literal: true
281
2
 
3
+ require 'zeitwerk'
282
4
 
283
- def association(method, collection, value, text, options = {})
284
- options[:as] ||= :select
285
- options[:association] ||= {}
286
-
287
- klass = [::Formula.association_class, options[:as]]
288
- klass << ::Formula.association_error_class if ::Formula.association_error_class.present? and error?(method)
289
-
290
- self.block(method, options) do
291
- @template.content_tag(::Formula.association_tag, :class => klass) do
292
- case options[:as]
293
- when :select then collection_select :"#{method}_id", collection, value, text,
294
- options[:association], options[:association].delete(:html) || {}
295
- end
296
- end
297
- end
298
- end
299
-
300
-
301
- private
302
-
303
-
304
- # Introspection on the column to determine how to render a method. The method is used to
305
- # identify a method type (if the method corresponds to a column)
306
- #
307
- # Returns:
308
- #
309
- # * :text - for columns of type 'text'
310
- # * :string - for columns of type 'string'
311
- # * :integer - for columns of type 'integer'
312
- # * :float - for columns of type 'float'
313
- # * :decimal - for columns of type 'decimal'
314
- # * :datetime - for columns of type 'datetime'
315
- # * :date - for columns of type 'date'
316
- # * :time - for columns of type 'time'
317
- # * nil - for unkown columns
318
-
319
- def type(method)
320
- if @object.respond_to?(:has_attribute?) && @object.has_attribute?(method)
321
- column = @object.column_for_attribute(method) if @object.respond_to?(:column_for_attribute)
322
- return column.type if column
323
- end
324
- end
325
-
326
-
327
- # Introspection on an association to determine if a method is a file. This
328
- # is determined by the methods ability to respond to file methods.
329
-
330
- def file?(method)
331
- @files ||= {}
332
- @files[method] ||= begin
333
- file = @object.send(method) if @object && @object.respond_to?(method)
334
- file && ::Formula.file.any? { |method| file.respond_to?(method) }
335
- end
336
- end
337
-
338
-
339
- # Introspection on the field and method to determine how to render a method. The method is
340
- # used to generate form element types.
341
- #
342
- # Returns:
343
- #
344
- # * :url - for columns containing 'url'
345
- # * :email - for columns containing 'email'
346
- # * :phone - for columns containing 'phone'
347
- # * :password - for columns containing 'password'
348
- # * :number - for integer, float or decimal columns
349
- # * :datetime - for datetime or timestamp columns
350
- # * :date - for date column
351
- # * :time - for time column
352
- # * :text - for time column
353
- # * :string - for all other cases
354
-
355
- def as(method)
356
-
357
- case "#{method}"
358
- when /url/ then return :url
359
- when /email/ then return :email
360
- when /phone/ then return :phone
361
- when /password/ then return :password
362
- end
363
-
364
- case type(method)
365
- when :string then return :string
366
- when :integer then return :number
367
- when :float then return :number
368
- when :decimal then return :number
369
- when :timestamp then return :datetime
370
- when :datetime then return :datetime
371
- when :date then return :date
372
- when :time then return :time
373
- when :text then return :text
374
- end
375
-
376
- return :file if file?(method)
377
-
378
- return ::Formula.default_as
379
-
380
- end
381
-
382
-
383
- # Generate error messages by combining all errors on an object into a comma seperated string
384
- # representation.
385
-
386
- def error(method)
387
- errors = @object.errors[method] if @object
388
- errors.to_sentence if errors.present?
389
- end
390
-
391
-
392
- # Identify if error message exists for a given method by checking for the presence of the object
393
- # followed by the presence of errors.
394
-
395
- def error?(method)
396
- @object.present? and @object.errors[method].present?
397
- end
398
-
399
-
400
- # Create an array from a string, a symbol, or an undefined value. The default is to return
401
- # the value and assume it has already is valid.
402
-
403
- def arrayorize(value)
404
- case value
405
- when nil then return []
406
- when String then value.to_s.split
407
- when Symbol then value.to_s.split
408
- else value
409
- end
410
- end
411
-
412
-
413
- public
414
-
415
-
416
- # Generates a wrapper around fields_form with :builder set to FormulaFormBuilder.
417
- #
418
- # Supports:
419
- #
420
- # * f.formula_fields_for(@user.company)
421
- # * f.fieldsula_for(@user.company)
422
- #
423
- # Equivalent:
424
- #
425
- # * f.fields_for(@user.company, :builder => Formula::FormulaFormBuilder))
426
- #
427
- # Usage:
428
- #
429
- # <% f.formula_fields_for(@user.company) do |company_f| %>
430
- # <%= company_f.input :url %>
431
- # <%= company_f.input :phone %>
432
- # <% end %>
433
-
434
- def formula_fields_for(record_or_name_or_array, *args, &block)
435
- options = args.extract_options!
436
- options[:builder] ||= self.class
437
- fields_for(record_or_name_or_array, *(args << options), &block)
438
- end
439
-
440
- alias :fieldsula_for :formula_fields_for
5
+ loader = Zeitwerk::Loader.for_gem
6
+ loader.setup
441
7
 
8
+ require 'formula/railtie' if defined?(Rails)
442
9
 
10
+ module Formula
11
+ # @return [Formula::Config]
12
+ def self.config
13
+ @config ||= Config.new
443
14
  end
444
15
 
445
- module FormulaFormHelper
446
- @@builder = ::Formula::FormulaFormBuilder
447
-
448
-
449
- # Generates a wrapper around form_for with :builder set to FormulaFormBuilder.
450
- #
451
- # Supports:
452
- #
453
- # * formula_form_for(@user)
454
- #
455
- # Equivalent:
456
- #
457
- # * form_for(@user, :builder => Formula::FormulaFormBuilder))
458
- #
459
- # Usage:
460
- #
461
- # <% formula_form_for(@user) do |f| %>
462
- # <%= f.input :email %>
463
- # <%= f.input :password %>
464
- # <% end %>
465
-
466
- def formula_form_for(record_or_name_or_array, *args, &proc)
467
- options = args.extract_options!
468
- options[:builder] ||= @@builder
469
- form_for(record_or_name_or_array, *(args << options), &proc)
470
- end
471
-
472
- alias :formula_for :formula_form_for
473
-
474
-
475
- # Generates a wrapper around fields_for with :builder set to FormulaFormBuilder.
476
- #
477
- # Supports:
478
- #
479
- # * f.formula_fields_for(@user.company)
480
- # * f.fieldsula_for(@user.company)
481
- #
482
- # Equivalent:
483
- #
484
- # * f.fields_for(@user.company, :builder => Formula::FormulaFormBuilder))
485
- #
486
- # Usage:
487
- #
488
- # <% f.formula_fields_for(@user.company) do |company_f| %>
489
- # <%= company_f.input :url %>
490
- # <%= company_f.input :phone %>
491
- # <% end %>
492
-
493
- def formula_fields_for(record_or_name_or_array, *args, &block)
494
- options = args.extract_options!
495
- options[:builder] ||= @@builder
496
- fields_for(record_or_name_or_array, *(args << options), &block)
497
- end
498
-
499
- alias :fieldsula_for :formula_fields_for
500
-
16
+ # @yield [Formula::Config]
17
+ def self.configure
18
+ yield config
501
19
  end
502
-
503
20
  end
metadata CHANGED
@@ -1,29 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: formula
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.1
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kevin Sylvestre
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-01-20 00:00:00.000000000 Z
11
+ date: 2024-10-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 3.0.0
19
+ version: '0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ">"
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 3.0.0
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: zeitwerk
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
27
41
  description: Formula is a Rails form generator that generates simple clean markup.
28
42
  The project aims to let users create semantically beautiful forms without introducing
29
43
  too much syntax. The goal is to make integrating advanced layout systems as simple
@@ -34,19 +48,26 @@ executables: []
34
48
  extensions: []
35
49
  extra_rdoc_files: []
36
50
  files:
37
- - LICENSE
38
- - README.rdoc
39
- - Rakefile
51
+ - Gemfile
52
+ - README.md
53
+ - bin/rubocop
54
+ - bin/test
40
55
  - lib/formula.rb
56
+ - lib/formula/config.rb
57
+ - lib/formula/form_builder.rb
58
+ - lib/formula/form_helper.rb
41
59
  - lib/formula/railtie.rb
42
60
  - lib/formula/version.rb
43
61
  - lib/generators/attached/templates/_form.html.erb
44
62
  - lib/generators/attached/templates/_form.html.haml
45
63
  - lib/generators/attached/templates/_form.html.slim
46
- homepage: http://github.com/ksylvest/formula
64
+ homepage: https://github.com/ksylvest/formula
47
65
  licenses: []
48
- metadata: {}
49
- post_install_message:
66
+ metadata:
67
+ homepage_uri: https://github.com/ksylvest/formula
68
+ changelog_uri: https://github.com/ksylvest/formula/releases
69
+ rubygems_mfa_required: 'true'
70
+ post_install_message:
50
71
  rdoc_options: []
51
72
  require_paths:
52
73
  - lib
@@ -54,16 +75,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
54
75
  requirements:
55
76
  - - ">="
56
77
  - !ruby/object:Gem::Version
57
- version: '0'
78
+ version: 3.2.0
58
79
  required_rubygems_version: !ruby/object:Gem::Requirement
59
80
  requirements:
60
81
  - - ">="
61
82
  - !ruby/object:Gem::Version
62
83
  version: '0'
63
84
  requirements: []
64
- rubyforge_project:
65
- rubygems_version: 2.4.5
66
- signing_key:
85
+ rubygems_version: 3.5.22
86
+ signing_key:
67
87
  specification_version: 4
68
88
  summary: A great way to simplify complex forms
69
89
  test_files: []
data/LICENSE DELETED
@@ -1,20 +0,0 @@
1
- Copyright (c) 2010 - 2012 Kevin Sylvestre
2
-
3
- Permission is hereby granted, free of charge, to any person obtaining
4
- a copy of this software and associated documentation files (the
5
- "Software"), to deal in the Software without restriction, including
6
- without limitation the rights to use, copy, modify, merge, publish,
7
- distribute, sublicense, and/or sell copies of the Software, and to
8
- permit persons to whom the Software is furnished to do so, subject to
9
- the following conditions:
10
-
11
- The above copyright notice and this permission notice shall be
12
- included in all copies or substantial portions of the Software.
13
-
14
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.