trenni-formatters 2.6.0 → 2.11.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 492fe49e4a836ae2bfd931e505dc45744e50387a
4
- data.tar.gz: 789f8f795d95e35576f8841fbb43cf0ba7665bf6
2
+ SHA256:
3
+ metadata.gz: 6d6feaaa592cf7b7ee7470871eb4a169485b1141978ca45fc0bae655e76494fc
4
+ data.tar.gz: 78e3dec788ea4b9439d64a281f13b1dd8a4b4845d65340d595e4e8489437d93c
5
5
  SHA512:
6
- metadata.gz: 795ef68fecbeb39740a104bd80916a50f723fd16d94987bb9b4118264d6e0cc485cca9e8f82871343214f22fa80e4ea47fa438f54ee5137b51fd43a64aaa1a7d
7
- data.tar.gz: 5d6a141d9ae4ed0cce880ce4747ba9e4eab6e6e312c4343676345a9ea5dc4c2515d995b1e31a3f10d6944804c97f0e3aa7ba29598d2098f96a825ccdb2ea3236
6
+ metadata.gz: 1ed0633355b499980dadbcb900a651020f9718d43bae54b8dbbe2f8e0c491d06dec7bb9cf63e4eab58f6aa5bdba84742a31f1824711c124e95c2a24f8930fd0f
7
+ data.tar.gz: 151c6d08577bfc6481591c3b2c0733083b5d847c02f633525c5225629dc717f45b532b6c957fb27450cda2787e88d939e63d1bc4e6c15fe15bc4e570f2b78c4b
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright (c) 2012 Samuel G. D. Williams. <http://www.codeotaku.com>
2
4
  #
3
5
  # Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright, 2012, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
4
  #
3
5
  # Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -25,12 +27,60 @@ require 'mapping/descendants'
25
27
  module Trenni
26
28
  module Formatters
27
29
  class Formatter < Mapping::Model
28
- def initialize(options = {})
30
+ def self.for(object, **options)
31
+ self.new(object: object, **options)
32
+ end
33
+
34
+ def initialize(**options)
29
35
  @options = options
36
+
37
+ @object = nil
38
+ end
39
+
40
+ # The target object of the form.
41
+ def object
42
+ @object ||= @options[:object]
43
+ end
44
+
45
+ def nested_name(**options)
46
+ options[:nested_name] || @options[:nested_name]
47
+ end
48
+
49
+ # The name of the field, used for the name attribute of an input.
50
+ def name_for(**options)
51
+ name = options[:name] || options[:field]
52
+
53
+ if suffix = options[:suffix]
54
+ name = "#{name}#{suffix}"
55
+ end
56
+
57
+ if nested_name = self.nested_name(**options)
58
+ "#{nested_name}[#{name}]"
59
+ else
60
+ name
61
+ end
62
+ end
63
+
64
+ def nested_name_for(**options)
65
+ name_for(**options)
66
+ end
67
+
68
+ def nested(name, key = name, klass: self.class)
69
+ options = @options.dup
70
+ target = self.object.send(name)
71
+
72
+ options[:object] = target
73
+ options[:nested_name] = nested_name_for(name: key)
74
+
75
+ formatter = klass.new(**options)
76
+
77
+ return formatter unless block_given?
78
+
79
+ yield formatter
30
80
  end
31
81
 
32
82
  attr :options
33
-
83
+
34
84
  def format_unspecified(object, options)
35
85
  object.to_s
36
86
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright, 2012, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
4
  #
3
5
  # Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -30,104 +32,132 @@ module Trenni
30
32
  include FormFormatter
31
33
 
32
34
  # An input field (single line text).
33
- def input(options = {})
34
- options = @options.merge(options)
35
+ def input(**options)
36
+ options = @options.merge(**options)
35
37
 
36
38
  Builder.fragment do |builder|
37
39
  builder.inline(:dt) do
38
- builder.text title_for(options)
39
-
40
- if details = details_for(options)
41
- builder.inline(:small) { builder.text details }
42
- end
40
+ builder.text title_for(**options)
43
41
  end
44
42
 
45
43
  builder.inline(:dd) do
46
- builder.tag :input, input_attributes_for(options)
44
+ builder.tag :input, input_attributes_for(**options)
45
+
46
+ if details = details_for(**options)
47
+ builder.inline(:small, class: 'details') {builder.text details}
48
+ end
47
49
  end
48
50
  end
49
51
  end
50
52
 
51
53
  # An output field for the result of a computation.
52
- def output(options = {})
53
- options = @options.merge(options)
54
+ def output(**options)
55
+ options = @options.merge(**options)
54
56
 
55
57
  Builder.fragment do |builder|
56
- builder.inline(:dt) { builder.text title_for(options) }
58
+ builder.inline(:dt) {builder.text title_for(**options)}
57
59
 
58
60
  builder.inline(:dd) do
59
- builder.inline :output, output_attributes_for(options) do
60
- builder.text value_for(options)
61
+ builder.inline :output, output_attributes_for(**options) do
62
+ builder.text value_for(**options)
61
63
  end
62
64
  end
63
65
  end
64
66
  end
65
67
 
66
68
  # A textarea field (multi-line text).
67
- def textarea(options = {})
68
- options = @options.merge(options)
69
+ def textarea(**options)
70
+ options = @options.merge(**options)
69
71
 
70
72
  Builder.fragment do |builder|
71
73
  builder.tag(:dt) do
72
- builder.text title_for(options)
74
+ builder.text title_for(**options)
73
75
 
74
- if details = details_for(options)
75
- builder.inline(:small) { builder.text details }
76
+ if details = details_for(**options)
77
+ builder.inline(:small, class: 'details') {builder.text details}
76
78
  end
77
79
  end
78
80
 
79
81
  builder.inline(:dd) do
80
- builder.tag :textarea, textarea_attributes_for(options) do
81
- builder.text value_for(options)
82
+ builder.tag :textarea, textarea_attributes_for(**options) do
83
+ builder.text value_for(**options)
82
84
  end
83
85
  end
84
86
  end
85
87
  end
86
88
 
87
89
  # A checkbox field.
88
- def checkbox(options)
89
- options = @options.merge(options)
90
+ def checkbox(**options)
91
+ options = @options.merge(**options)
90
92
 
91
93
  Builder.fragment do |builder|
92
94
  builder.tag(:dd) do
93
- builder.tag :input, :type => :hidden, :name => name_for(options), :value => 'false'
95
+ builder.tag :input, :type => :hidden, :name => name_for(**options), :value => 'false'
96
+
94
97
  builder.inline(:label) do
95
- builder.tag :input, checkbox_attributes_for(options)
98
+ builder.tag :input, checkbox_attributes_for(**options)
96
99
  # We would like a little bit of whitespace between the checkbox and the title.
97
- builder.text " " + title_for(options)
100
+ builder.text " " + title_for(**options)
101
+ end
102
+
103
+ if details = details_for(**options)
104
+ builder.inline(:small, class: 'details') {builder.text details}
98
105
  end
99
106
  end
100
107
  end
101
108
  end
102
109
 
103
110
  # A submission button
104
- def submit(options = {})
105
- options = @options.merge(options)
106
- options[:title] ||= submit_title_for(options)
111
+ def submit(**options)
112
+ options = @options.merge(**options)
113
+ options[:title] ||= submit_title_for(**options)
107
114
 
108
115
  Builder.fragment do |builder|
109
- builder.tag :input, submit_attributes_for(options)
116
+ builder.tag :input, submit_attributes_for(**options)
110
117
  end
111
118
  end
112
-
113
- def element(klass, options = {}, &block)
114
- options = @options.merge(options)
119
+
120
+ def fieldset(**options, &block)
121
+ options = @options.merge(**options)
115
122
  buffer = Trenni::Template.buffer(block.binding)
116
123
 
117
- buffer << Builder.fragment do |builder|
118
- builder.inline(:dt) do
119
- builder.text title_for(options)
124
+ Builder.fragment(buffer) do |builder|
125
+ builder.tag('fieldset') do
126
+ builder.inline('legend') do
127
+ builder.text title_for(**options)
128
+ end
120
129
 
121
- if details = details_for(options)
122
- builder.inline(:small) { builder.text details }
130
+ builder.tag('dl') do
131
+ yield(builder)
123
132
  end
124
133
  end
134
+ end
135
+ end
136
+
137
+ def element(klass, **options, &block)
138
+ options = @options.merge(**options)
139
+ buffer = Trenni::Template.buffer(block.binding)
140
+
141
+ buffer << Builder.fragment do |builder|
142
+ builder.inline(:dt) do
143
+ builder.text title_for(**options)
144
+ end
125
145
 
126
146
  builder.tag(:dd) do
127
- klass.call(self, options, builder, &block)
147
+ klass.call(self, builder, **options, &block)
148
+
149
+ if details = details_for(**options)
150
+ builder.inline(:small, class: 'details') {builder.text details}
151
+ end
128
152
  end
129
153
  end
130
154
  end
155
+
156
+ def fieldset(**options, &block)
157
+ super do |builder|
158
+ builder.tag(:dl, &block)
159
+ end
160
+ end
131
161
  end
132
162
  end
133
163
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright, 2012, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
4
  #
3
5
  # Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -24,99 +26,89 @@ module Trenni
24
26
  module Formatters
25
27
  module HTML
26
28
  module FormFormatter
27
- # The target object of the form.
28
- def object
29
- @object ||= @options[:object]
30
- end
31
-
32
29
  # Return true if the object is begin created or false if it is being updated.
33
30
  def new_record?
34
31
  object.new_record?
35
32
  end
36
33
 
37
34
  # Any additional details relating to a field (e.g. explanation text)
38
- def details_for(options)
35
+ def details_for(**options)
39
36
  options[:details]
40
37
  end
41
38
 
42
- # The name of the field, used for the name attribute of an input.
43
- def name_for(options)
44
- options[:name] || options[:field]
45
- end
46
-
47
- def field_for(options)
39
+ def field_for(**options)
48
40
  options[:field]
49
41
  end
50
42
 
51
43
  # A title is a text string that will be displayed next to or on top of the control to describe it or its value:
52
- def title_for(options)
44
+ def title_for(**options)
53
45
  if title = options[:title]
54
46
  return title
55
47
  end
56
48
 
57
49
  # Generate a title from a field name:
58
- if field_name = field_for(options)
50
+ if field_name = field_for(**options)
59
51
  # Remove postfix "_id" or "_ids":
60
52
  return Strings::to_title(field_name.to_s.sub(/_ids?/, ''))
61
53
  end
62
54
  end
63
55
 
64
- def object_value_for(options)
65
- if object = options[:object] and field = field_for(options)
56
+ def object_value_for(**options)
57
+ if object = options[:object] and field = field_for(**options)
66
58
  object.send(field)
67
59
  end
68
60
  end
69
61
 
70
- def raw_value_for(options)
71
- value = options.fetch(:value) { object_value_for(options) }
62
+ def raw_value_for(**options)
63
+ value = options.fetch(:value) {object_value_for(**options)}
72
64
 
73
65
  # Allow to specify a default value if the value given, usually from an object, is nil.
74
66
  value || options[:default]
75
67
  end
76
68
 
77
69
  # The value of the field.
78
- def value_for(options)
79
- if value = raw_value_for(options)
70
+ def value_for(**options)
71
+ if value = raw_value_for(**options)
80
72
  self.format(value, options)
81
73
  end
82
74
  end
83
75
 
84
- def pattern_for(options)
76
+ def pattern_for(**options)
85
77
  options[:pattern]
86
78
  end
87
79
 
88
- def placeholder_for(options)
80
+ def placeholder_for(**options)
89
81
  options[:placeholder]
90
82
  end
91
83
 
92
- def input_attributes_for(options)
84
+ def input_attributes_for(**options)
93
85
  attributes = {
94
86
  :type => options[:type],
95
- :name => name_for(options),
87
+ :name => name_for(**options),
96
88
  :id => options[:id],
97
89
  :class => options[:class],
98
- :value => value_for(options),
90
+ :value => value_for(**options),
99
91
  :required => options[:required],
100
92
  :disabled => options[:disabled],
101
93
  :readonly => options[:readonly],
102
- :pattern => pattern_for(options),
103
- :placeholder => placeholder_for(options),
94
+ :pattern => pattern_for(**options),
95
+ :placeholder => placeholder_for(**options),
104
96
  # for <input type="range|number">
105
- :min => options[:min],
106
- :max => options[:max],
97
+ :min => options[:minimum] || options[:min],
98
+ :max => options[:maximum] || options[:max],
107
99
  :step => options[:step],
108
100
  # for <input type="text">
109
- :minlength => options[:minlength],
110
- :maxlength => options[:maxlength],
101
+ :minlength => options[:minimum] || options[:minlength],
102
+ :maxlength => options[:maximum] || options[:maxlength],
111
103
  :data => options[:data],
112
104
  }
113
105
 
114
106
  return attributes
115
107
  end
116
108
 
117
- def output_attributes_for(options)
109
+ def output_attributes_for(**options)
118
110
  attributes = {
119
- :name => name_for(options),
111
+ :name => name_for(**options),
120
112
  :id => options[:id],
121
113
  :class => options[:class],
122
114
  :for => options[:for],
@@ -127,30 +119,30 @@ module Trenni
127
119
  return attributes
128
120
  end
129
121
 
130
- def textarea_attributes_for(options)
122
+ def textarea_attributes_for(**options)
131
123
  return {
132
- :name => name_for(options),
124
+ :name => name_for(**options),
133
125
  :id => options[:id],
134
126
  :class => options[:class],
135
127
  :required => options[:required],
136
128
  :disabled => options[:disabled],
137
129
  :readonly => options[:readonly],
138
- :pattern => pattern_for(options),
139
- :placeholder => placeholder_for(options),
130
+ :pattern => pattern_for(**options),
131
+ :placeholder => placeholder_for(**options),
140
132
  :minlength => options[:minlength],
141
133
  :maxlength => options[:maxlength],
142
134
  :data => options[:data],
143
135
  }
144
136
  end
145
137
 
146
- def checkbox_attributes_for(options)
138
+ def checkbox_attributes_for(**options)
147
139
  return {
148
140
  :type => options[:type] || 'checkbox',
149
141
  :id => options[:id],
150
142
  :class => options[:class],
151
- :name => name_for(options),
143
+ :name => name_for(**options),
152
144
  :value => 'true',
153
- :checked => raw_value_for(options),
145
+ :checked => raw_value_for(**options),
154
146
  :required => options[:required],
155
147
  :disabled => options[:disabled],
156
148
  :readonly => options[:readonly],
@@ -158,71 +150,86 @@ module Trenni
158
150
  }
159
151
  end
160
152
 
161
- def submit_attributes_for(options)
153
+ def submit_attributes_for(**options)
162
154
  return {
163
155
  :type => options[:type] || 'submit',
164
- :name => name_for(options),
156
+ :name => name_for(**options),
165
157
  :id => options[:id],
166
158
  :class => options[:class],
167
159
  :disabled => options[:disabled],
168
- :value => title_for(options),
160
+ :value => title_for(**options),
169
161
  :data => options[:data],
170
162
  }
171
163
  end
172
164
 
173
- def submit_title_for(options)
174
- title_for(options) || (new_record? ? 'Create' : 'Update')
165
+ def submit_title_for(**options)
166
+ title_for(**options) || (new_record? ? 'Create' : 'Update')
175
167
  end
176
168
 
177
- def hidden_attributes_for(options)
169
+ def hidden_attributes_for(**options)
178
170
  return {
179
171
  :type => options[:type] || 'hidden',
180
172
  :id => options[:id],
181
173
  :class => options[:class],
182
- :name => name_for(options),
183
- :value => value_for(options),
174
+ :name => name_for(**options),
175
+ :value => value_for(**options),
184
176
  :data => options[:data],
185
177
  }
186
178
  end
187
179
 
188
180
  # A hidden field.
189
- def hidden(options = {})
190
- options = @options.merge(options)
181
+ def hidden(**options)
182
+ options = @options.merge(**options)
191
183
 
192
184
  Builder.fragment do |builder|
193
- builder.tag :input, hidden_attributes_for(options)
185
+ builder.tag :input, hidden_attributes_for(**options)
194
186
  end
195
187
  end
196
188
 
197
- def button_attributes_for(options)
189
+ def button_attributes_for(**options)
198
190
  return {
199
191
  :type => options[:type] || 'submit',
200
- :name => name_for(options),
192
+ :name => name_for(**options),
201
193
  :id => options[:id],
202
194
  :class => options[:class],
203
195
  :disabled => options[:disabled],
204
- :value => value_for(options),
196
+ :value => value_for(**options),
205
197
  :data => options[:data],
206
198
  }
207
199
  end
208
200
 
209
- def button_title_for(options)
201
+ def button_title_for(**options)
210
202
  type = options.fetch(:type, 'submit').to_sym
211
203
 
212
204
  if type == :submit
213
- submit_title_for(options)
205
+ submit_title_for(**options)
214
206
  else
215
- title_for(options) || Strings::to_title(type.to_s)
207
+ title_for(**options) || Strings::to_title(type.to_s)
216
208
  end
217
209
  end
218
210
 
219
211
  # A hidden field.
220
- def button(options = {})
221
- options = @options.merge(options)
212
+ def button(**options)
213
+ options = @options.merge(**options)
222
214
 
223
215
  Builder.fragment do |builder|
224
- builder.inline :button, button_attributes_for(options) do
225
- builder.text button_title_for(options)
216
+ builder.inline :button, button_attributes_for(**options) do
217
+ builder.text button_title_for(**options)
218
+ end
219
+ end
220
+ end
221
+
222
+ def fieldset(**options, &block)
223
+ options = @options.merge(**options)
224
+ buffer = Trenni::Template.buffer(block.binding)
225
+
226
+ Builder.fragment(buffer) do |builder|
227
+ builder.tag('fieldset') do
228
+ builder.inline('legend') do
229
+ builder.text title_for(**options)
230
+ end
231
+
232
+ yield(builder)
226
233
  end
227
234
  end
228
235
  end