xrb-formatters 0.1.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 +7 -0
- checksums.yaml.gz.sig +1 -0
- data/lib/xrb/formatters/formatter.rb +100 -0
- data/lib/xrb/formatters/html/accept_checkbox.rb +48 -0
- data/lib/xrb/formatters/html/definition_list_form.rb +131 -0
- data/lib/xrb/formatters/html/form_formatter.rb +222 -0
- data/lib/xrb/formatters/html/label_form.rb +129 -0
- data/lib/xrb/formatters/html/option_select.rb +131 -0
- data/lib/xrb/formatters/html/radio_select.rb +104 -0
- data/lib/xrb/formatters/markdown.rb +23 -0
- data/lib/xrb/formatters/relative_time.rb +26 -0
- data/lib/xrb/formatters/truncated_text.rb +39 -0
- data/lib/xrb/formatters/version.rb +10 -0
- data/lib/xrb/formatters.rb +6 -0
- data/license.md +21 -0
- data/readme.md +63 -0
- data.tar.gz.sig +0 -0
- metadata +115 -0
- metadata.gz.sig +0 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 7c7d3c4882fa5d1766266d11516647193f2edb6a414aa3901cd2280da98b219e
|
4
|
+
data.tar.gz: 82609011a18a1ebf7848c8b92654b75ed9721d2f27640b2687fdb4d89e03cec7
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: af17a0f56086a82b143d69d5b02ec070126a8182bd1a6ecb8ce628d10b6063ac6a689e15d69c059e298128202165c9b15ed382ce27f7147a387bb5eb7933bf99
|
7
|
+
data.tar.gz: 836b7440bf8623edf869c929172c32c4613a89c6ff18b68aff2a3f26fc68bd62da3e2f0d0a123940f6bf28051b3d1aac54f6d0083988b01e36887041ba368e9d
|
checksums.yaml.gz.sig
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
<���3S-q�Aa�G�"hsiǯ���S����g^^]C_�1���v�������XT����TZܼXc��������c�Hr��'~&� $aK�廰��L���t������!y����Г<�O�b�_lgu�i�NX�S�n�=���Eh<�Lv�8x`V��{gP����5
|
@@ -0,0 +1,100 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Released under the MIT License.
|
4
|
+
# Copyright, 2012-2024, by Samuel Williams.
|
5
|
+
|
6
|
+
require 'xrb/strings'
|
7
|
+
require 'mapping/model'
|
8
|
+
require 'mapping/descendants'
|
9
|
+
|
10
|
+
module XRB
|
11
|
+
module Formatters
|
12
|
+
class Formatter < Mapping::Model
|
13
|
+
def self.for(object, **options)
|
14
|
+
self.new(object: object, **options)
|
15
|
+
end
|
16
|
+
|
17
|
+
def initialize(**options)
|
18
|
+
@options = options
|
19
|
+
|
20
|
+
@object = nil
|
21
|
+
end
|
22
|
+
|
23
|
+
# The target object of the form.
|
24
|
+
def object
|
25
|
+
@object ||= @options[:object]
|
26
|
+
end
|
27
|
+
|
28
|
+
def nested_name(**options)
|
29
|
+
options[:nested_name] || @options[:nested_name]
|
30
|
+
end
|
31
|
+
|
32
|
+
# The name of the field, used for the name attribute of an input.
|
33
|
+
def name_for(**options)
|
34
|
+
name = options[:name] || options[:field]
|
35
|
+
|
36
|
+
if suffix = options[:suffix]
|
37
|
+
name = "#{name}#{suffix}"
|
38
|
+
end
|
39
|
+
|
40
|
+
if nested_name = self.nested_name(**options)
|
41
|
+
"#{nested_name}[#{name}]"
|
42
|
+
else
|
43
|
+
name
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def nested_name_for(**options)
|
48
|
+
name_for(**options)
|
49
|
+
end
|
50
|
+
|
51
|
+
def nested(name, key = name, klass: self.class)
|
52
|
+
options = @options.dup
|
53
|
+
target = self.object.send(name)
|
54
|
+
|
55
|
+
options[:object] = target
|
56
|
+
options[:nested_name] = nested_name_for(name: key)
|
57
|
+
|
58
|
+
formatter = klass.new(**options)
|
59
|
+
|
60
|
+
return formatter unless block_given?
|
61
|
+
|
62
|
+
yield formatter
|
63
|
+
end
|
64
|
+
|
65
|
+
attr :options
|
66
|
+
|
67
|
+
def format_unspecified(object, **options)
|
68
|
+
object.to_s
|
69
|
+
end
|
70
|
+
|
71
|
+
def format(object, **options)
|
72
|
+
method_name = self.method_for_mapping(object)
|
73
|
+
|
74
|
+
if self.respond_to?(method_name)
|
75
|
+
self.send(method_name, object, **options)
|
76
|
+
else
|
77
|
+
format_unspecified(object, **options)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
alias text format
|
82
|
+
|
83
|
+
def [] key
|
84
|
+
@options[key]
|
85
|
+
end
|
86
|
+
|
87
|
+
map(String) do |object, **options|
|
88
|
+
object
|
89
|
+
end
|
90
|
+
|
91
|
+
map(NilClass) do |object, **options|
|
92
|
+
options[:blank] || @options[:blank] || ""
|
93
|
+
end
|
94
|
+
|
95
|
+
map(TrueClass, FalseClass, *Mapping.lookup_descendants(Numeric)) do |object, **options|
|
96
|
+
object.to_s
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Released under the MIT License.
|
4
|
+
# Copyright, 2020-2024, by Samuel Williams.
|
5
|
+
|
6
|
+
require 'xrb/builder'
|
7
|
+
|
8
|
+
module XRB
|
9
|
+
module Formatters
|
10
|
+
module HTML
|
11
|
+
class AcceptCheckbox
|
12
|
+
def self.call(formatter, builder, **options, &block)
|
13
|
+
instance = self.new(formatter, builder, **options)
|
14
|
+
|
15
|
+
instance.call(&block)
|
16
|
+
end
|
17
|
+
|
18
|
+
def initialize(formatter, builder, **options)
|
19
|
+
@formatter = formatter
|
20
|
+
@builder = builder
|
21
|
+
@options = options
|
22
|
+
end
|
23
|
+
|
24
|
+
def name_for(**options)
|
25
|
+
@formatter.name_for(**options)
|
26
|
+
end
|
27
|
+
|
28
|
+
def checkbox_attributes_for(**options)
|
29
|
+
@formatter.checkbox_attributes_for(**options)
|
30
|
+
end
|
31
|
+
|
32
|
+
def call(&block)
|
33
|
+
Builder.fragment(@builder) do |builder|
|
34
|
+
builder.inline('span') do
|
35
|
+
builder.inline :input, type: :hidden, name: name_for(**@options), value: 'false'
|
36
|
+
|
37
|
+
builder.tag :input, checkbox_attributes_for(**@options)
|
38
|
+
|
39
|
+
builder.text " "
|
40
|
+
|
41
|
+
builder.capture(self, &block)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,131 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Released under the MIT License.
|
4
|
+
# Copyright, 2012-2024, by Samuel Williams.
|
5
|
+
|
6
|
+
require 'xrb/builder'
|
7
|
+
require 'xrb/template'
|
8
|
+
|
9
|
+
require_relative 'form_formatter'
|
10
|
+
|
11
|
+
module XRB
|
12
|
+
module Formatters
|
13
|
+
module HTML
|
14
|
+
module DefinitionListForm
|
15
|
+
include FormFormatter
|
16
|
+
|
17
|
+
# An input field (single line text).
|
18
|
+
def input(**options)
|
19
|
+
options = @options.merge(**options)
|
20
|
+
|
21
|
+
Builder.fragment do |builder|
|
22
|
+
builder.inline(:dt) do
|
23
|
+
builder.text title_for(**options)
|
24
|
+
end
|
25
|
+
|
26
|
+
builder.inline(:dd) do
|
27
|
+
builder.tag :input, input_attributes_for(**options)
|
28
|
+
|
29
|
+
if details = details_for(**options)
|
30
|
+
builder.inline(:small, class: 'details') {builder.text details}
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# An output field for the result of a computation.
|
37
|
+
def output(**options)
|
38
|
+
options = @options.merge(**options)
|
39
|
+
|
40
|
+
Builder.fragment do |builder|
|
41
|
+
builder.inline(:dt) {builder.text title_for(**options)}
|
42
|
+
|
43
|
+
builder.inline(:dd) do
|
44
|
+
builder.inline :output, output_attributes_for(**options) do
|
45
|
+
builder.text value_for(**options)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# A textarea field (multi-line text).
|
52
|
+
def textarea(**options)
|
53
|
+
options = @options.merge(**options)
|
54
|
+
|
55
|
+
Builder.fragment do |builder|
|
56
|
+
builder.tag(:dt) do
|
57
|
+
builder.text title_for(**options)
|
58
|
+
|
59
|
+
if details = details_for(**options)
|
60
|
+
builder.inline(:small, class: 'details') {builder.text details}
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
builder.inline(:dd) do
|
65
|
+
builder.tag :textarea, textarea_attributes_for(**options) do
|
66
|
+
builder.text value_for(**options)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
# A checkbox field.
|
73
|
+
def checkbox(**options)
|
74
|
+
options = @options.merge(**options)
|
75
|
+
|
76
|
+
Builder.fragment do |builder|
|
77
|
+
builder.tag(:dd) do
|
78
|
+
builder.tag :input, :type => :hidden, :name => name_for(**options), :value => 'false'
|
79
|
+
|
80
|
+
builder.inline(:label) do
|
81
|
+
builder.tag :input, checkbox_attributes_for(**options)
|
82
|
+
# We would like a little bit of whitespace between the checkbox and the title.
|
83
|
+
builder.text " " + title_for(**options)
|
84
|
+
end
|
85
|
+
|
86
|
+
if details = details_for(**options)
|
87
|
+
builder.inline(:small, class: 'details') {builder.text details}
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
# A submission button
|
94
|
+
def submit(**options)
|
95
|
+
options = @options.merge(**options)
|
96
|
+
options[:title] ||= submit_title_for(**options)
|
97
|
+
|
98
|
+
Builder.fragment do |builder|
|
99
|
+
builder.tag :input, submit_attributes_for(**options)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def element(klass, **options, &block)
|
104
|
+
options = @options.merge(**options)
|
105
|
+
|
106
|
+
Builder.fragment(block&.binding) do |builder|
|
107
|
+
builder.inline(:dt) do
|
108
|
+
builder.text title_for(**options)
|
109
|
+
end
|
110
|
+
|
111
|
+
builder.tag(:dd) do
|
112
|
+
klass.call(self, builder, **options, &block)
|
113
|
+
|
114
|
+
if details = details_for(**options)
|
115
|
+
builder.inline(:small, class: 'details') {builder.text details}
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
def fieldset(**options, &block)
|
122
|
+
super do |builder|
|
123
|
+
builder.tag(:dl) do
|
124
|
+
yield(builder)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
@@ -0,0 +1,222 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Released under the MIT License.
|
4
|
+
# Copyright, 2014-2024, by Samuel Williams.
|
5
|
+
|
6
|
+
require 'xrb/builder'
|
7
|
+
|
8
|
+
module XRB
|
9
|
+
module Formatters
|
10
|
+
module HTML
|
11
|
+
module FormFormatter
|
12
|
+
# Return true if the object is begin created or false if it is being updated.
|
13
|
+
def new_record?
|
14
|
+
object.new_record?
|
15
|
+
end
|
16
|
+
|
17
|
+
# Any additional details relating to a field (e.g. explanation text)
|
18
|
+
def details_for(**options)
|
19
|
+
options[:details]
|
20
|
+
end
|
21
|
+
|
22
|
+
def field_for(**options)
|
23
|
+
options[:field]
|
24
|
+
end
|
25
|
+
|
26
|
+
# A title is a text string that will be displayed next to or on top of the control to describe it or its value:
|
27
|
+
def title_for(**options)
|
28
|
+
if title = options[:title]
|
29
|
+
return title
|
30
|
+
end
|
31
|
+
|
32
|
+
# Generate a title from a field name:
|
33
|
+
if field_name = field_for(**options)
|
34
|
+
# Remove postfix "_id" or "_ids":
|
35
|
+
return Strings::to_title(field_name.to_s.sub(/_ids?/, ''))
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def object_value_for(**options)
|
40
|
+
if object = options[:object] and field = field_for(**options)
|
41
|
+
object.send(field)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def raw_value_for(**options)
|
46
|
+
value = options.fetch(:value) {object_value_for(**options)}
|
47
|
+
|
48
|
+
# Allow to specify a default value if the value given, usually from an object, is nil.
|
49
|
+
value || options[:default]
|
50
|
+
end
|
51
|
+
|
52
|
+
# The value of the field.
|
53
|
+
def value_for(**options)
|
54
|
+
if value = raw_value_for(**options)
|
55
|
+
self.format(value, **options)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def pattern_for(**options)
|
60
|
+
options[:pattern]
|
61
|
+
end
|
62
|
+
|
63
|
+
def placeholder_for(**options)
|
64
|
+
options[:placeholder]
|
65
|
+
end
|
66
|
+
|
67
|
+
def input_attributes_for(**options)
|
68
|
+
attributes = {
|
69
|
+
:type => options[:type],
|
70
|
+
:name => name_for(**options),
|
71
|
+
:id => options[:id],
|
72
|
+
:class => options[:class],
|
73
|
+
:value => value_for(**options),
|
74
|
+
:required => options[:required],
|
75
|
+
:disabled => options[:disabled],
|
76
|
+
:readonly => options[:readonly],
|
77
|
+
:pattern => pattern_for(**options),
|
78
|
+
:placeholder => placeholder_for(**options),
|
79
|
+
# for <input type="range|number">
|
80
|
+
:min => options[:minimum] || options[:min],
|
81
|
+
:max => options[:maximum] || options[:max],
|
82
|
+
:step => options[:step],
|
83
|
+
# for <input type="text">
|
84
|
+
:minlength => options[:minimum] || options[:minlength],
|
85
|
+
:maxlength => options[:maximum] || options[:maxlength],
|
86
|
+
:data => options[:data],
|
87
|
+
}
|
88
|
+
|
89
|
+
return attributes
|
90
|
+
end
|
91
|
+
|
92
|
+
def output_attributes_for(**options)
|
93
|
+
attributes = {
|
94
|
+
:name => name_for(**options),
|
95
|
+
:id => options[:id],
|
96
|
+
:class => options[:class],
|
97
|
+
:for => options[:for],
|
98
|
+
:form => options[:form],
|
99
|
+
:data => options[:data],
|
100
|
+
}
|
101
|
+
|
102
|
+
return attributes
|
103
|
+
end
|
104
|
+
|
105
|
+
def textarea_attributes_for(**options)
|
106
|
+
return {
|
107
|
+
:name => name_for(**options),
|
108
|
+
:id => options[:id],
|
109
|
+
:class => options[:class],
|
110
|
+
:required => options[:required],
|
111
|
+
:disabled => options[:disabled],
|
112
|
+
:readonly => options[:readonly],
|
113
|
+
:pattern => pattern_for(**options),
|
114
|
+
:placeholder => placeholder_for(**options),
|
115
|
+
:minlength => options[:minlength],
|
116
|
+
:maxlength => options[:maxlength],
|
117
|
+
:data => options[:data],
|
118
|
+
}
|
119
|
+
end
|
120
|
+
|
121
|
+
def checkbox_attributes_for(**options)
|
122
|
+
return {
|
123
|
+
:type => options[:type] || 'checkbox',
|
124
|
+
:id => options[:id],
|
125
|
+
:class => options[:class],
|
126
|
+
:name => name_for(**options),
|
127
|
+
:value => 'true',
|
128
|
+
:checked => raw_value_for(**options),
|
129
|
+
:required => options[:required],
|
130
|
+
:disabled => options[:disabled],
|
131
|
+
:readonly => options[:readonly],
|
132
|
+
:data => options[:data],
|
133
|
+
}
|
134
|
+
end
|
135
|
+
|
136
|
+
def submit_attributes_for(**options)
|
137
|
+
return {
|
138
|
+
:type => options[:type] || 'submit',
|
139
|
+
:name => name_for(**options),
|
140
|
+
:id => options[:id],
|
141
|
+
:class => options[:class],
|
142
|
+
:disabled => options[:disabled],
|
143
|
+
:value => title_for(**options),
|
144
|
+
:data => options[:data],
|
145
|
+
}
|
146
|
+
end
|
147
|
+
|
148
|
+
def submit_title_for(**options)
|
149
|
+
title_for(**options) || (new_record? ? 'Create' : 'Update')
|
150
|
+
end
|
151
|
+
|
152
|
+
def hidden_attributes_for(**options)
|
153
|
+
return {
|
154
|
+
:type => options[:type] || 'hidden',
|
155
|
+
:id => options[:id],
|
156
|
+
:class => options[:class],
|
157
|
+
:name => name_for(**options),
|
158
|
+
:value => value_for(**options),
|
159
|
+
:data => options[:data],
|
160
|
+
}
|
161
|
+
end
|
162
|
+
|
163
|
+
# A hidden field.
|
164
|
+
def hidden(**options)
|
165
|
+
options = @options.merge(**options)
|
166
|
+
|
167
|
+
Builder.fragment do |builder|
|
168
|
+
builder.tag :input, hidden_attributes_for(**options)
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
def button_attributes_for(**options)
|
173
|
+
return {
|
174
|
+
:type => options[:type] || 'submit',
|
175
|
+
:name => name_for(**options),
|
176
|
+
:id => options[:id],
|
177
|
+
:class => options[:class],
|
178
|
+
:disabled => options[:disabled],
|
179
|
+
:value => value_for(**options),
|
180
|
+
:data => options[:data],
|
181
|
+
}
|
182
|
+
end
|
183
|
+
|
184
|
+
def button_title_for(**options)
|
185
|
+
type = options.fetch(:type, 'submit').to_sym
|
186
|
+
|
187
|
+
if type == :submit
|
188
|
+
submit_title_for(**options)
|
189
|
+
else
|
190
|
+
title_for(**options) || Strings::to_title(type.to_s)
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
# A hidden field.
|
195
|
+
def button(**options)
|
196
|
+
options = @options.merge(**options)
|
197
|
+
|
198
|
+
Builder.fragment do |builder|
|
199
|
+
builder.inline :button, button_attributes_for(**options) do
|
200
|
+
builder.text button_title_for(**options)
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
def fieldset(**options, &block)
|
206
|
+
options = @options.merge(**options)
|
207
|
+
buffer = XRB::Template.buffer(block.binding)
|
208
|
+
|
209
|
+
Builder.fragment(buffer) do |builder|
|
210
|
+
builder.tag('fieldset') do
|
211
|
+
builder.inline('legend') do
|
212
|
+
builder.text title_for(**options)
|
213
|
+
end
|
214
|
+
|
215
|
+
yield(builder)
|
216
|
+
end
|
217
|
+
end
|
218
|
+
end
|
219
|
+
end
|
220
|
+
end
|
221
|
+
end
|
222
|
+
end
|
@@ -0,0 +1,129 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Released under the MIT License.
|
4
|
+
# Copyright, 2020-2024, by Samuel Williams.
|
5
|
+
|
6
|
+
require 'xrb/builder'
|
7
|
+
require 'xrb/template'
|
8
|
+
|
9
|
+
require_relative 'form_formatter'
|
10
|
+
|
11
|
+
module XRB
|
12
|
+
module Formatters
|
13
|
+
module HTML
|
14
|
+
module LabelForm
|
15
|
+
include FormFormatter
|
16
|
+
|
17
|
+
# An input field (single line text).
|
18
|
+
def input(**options)
|
19
|
+
options = @options.merge(**options)
|
20
|
+
|
21
|
+
Builder.fragment do |builder|
|
22
|
+
builder.inline(:label) do
|
23
|
+
builder.inline(:span) do
|
24
|
+
builder.text title_for(**options)
|
25
|
+
|
26
|
+
if details = details_for(**options)
|
27
|
+
builder.inline(:small) {builder.text details}
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
builder.inline :input, input_attributes_for(**options)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# An output field for the result of a computation.
|
37
|
+
def output(**options)
|
38
|
+
options = @options.merge(**options)
|
39
|
+
|
40
|
+
builder.inline(:label) do
|
41
|
+
builder.inline(:span) do
|
42
|
+
builder.text title_for(**options)
|
43
|
+
|
44
|
+
if details = details_for(**options)
|
45
|
+
builder.inline(:small) {builder.text details}
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
builder.inline :output, output_attributes_for(**options) do
|
50
|
+
builder.text value_for(**options)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# A textarea field (multi-line text).
|
56
|
+
def textarea(**options)
|
57
|
+
options = @options.merge(**options)
|
58
|
+
|
59
|
+
Builder.fragment do |builder|
|
60
|
+
builder.inline(:label) do
|
61
|
+
builder.inline(:span) do
|
62
|
+
builder.text title_for(**options)
|
63
|
+
|
64
|
+
if details = details_for(**options)
|
65
|
+
builder.inline(:small) {builder.text details}
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
builder.tag :textarea, textarea_attributes_for(**options) do
|
70
|
+
builder.text value_for(**options)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
# A checkbox field.
|
77
|
+
def checkbox(**options)
|
78
|
+
options = @options.merge(**options)
|
79
|
+
|
80
|
+
Builder.fragment do |builder|
|
81
|
+
builder.inline(:label) do
|
82
|
+
builder.inline :input, :type => :hidden, :name => name_for(**options), :value => 'false'
|
83
|
+
|
84
|
+
builder.inline(:span) do
|
85
|
+
if details = details_for(**options)
|
86
|
+
builder.inline(:small) {builder.text details}
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
builder.tag :input, checkbox_attributes_for(**options)
|
91
|
+
|
92
|
+
# We would like a little bit of whitespace between the checkbox and the title:
|
93
|
+
builder.text " " + title_for(**options)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
# A submission button
|
99
|
+
def submit(**options)
|
100
|
+
options = @options.merge(**options)
|
101
|
+
options[:title] ||= submit_title_for(**options)
|
102
|
+
|
103
|
+
Builder.fragment do |builder|
|
104
|
+
builder.inline :input, submit_attributes_for(**options)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def element(klass, **options, &block)
|
109
|
+
options = @options.merge(**options)
|
110
|
+
buffer = XRB::Template.buffer(block.binding)
|
111
|
+
|
112
|
+
Builder.fragment(buffer) do |builder|
|
113
|
+
builder.inline(:label) do
|
114
|
+
builder.inline(:span) do
|
115
|
+
builder.text title_for(**options)
|
116
|
+
|
117
|
+
if details = details_for(**options)
|
118
|
+
builder.inline(:small) {builder.text details}
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
klass.call(self, builder, **options, &block)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
@@ -0,0 +1,131 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Released under the MIT License.
|
4
|
+
# Copyright, 2012-2024, by Samuel Williams.
|
5
|
+
|
6
|
+
require 'xrb/builder'
|
7
|
+
|
8
|
+
module XRB
|
9
|
+
module Formatters
|
10
|
+
module HTML
|
11
|
+
# Standard drop-down select box:
|
12
|
+
class OptionSelect
|
13
|
+
def self.call(formatter, builder, **options, &block)
|
14
|
+
instance = self.new(formatter, builder, **options)
|
15
|
+
|
16
|
+
instance.call(&block)
|
17
|
+
end
|
18
|
+
|
19
|
+
def initialize(formatter, builder, **options)
|
20
|
+
@formatter = formatter
|
21
|
+
@builder = builder
|
22
|
+
@options = options
|
23
|
+
end
|
24
|
+
|
25
|
+
def name_for(**options)
|
26
|
+
if name = @formatter.name_for(**options)
|
27
|
+
if options[:multiple]
|
28
|
+
name = "#{name}[]"
|
29
|
+
end
|
30
|
+
|
31
|
+
return name
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def raw_value_for(**options)
|
36
|
+
@formatter.raw_value_for(**options)
|
37
|
+
end
|
38
|
+
|
39
|
+
def raw_value
|
40
|
+
@raw_value ||= raw_value_for(**@options)
|
41
|
+
end
|
42
|
+
|
43
|
+
def value_for(**options)
|
44
|
+
@formatter.value_for(**options)
|
45
|
+
end
|
46
|
+
|
47
|
+
def title_for(**options)
|
48
|
+
@formatter.title_for(**options)
|
49
|
+
end
|
50
|
+
|
51
|
+
def option_attributes_for(**options)
|
52
|
+
return {
|
53
|
+
:value => value_for(**options),
|
54
|
+
:selected => options.fetch(:selected) {raw_value == raw_value_for(**options)},
|
55
|
+
:id => options[:id],
|
56
|
+
:class => options[:class],
|
57
|
+
:data => options[:data],
|
58
|
+
}
|
59
|
+
end
|
60
|
+
|
61
|
+
def item(**options, &block)
|
62
|
+
options[:field] ||= 'id'
|
63
|
+
|
64
|
+
Builder.fragment(block&.binding || @builder) do |builder|
|
65
|
+
builder.inline(:option, option_attributes_for(**options)) do
|
66
|
+
if block_given?
|
67
|
+
builder.capture(self, &block)
|
68
|
+
else
|
69
|
+
builder.text title_for(**options)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def optional_title_for(**options)
|
76
|
+
if options[:optional] == true
|
77
|
+
options[:blank] || ''
|
78
|
+
else
|
79
|
+
options[:optional]
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def group_attributes_for(**options)
|
84
|
+
return {
|
85
|
+
:label => title_for(**options),
|
86
|
+
:id => options[:id],
|
87
|
+
:class => options[:class],
|
88
|
+
:data => options[:data],
|
89
|
+
}
|
90
|
+
end
|
91
|
+
|
92
|
+
def group(**options, &block)
|
93
|
+
@builder.tag :optgroup, group_attributes_for(**options) do
|
94
|
+
if options[:optional]
|
95
|
+
item(title: optional_title_for(**options), value: nil)
|
96
|
+
end
|
97
|
+
|
98
|
+
@builder.capture(&block)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def select_attributes_for(**options)
|
103
|
+
return {
|
104
|
+
:name => name_for(**options),
|
105
|
+
:id => options[:id],
|
106
|
+
:class => options[:class],
|
107
|
+
:multiple => options[:multiple],
|
108
|
+
:data => options[:data],
|
109
|
+
:required => options[:required],
|
110
|
+
}
|
111
|
+
end
|
112
|
+
|
113
|
+
def optional?
|
114
|
+
@options[:optional]
|
115
|
+
end
|
116
|
+
|
117
|
+
def call(&block)
|
118
|
+
Builder.fragment(@builder) do |builder|
|
119
|
+
builder.tag :select, select_attributes_for(**@options) do
|
120
|
+
if self.optional?
|
121
|
+
builder << item(title: optional_title_for(**@options), value: nil)
|
122
|
+
end
|
123
|
+
|
124
|
+
builder.capture(self, &block)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Released under the MIT License.
|
4
|
+
# Copyright, 2012-2024, by Samuel Williams.
|
5
|
+
|
6
|
+
require 'xrb/builder'
|
7
|
+
|
8
|
+
module XRB
|
9
|
+
module Formatters
|
10
|
+
module HTML
|
11
|
+
# Table based select boxes using per-row checkboxes.
|
12
|
+
class RadioSelect
|
13
|
+
def self.call(formatter, builder, **options, &block)
|
14
|
+
instance = self.new(formatter, builder, **options)
|
15
|
+
|
16
|
+
instance.call(&block)
|
17
|
+
end
|
18
|
+
|
19
|
+
def initialize(formatter, builder, **options)
|
20
|
+
@formatter = formatter
|
21
|
+
@builder = builder
|
22
|
+
@options = options
|
23
|
+
|
24
|
+
@field = options[:field]
|
25
|
+
end
|
26
|
+
|
27
|
+
def name_for(**options)
|
28
|
+
@formatter.name_for(**options)
|
29
|
+
end
|
30
|
+
|
31
|
+
def raw_value_for(**options)
|
32
|
+
@formatter.raw_value_for(**options)
|
33
|
+
end
|
34
|
+
|
35
|
+
def raw_value
|
36
|
+
@raw_value ||= raw_value_for(**@options)
|
37
|
+
end
|
38
|
+
|
39
|
+
def value_for(**options)
|
40
|
+
@formatter.value_for(**options)
|
41
|
+
end
|
42
|
+
|
43
|
+
def title_for(**options)
|
44
|
+
@formatter.title_for(**options)
|
45
|
+
end
|
46
|
+
|
47
|
+
def radio_attributes_for(**options)
|
48
|
+
return {
|
49
|
+
:type => :radio,
|
50
|
+
:name => @field,
|
51
|
+
# We set a default value to empty string, otherwise it becomes "on".
|
52
|
+
:value => value_for(**options) || "",
|
53
|
+
:checked => options.fetch(:selected) {raw_value == raw_value_for(**options)},
|
54
|
+
:data => options[:data],
|
55
|
+
}
|
56
|
+
end
|
57
|
+
|
58
|
+
def item(**options, &block)
|
59
|
+
Builder.fragment(block&.binding || @builder) do |builder|
|
60
|
+
builder.tag :tr do
|
61
|
+
builder.inline(:td, :class => :handle) do
|
62
|
+
builder.tag :input, radio_attributes_for(**options)
|
63
|
+
end
|
64
|
+
|
65
|
+
builder.inline(:td, :class => :item) do
|
66
|
+
if block_given?
|
67
|
+
builder.capture(self, &block)
|
68
|
+
else
|
69
|
+
builder.text title_for(**options)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def optional_title_for(**options)
|
77
|
+
if options[:optional] == true
|
78
|
+
options[:blank] || ''
|
79
|
+
else
|
80
|
+
options[:optional]
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def optional?
|
85
|
+
@options[:optional]
|
86
|
+
end
|
87
|
+
|
88
|
+
def call(&block)
|
89
|
+
Builder.fragment(@builder) do |builder|
|
90
|
+
builder.tag :table do
|
91
|
+
builder.tag :tbody do
|
92
|
+
if self.optional?
|
93
|
+
builder << item(title: optional_title_for(**@options), value: nil)
|
94
|
+
end
|
95
|
+
|
96
|
+
builder.capture(self, &block)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Released under the MIT License.
|
4
|
+
# Copyright, 2016-2024, by Samuel Williams.
|
5
|
+
|
6
|
+
require 'markly'
|
7
|
+
|
8
|
+
require 'xrb/markup'
|
9
|
+
require 'xrb/sanitize/fragment'
|
10
|
+
|
11
|
+
module XRB
|
12
|
+
module Formatters
|
13
|
+
module Markdown
|
14
|
+
def markdown(text, filter = XRB::Sanitize::Fragment, **options)
|
15
|
+
root = Markly.parse(text, **options)
|
16
|
+
|
17
|
+
html = filter.parse(root.to_html).output
|
18
|
+
|
19
|
+
return MarkupString.raw(html)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Released under the MIT License.
|
4
|
+
# Copyright, 2016-2024, by Samuel Williams.
|
5
|
+
|
6
|
+
require 'xrb/strings'
|
7
|
+
require 'mapping/model'
|
8
|
+
|
9
|
+
module XRB
|
10
|
+
module Formatters
|
11
|
+
module RelativeTime
|
12
|
+
def self.included(base)
|
13
|
+
base.map(Time) do |object, **options|
|
14
|
+
current_time = options.fetch(:current_time) {Time.now}
|
15
|
+
|
16
|
+
# Ensure we display the time in localtime, and show the year if it is different:
|
17
|
+
if object.localtime.year != current_time.year
|
18
|
+
object.localtime.strftime("%B %-d, %-l:%M%P, %Y")
|
19
|
+
else
|
20
|
+
object.localtime.strftime("%B %-d, %-l:%M%P")
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Released under the MIT License.
|
4
|
+
# Copyright, 2016-2024, by Samuel Williams.
|
5
|
+
|
6
|
+
require 'xrb/strings'
|
7
|
+
require 'mapping/model'
|
8
|
+
|
9
|
+
module XRB
|
10
|
+
module Formatters
|
11
|
+
module TruncatedText
|
12
|
+
def truncated_text(content, length: 30, **options)
|
13
|
+
if content
|
14
|
+
content = TruncatedText.truncate_text(content, length, **options)
|
15
|
+
|
16
|
+
return self.format(content)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.truncate_text(text, truncate_at, omission: nil, separator: nil, **options)
|
21
|
+
return text.dup unless text.length > truncate_at
|
22
|
+
|
23
|
+
omission ||= '...'
|
24
|
+
|
25
|
+
length_with_room_for_omission = truncate_at - omission.length
|
26
|
+
|
27
|
+
stop = nil
|
28
|
+
|
29
|
+
if separator
|
30
|
+
stop = text.rindex(separator, length_with_room_for_omission)
|
31
|
+
end
|
32
|
+
|
33
|
+
stop ||= length_with_room_for_omission
|
34
|
+
|
35
|
+
"#{text[0...stop]}#{omission}"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/license.md
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# MIT License
|
2
|
+
|
3
|
+
Copyright, 2012-2024, by Samuel Williams.
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/readme.md
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
# XRB::Formatters
|
2
|
+
|
3
|
+
XRB is a templating system, and these formatters assist with the development
|
4
|
+
of typical view and form based web interface. A formatter is a high-level
|
5
|
+
adapter that turns model data into presentation text.
|
6
|
+
|
7
|
+
Formatters are designed to be customised, typically per-project, for specific
|
8
|
+
formatting needs.
|
9
|
+
|
10
|
+
[](https://github.com/socketry/xrb-formatters/actions?workflow=Test)
|
11
|
+
|
12
|
+
## Motivation
|
13
|
+
|
14
|
+
`XRB::Formatters` was a library extracted from [Financier](https://github.com/ioquatix/financier), an small business management app, itself, derived from an old Rails app. I was a bit envious of `form_for` in terms of the ease of generating forms, but found that it wasn't very extendable. I also found myself generating code to format model data as rich HTML. `XRB::Formatters` attempts to be an easily extendable formatting module which can generate rich text, links and HTML.
|
15
|
+
|
16
|
+
## Installation
|
17
|
+
|
18
|
+
Add this line to your application's Gemfile:
|
19
|
+
|
20
|
+
gem 'xrb-formatters'
|
21
|
+
|
22
|
+
And then execute:
|
23
|
+
|
24
|
+
$ bundle
|
25
|
+
|
26
|
+
Or install it yourself as:
|
27
|
+
|
28
|
+
$ gem install xrb-formatters
|
29
|
+
|
30
|
+
## Usage
|
31
|
+
|
32
|
+
The most basic usage involves converting model data into presentation text by
|
33
|
+
a mapping corresponding to the objects type:
|
34
|
+
|
35
|
+
``` ruby
|
36
|
+
formatter = XRB::Formatters::Formatter.new
|
37
|
+
|
38
|
+
formatter.for(String) do |value, **options|
|
39
|
+
"String: #{value}"
|
40
|
+
end
|
41
|
+
|
42
|
+
expect(formatter.format("foobar")).to be == "String: foobar"
|
43
|
+
```
|
44
|
+
|
45
|
+
For more examples please see `spec/`.
|
46
|
+
|
47
|
+
## Contributing
|
48
|
+
|
49
|
+
We welcome contributions to this project.
|
50
|
+
|
51
|
+
1. Fork it.
|
52
|
+
2. Create your feature branch (`git checkout -b my-new-feature`).
|
53
|
+
3. Commit your changes (`git commit -am 'Add some feature'`).
|
54
|
+
4. Push to the branch (`git push origin my-new-feature`).
|
55
|
+
5. Create new Pull Request.
|
56
|
+
|
57
|
+
### Developer Certificate of Origin
|
58
|
+
|
59
|
+
This project uses the [Developer Certificate of Origin](https://developercertificate.org/). All contributors to this project must agree to this document to have their contributions accepted.
|
60
|
+
|
61
|
+
### Contributor Covenant
|
62
|
+
|
63
|
+
This project is governed by the [Contributor Covenant](https://www.contributor-covenant.org/). All contributors and participants agree to abide by its terms.
|
data.tar.gz.sig
ADDED
Binary file
|
metadata
ADDED
@@ -0,0 +1,115 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: xrb-formatters
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Samuel Williams
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain:
|
11
|
+
- |
|
12
|
+
-----BEGIN CERTIFICATE-----
|
13
|
+
MIIE2DCCA0CgAwIBAgIBATANBgkqhkiG9w0BAQsFADBhMRgwFgYDVQQDDA9zYW11
|
14
|
+
ZWwud2lsbGlhbXMxHTAbBgoJkiaJk/IsZAEZFg1vcmlvbnRyYW5zZmVyMRIwEAYK
|
15
|
+
CZImiZPyLGQBGRYCY28xEjAQBgoJkiaJk/IsZAEZFgJuejAeFw0yMjA4MDYwNDUz
|
16
|
+
MjRaFw0zMjA4MDMwNDUzMjRaMGExGDAWBgNVBAMMD3NhbXVlbC53aWxsaWFtczEd
|
17
|
+
MBsGCgmSJomT8ixkARkWDW9yaW9udHJhbnNmZXIxEjAQBgoJkiaJk/IsZAEZFgJj
|
18
|
+
bzESMBAGCgmSJomT8ixkARkWAm56MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIB
|
19
|
+
igKCAYEAomvSopQXQ24+9DBB6I6jxRI2auu3VVb4nOjmmHq7XWM4u3HL+pni63X2
|
20
|
+
9qZdoq9xt7H+RPbwL28LDpDNflYQXoOhoVhQ37Pjn9YDjl8/4/9xa9+NUpl9XDIW
|
21
|
+
sGkaOY0eqsQm1pEWkHJr3zn/fxoKPZPfaJOglovdxf7dgsHz67Xgd/ka+Wo1YqoE
|
22
|
+
e5AUKRwUuvaUaumAKgPH+4E4oiLXI4T1Ff5Q7xxv6yXvHuYtlMHhYfgNn8iiW8WN
|
23
|
+
XibYXPNP7NtieSQqwR/xM6IRSoyXKuS+ZNGDPUUGk8RoiV/xvVN4LrVm9upSc0ss
|
24
|
+
RZ6qwOQmXCo/lLcDUxJAgG95cPw//sI00tZan75VgsGzSWAOdjQpFM0l4dxvKwHn
|
25
|
+
tUeT3ZsAgt0JnGqNm2Bkz81kG4A2hSyFZTFA8vZGhp+hz+8Q573tAR89y9YJBdYM
|
26
|
+
zp0FM4zwMNEUwgfRzv1tEVVUEXmoFCyhzonUUw4nE4CFu/sE3ffhjKcXcY//qiSW
|
27
|
+
xm4erY3XAgMBAAGjgZowgZcwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAwHQYDVR0O
|
28
|
+
BBYEFO9t7XWuFf2SKLmuijgqR4sGDlRsMC4GA1UdEQQnMCWBI3NhbXVlbC53aWxs
|
29
|
+
aWFtc0BvcmlvbnRyYW5zZmVyLmNvLm56MC4GA1UdEgQnMCWBI3NhbXVlbC53aWxs
|
30
|
+
aWFtc0BvcmlvbnRyYW5zZmVyLmNvLm56MA0GCSqGSIb3DQEBCwUAA4IBgQB5sxkE
|
31
|
+
cBsSYwK6fYpM+hA5B5yZY2+L0Z+27jF1pWGgbhPH8/FjjBLVn+VFok3CDpRqwXCl
|
32
|
+
xCO40JEkKdznNy2avOMra6PFiQyOE74kCtv7P+Fdc+FhgqI5lMon6tt9rNeXmnW/
|
33
|
+
c1NaMRdxy999hmRGzUSFjozcCwxpy/LwabxtdXwXgSay4mQ32EDjqR1TixS1+smp
|
34
|
+
8C/NCWgpIfzpHGJsjvmH2wAfKtTTqB9CVKLCWEnCHyCaRVuKkrKjqhYCdmMBqCws
|
35
|
+
JkxfQWC+jBVeG9ZtPhQgZpfhvh+6hMhraUYRQ6XGyvBqEUe+yo6DKIT3MtGE2+CP
|
36
|
+
eX9i9ZWBydWb8/rvmwmX2kkcBbX0hZS1rcR593hGc61JR6lvkGYQ2MYskBveyaxt
|
37
|
+
Q2K9NVun/S785AP05vKkXZEFYxqG6EW012U4oLcFl5MySFajYXRYbuUpH6AY+HP8
|
38
|
+
voD0MPg1DssDLKwXyt1eKD/+Fq0bFWhwVM/1XiAXL7lyYUyOq24KHgQ2Csg=
|
39
|
+
-----END CERTIFICATE-----
|
40
|
+
date: 2024-05-08 00:00:00.000000000 Z
|
41
|
+
dependencies:
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: mapping
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - "~>"
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '1.1'
|
49
|
+
type: :runtime
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - "~>"
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '1.1'
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: xrb
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - "~>"
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0.6'
|
63
|
+
type: :runtime
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - "~>"
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0.6'
|
70
|
+
description:
|
71
|
+
email:
|
72
|
+
executables: []
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- lib/xrb/formatters.rb
|
77
|
+
- lib/xrb/formatters/formatter.rb
|
78
|
+
- lib/xrb/formatters/html/accept_checkbox.rb
|
79
|
+
- lib/xrb/formatters/html/definition_list_form.rb
|
80
|
+
- lib/xrb/formatters/html/form_formatter.rb
|
81
|
+
- lib/xrb/formatters/html/label_form.rb
|
82
|
+
- lib/xrb/formatters/html/option_select.rb
|
83
|
+
- lib/xrb/formatters/html/radio_select.rb
|
84
|
+
- lib/xrb/formatters/markdown.rb
|
85
|
+
- lib/xrb/formatters/relative_time.rb
|
86
|
+
- lib/xrb/formatters/truncated_text.rb
|
87
|
+
- lib/xrb/formatters/version.rb
|
88
|
+
- license.md
|
89
|
+
- readme.md
|
90
|
+
homepage: https://github.com/ioquatix/xrb-formatters
|
91
|
+
licenses:
|
92
|
+
- MIT
|
93
|
+
metadata:
|
94
|
+
funding_uri: https://github.com/sponsors/ioquatix/
|
95
|
+
source_code_uri: https://github.com/ioquatix/xrb-formatters.git
|
96
|
+
post_install_message:
|
97
|
+
rdoc_options: []
|
98
|
+
require_paths:
|
99
|
+
- lib
|
100
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
101
|
+
requirements:
|
102
|
+
- - ">="
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
version: '3.1'
|
105
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
106
|
+
requirements:
|
107
|
+
- - ">="
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
requirements: []
|
111
|
+
rubygems_version: 3.5.3
|
112
|
+
signing_key:
|
113
|
+
specification_version: 4
|
114
|
+
summary: Formatters for XRB, to assist with typical views and form based interfaces.
|
115
|
+
test_files: []
|
metadata.gz.sig
ADDED
Binary file
|