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 +5 -5
- data/lib/trenni/formatters.rb +2 -0
- data/lib/trenni/formatters/formatter.rb +52 -2
- data/lib/trenni/formatters/html/definition_list_form.rb +68 -38
- data/lib/trenni/formatters/html/form_formatter.rb +68 -61
- data/lib/trenni/formatters/html/label_form.rb +148 -0
- data/lib/trenni/formatters/html/option_select.rb +33 -30
- data/lib/trenni/formatters/html/radio_select.rb +25 -23
- data/lib/trenni/formatters/markdown.rb +7 -7
- data/lib/trenni/formatters/relative_time.rb +2 -0
- data/lib/trenni/formatters/truncated_text.rb +10 -8
- data/lib/trenni/formatters/version.rb +3 -1
- metadata +70 -52
- data/.gitignore +0 -17
- data/.rspec +0 -4
- data/.simplecov +0 -9
- data/.travis.yml +0 -14
- data/Gemfile +0 -12
- data/README.md +0 -77
- data/Rakefile +0 -8
- data/spec/trenni/formatters/form_formatter_spec.rb +0 -165
- data/spec/trenni/formatters/formatters_spec.rb +0 -57
- data/spec/trenni/formatters/html/option_select_spec.rb +0 -129
- data/spec/trenni/formatters/html/radio_select_spec.rb +0 -49
- data/spec/trenni/formatters/markdown_spec.rb +0 -34
- data/spec/trenni/formatters/relative_time_spec.rb +0 -38
- data/spec/trenni/formatters/truncated_text_spec.rb +0 -32
- data/trenni-formatters.gemspec +0 -33
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 6d6feaaa592cf7b7ee7470871eb4a169485b1141978ca45fc0bae655e76494fc
|
4
|
+
data.tar.gz: 78e3dec788ea4b9439d64a281f13b1dd8a4b4845d65340d595e4e8489437d93c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1ed0633355b499980dadbcb900a651020f9718d43bae54b8dbbe2f8e0c491d06dec7bb9cf63e4eab58f6aa5bdba84742a31f1824711c124e95c2a24f8930fd0f
|
7
|
+
data.tar.gz: 151c6d08577bfc6481591c3b2c0733083b5d847c02f633525c5225629dc717f45b532b6c957fb27450cda2787e88d939e63d1bc4e6c15fe15bc4e570f2b78c4b
|
data/lib/trenni/formatters.rb
CHANGED
@@ -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
|
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) {
|
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) {
|
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
|
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
|
-
|
118
|
-
builder.
|
119
|
-
builder.
|
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
|
-
|
122
|
-
builder
|
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,
|
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
|
-
|
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) {
|
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
|