express_templates 0.9.8 → 0.10.1
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 +4 -4
- data/lib/express_templates/components/all.rb +26 -0
- data/lib/express_templates/components/base.rb +4 -0
- data/lib/express_templates/components/capabilities/resourceful.rb +13 -13
- data/lib/express_templates/components/forms/basic_fields.rb +4 -4
- data/lib/express_templates/components/forms/checkbox.rb +1 -1
- data/lib/express_templates/components/forms/express_form.rb +6 -2
- data/lib/express_templates/components/forms/form_component.rb +16 -4
- data/lib/express_templates/components/forms/radio.rb +3 -3
- data/lib/express_templates/components.rb +1 -0
- data/lib/express_templates/version.rb +1 -1
- data/test/components/forms/basic_fields_test.rb +17 -9
- data/test/components/forms/checkbox_test.rb +16 -3
- data/test/components/forms/express_form_test.rb +12 -8
- data/test/components/forms/radio_test.rb +14 -2
- data/test/components/forms/select_test.rb +11 -3
- data/test/test_helper.rb +3 -17
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4c9baef818e61dca4af8b2dc58563e052a18dbe6
|
4
|
+
data.tar.gz: 380b2be118607d717bd5c9d7adb5b6bb54cd21d9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 300363fd967967329bbc0a4a783d5affce0c83fa522086735be9df12561484c91e3179e668adf933f1660a4894696c8f6229c3811b56f253e26479533ed751c6
|
7
|
+
data.tar.gz: c82fd24eb83f898092ebb731f37c60739d29ec09316038ab6605a27fef4feda4b6ad2053c2d303f127fee8de41f482c81bdf317e792e862bfffebaee87999438
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module ExpressTemplates
|
2
|
+
module Components
|
3
|
+
class All < Container
|
4
|
+
|
5
|
+
has_argument :id, "Name of the collection", as: :collection_name, type: :symbol
|
6
|
+
|
7
|
+
contains -> (&block) {
|
8
|
+
prepended
|
9
|
+
collection.each do |item|
|
10
|
+
assigns[member_name] = item
|
11
|
+
block.call(self) if block
|
12
|
+
end
|
13
|
+
appended
|
14
|
+
}
|
15
|
+
|
16
|
+
def member_name
|
17
|
+
config[:collection_name].to_s.singularize.to_sym
|
18
|
+
end
|
19
|
+
|
20
|
+
def collection
|
21
|
+
self.send(config[:collection_name])
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -32,6 +32,10 @@ module ExpressTemplates
|
|
32
32
|
add_class _default_classes
|
33
33
|
end
|
34
34
|
|
35
|
+
def assigns
|
36
|
+
@assigns_with_indifferent_access ||= super.merge(helpers.assigns.with_indifferent_access)
|
37
|
+
end
|
38
|
+
|
35
39
|
def self.contains(proc = nil, &block)
|
36
40
|
define_method(:_build_body, &(proc || block))
|
37
41
|
end
|
@@ -38,7 +38,7 @@ module ExpressTemplates
|
|
38
38
|
if namespace
|
39
39
|
"#{namespace}/#{resource_name}".classify
|
40
40
|
else
|
41
|
-
resource_name.classify
|
41
|
+
resource_name.to_s.classify
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
@@ -120,7 +120,7 @@ module ExpressTemplates
|
|
120
120
|
config[:collection]
|
121
121
|
end
|
122
122
|
else
|
123
|
-
|
123
|
+
self.send(collection_name) # should be in view assigns
|
124
124
|
end
|
125
125
|
end
|
126
126
|
|
@@ -170,14 +170,10 @@ module ExpressTemplates
|
|
170
170
|
resource_class_name.split("::").first.try(:underscore) : nil
|
171
171
|
end
|
172
172
|
|
173
|
-
|
174
|
-
# and also may accept a resource on which we call to_param
|
175
|
-
def resource_path(ivar_or_resource = nil)
|
173
|
+
def resource_path(object = nil)
|
176
174
|
if config[:resource_path]
|
177
|
-
if config[:resource_path].respond_to?(:call) &&
|
178
|
-
|
179
|
-
![true, false].include?(ivar_or_resource)
|
180
|
-
config[:resource_path].call(ivar_or_resource)
|
175
|
+
if config[:resource_path].respond_to?(:call) && object.respond_to?(:to_param)
|
176
|
+
config[:resource_path].call(object)
|
181
177
|
else
|
182
178
|
config[:resource_path]
|
183
179
|
end
|
@@ -186,11 +182,11 @@ module ExpressTemplates
|
|
186
182
|
helpers.resource.to_param.present? # skip on nil resource
|
187
183
|
helpers.resource_path
|
188
184
|
else
|
189
|
-
if
|
190
|
-
|
191
|
-
helpers.
|
185
|
+
if resource_path_helper.match(/\w+\.\w+/)
|
186
|
+
namespace, path_helper = resource_path_helper.split('.')
|
187
|
+
helpers.send(namespace).send(path_helper, object)
|
192
188
|
else
|
193
|
-
helpers.
|
189
|
+
helpers.send(resource_path_helper, object)
|
194
190
|
end
|
195
191
|
end
|
196
192
|
end
|
@@ -207,6 +203,10 @@ module ExpressTemplates
|
|
207
203
|
def resource_attributes
|
208
204
|
resource_class.columns
|
209
205
|
end
|
206
|
+
|
207
|
+
def resource
|
208
|
+
self.send(resource_name)
|
209
|
+
end
|
210
210
|
end
|
211
211
|
end
|
212
212
|
end
|
@@ -11,7 +11,7 @@ module ExpressTemplates
|
|
11
11
|
class #{type.classify} < FormComponent
|
12
12
|
contains {
|
13
13
|
label_tag(label_name, label_text)
|
14
|
-
#{type}
|
14
|
+
#{type}_field_tag field_name_attribute, field_value, field_helper_options
|
15
15
|
}
|
16
16
|
end
|
17
17
|
RUBY
|
@@ -24,20 +24,20 @@ RUBY
|
|
24
24
|
# class Email < FormComponent
|
25
25
|
# contains {
|
26
26
|
# label_tag label_name, label_text
|
27
|
-
# email_field
|
27
|
+
# email_field field_name_attribute, field_value, field_helper_options
|
28
28
|
# }
|
29
29
|
# end
|
30
30
|
|
31
31
|
class Textarea < FormComponent
|
32
32
|
contains {
|
33
33
|
label_tag(label_name, label_text)
|
34
|
-
|
34
|
+
text_area_tag field_name_attribute, field_value, field_helper_options
|
35
35
|
}
|
36
36
|
end
|
37
37
|
|
38
38
|
class Hidden < FormComponent
|
39
39
|
contains {
|
40
|
-
|
40
|
+
hidden_field_tag field_name_attribute, field_value, field_helper_options
|
41
41
|
}
|
42
42
|
end
|
43
43
|
end
|
@@ -7,7 +7,7 @@ module ExpressTemplates
|
|
7
7
|
|
8
8
|
contains {
|
9
9
|
label_tag(label_name, label_text) if label_before?
|
10
|
-
check_box(
|
10
|
+
check_box(resource_name, field_name.to_sym, field_options, checked_value, unchecked_value)
|
11
11
|
label_tag(label_name, label_text) if label_after?
|
12
12
|
}
|
13
13
|
|
@@ -8,12 +8,16 @@ module ExpressTemplates
|
|
8
8
|
|
9
9
|
has_option :method, 'The form method', default: 'POST', attribute: true #, options: ['PUT', 'POST', 'GET', 'DELETE']
|
10
10
|
has_option :action, 'The form action containing the resource path or url.'
|
11
|
+
has_option :on_success, 'Pass a form value indicating where to go on a successful submission.'
|
12
|
+
has_option :on_failure, 'Pass a form value indicating where to go on a failed submission.'
|
11
13
|
|
12
14
|
prepends -> {
|
13
15
|
div(style: 'display:none') {
|
14
16
|
add_child helpers.utf8_enforcer_tag
|
15
17
|
add_child helpers.send(:method_tag, resource.persisted? ? :put : :post)
|
16
|
-
helpers.send(:token_tag)
|
18
|
+
add_child helpers.send(:token_tag)
|
19
|
+
hidden_field_tag :on_success, config[:on_success] if config[:on_success]
|
20
|
+
hidden_field_tag :on_failure, config[:on_failure] if config[:on_failure]
|
17
21
|
}
|
18
22
|
}
|
19
23
|
|
@@ -28,7 +32,7 @@ module ExpressTemplates
|
|
28
32
|
end
|
29
33
|
|
30
34
|
def form_action
|
31
|
-
config[:action] || (resource.try(:persisted?) ? resource_path(
|
35
|
+
config[:action] || (resource.try(:persisted?) ? resource_path(resource) : collection_path)
|
32
36
|
end
|
33
37
|
|
34
38
|
end
|
@@ -15,16 +15,16 @@ module ExpressTemplates
|
|
15
15
|
has_option :wrapper_class, 'Override the class of the wrapping div of a form component', default: 'field-wrapper'
|
16
16
|
has_option :label, 'Override the inferred label of a form component'
|
17
17
|
|
18
|
+
def resource
|
19
|
+
self.send(resource_name)
|
20
|
+
end
|
21
|
+
|
18
22
|
# Lookup the resource_name from the parent ExpressForm.
|
19
23
|
def resource_name
|
20
24
|
raise "FormComponent must have a parent form" unless parent_form
|
21
25
|
parent_form.config[:id].to_s
|
22
26
|
end
|
23
27
|
|
24
|
-
def resource_var
|
25
|
-
resource_name.to_sym
|
26
|
-
end
|
27
|
-
|
28
28
|
def resource_class
|
29
29
|
parent_form.resource_class
|
30
30
|
end
|
@@ -45,12 +45,24 @@ module ExpressTemplates
|
|
45
45
|
(config[:id] || (@args.first.is_a?(String) && @args.first)).to_s
|
46
46
|
end
|
47
47
|
|
48
|
+
def field_value
|
49
|
+
resource.send(field_name)
|
50
|
+
end
|
51
|
+
|
48
52
|
# Return the field name attribute. Currently handles only simple attributes
|
49
53
|
# on the resource. Does not handle attributes for associated resources.
|
50
54
|
def field_name_attribute
|
51
55
|
"#{resource_name.singularize}[#{field_name}]"
|
52
56
|
end
|
53
57
|
|
58
|
+
def field_id_attribute
|
59
|
+
"#{resource_name.singularize}_#{field_name}"
|
60
|
+
end
|
61
|
+
|
62
|
+
def field_helper_options
|
63
|
+
{id: field_id_attribute}.merge(input_attributes||nil)
|
64
|
+
end
|
65
|
+
|
54
66
|
# Search the parent graph until we find an ExpressForm. Returns nil if none found.
|
55
67
|
def parent_form
|
56
68
|
@my_form ||= parent
|
@@ -17,7 +17,7 @@ module ExpressTemplates
|
|
17
17
|
}
|
18
18
|
|
19
19
|
def use_options_from_collection_radio_buttons_helper
|
20
|
-
collection_radio_buttons(
|
20
|
+
collection_radio_buttons(resource_name, field_name.to_sym, collection_from_association,
|
21
21
|
option_value_method, option_name_method,
|
22
22
|
input_attributes) do |b|
|
23
23
|
b.label(class: "radio") {
|
@@ -39,14 +39,14 @@ module ExpressTemplates
|
|
39
39
|
when option_collection.kind_of?(Array)
|
40
40
|
option_collection.each_with_index do |option, index|
|
41
41
|
label(class: config[:label_wrapper_class]) {
|
42
|
-
radio_button(
|
42
|
+
radio_button(resource_name, field_name.to_sym, option, class: 'radio')
|
43
43
|
current_arbre_element.add_child option
|
44
44
|
}
|
45
45
|
end
|
46
46
|
when option_collection.kind_of?(Hash)
|
47
47
|
option_collection.each_pair do |key, value|
|
48
48
|
label(class: config[:label_wrapper_class]) {
|
49
|
-
radio_button(
|
49
|
+
radio_button(resource_name, field_name.to_sym, key, class: 'radio')
|
50
50
|
current_arbre_element.add_child value
|
51
51
|
}
|
52
52
|
end
|
@@ -8,7 +8,15 @@ class BasicFieldsTest < ActiveSupport::TestCase
|
|
8
8
|
search telephone time url week)
|
9
9
|
|
10
10
|
def assigns
|
11
|
-
{
|
11
|
+
{foo: resource}
|
12
|
+
end
|
13
|
+
|
14
|
+
def helpers
|
15
|
+
mock_action_view do
|
16
|
+
def foos_path
|
17
|
+
'/foos'
|
18
|
+
end
|
19
|
+
end
|
12
20
|
end
|
13
21
|
|
14
22
|
def field_type_map
|
@@ -67,7 +75,7 @@ class BasicFieldsTest < ActiveSupport::TestCase
|
|
67
75
|
}
|
68
76
|
}
|
69
77
|
assert_match label_html, html
|
70
|
-
assert_match /<textarea
|
78
|
+
assert_match /<textarea name="foo\[bar\]" id="foo_bar" rows="5" class="tinymce form-field"><\/textarea>/, html.gsub("\n", '')
|
71
79
|
end
|
72
80
|
|
73
81
|
test "hidden uses rails hidden_tag helper" do
|
@@ -87,7 +95,7 @@ class BasicFieldsTest < ActiveSupport::TestCase
|
|
87
95
|
}
|
88
96
|
}
|
89
97
|
assert_no_match label_html, html
|
90
|
-
assert_match /<input
|
98
|
+
assert_match /<input type="hidden" name="foo\[bar\]" id="foo_bar" value="ninja" class="hidden form-field"/, html
|
91
99
|
end
|
92
100
|
|
93
101
|
def resource_with_errors
|
@@ -113,37 +121,37 @@ class BasicFieldsTest < ActiveSupport::TestCase
|
|
113
121
|
end
|
114
122
|
|
115
123
|
test "adds error class if there are errors on a field with no input attributes" do
|
116
|
-
html_with_error = arbre(
|
124
|
+
html_with_error = arbre(foo: resource_with_errors) {
|
117
125
|
express_form(:foo) {
|
118
126
|
text :name
|
119
127
|
text :body
|
120
128
|
}
|
121
129
|
}
|
122
130
|
assert resource_with_errors.errors.any?
|
123
|
-
assert assigns[:
|
131
|
+
assert assigns[:foo].errors.any?
|
124
132
|
assert has_error_class_on(:name, html_with_error), "name field has no error when expected"
|
125
133
|
refute has_error_class_on(:body, html_with_error), "body field has error class when it should not"
|
126
134
|
end
|
127
135
|
|
128
136
|
test "adds error class if there are errors on a field with no class set" do
|
129
|
-
html_with_error = arbre(
|
137
|
+
html_with_error = arbre(foo: resource_with_errors) {
|
130
138
|
express_form(:foo) {
|
131
139
|
text :name, value: 'ninja'
|
132
140
|
}
|
133
141
|
}
|
134
142
|
assert resource_with_errors.errors.any?
|
135
|
-
assert assigns[:
|
143
|
+
assert assigns[:foo].errors.any?
|
136
144
|
assert_match has_error_class, html_with_error
|
137
145
|
end
|
138
146
|
|
139
147
|
test "adds error to class if there are errors on a field with existing class" do
|
140
|
-
html_with_error = arbre(
|
148
|
+
html_with_error = arbre(foo: resource_with_errors) {
|
141
149
|
express_form(:foo) {
|
142
150
|
text :name, value: 'ninja', class: 'slug'
|
143
151
|
}
|
144
152
|
}
|
145
153
|
assert resource_with_errors.errors.any?
|
146
|
-
assert assigns[:
|
154
|
+
assert assigns[:foo].errors.any?
|
147
155
|
assert_match has_error_class, html_with_error
|
148
156
|
end
|
149
157
|
|
@@ -1,12 +1,25 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
|
+
class Account
|
4
|
+
end
|
5
|
+
|
3
6
|
class CheckboxTest < ActiveSupport::TestCase
|
7
|
+
|
4
8
|
def assigns
|
5
|
-
{
|
9
|
+
{account: resource}
|
6
10
|
end
|
7
11
|
|
12
|
+
def helpers
|
13
|
+
mock_action_view do
|
14
|
+
def accounts_path
|
15
|
+
'/accounts'
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
|
8
21
|
test "checkbox places the label before the input" do
|
9
|
-
html = arbre {
|
22
|
+
html = arbre(account: resource) {
|
10
23
|
express_form(:account) {
|
11
24
|
checkbox :eula
|
12
25
|
}
|
@@ -21,7 +34,7 @@ class CheckboxTest < ActiveSupport::TestCase
|
|
21
34
|
end
|
22
35
|
|
23
36
|
test "checkbox respects label_after: true " do
|
24
|
-
html = arbre {
|
37
|
+
html = arbre(account: resource) {
|
25
38
|
express_form(:account) {
|
26
39
|
checkbox :eula, label_after: true
|
27
40
|
}
|
@@ -6,24 +6,28 @@ require 'test_helper'
|
|
6
6
|
|
7
7
|
class ExpressFormTest < ActiveSupport::TestCase
|
8
8
|
|
9
|
-
def assigns
|
10
|
-
{resource: resource}
|
11
|
-
end
|
12
|
-
|
13
9
|
def simplest_form
|
14
|
-
arbre {
|
15
|
-
express_form(:
|
10
|
+
arbre(foo: resource) {
|
11
|
+
express_form(:foo) {
|
16
12
|
submit value: 'Save it!'
|
17
13
|
}
|
18
14
|
}
|
19
15
|
end
|
20
16
|
|
17
|
+
def helpers
|
18
|
+
mock_action_view do
|
19
|
+
def foos_path
|
20
|
+
'/foos'
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
21
25
|
test "simplest form renders" do
|
22
26
|
assert simplest_form
|
23
27
|
end
|
24
28
|
|
25
29
|
test "simplest form will have the proper id" do
|
26
|
-
assert_match /<form.*id="
|
30
|
+
assert_match /<form.*id="foo_1"/, simplest_form
|
27
31
|
end
|
28
32
|
|
29
33
|
test "simplest form contains form tag" do
|
@@ -48,7 +52,7 @@ class ExpressFormTest < ActiveSupport::TestCase
|
|
48
52
|
|
49
53
|
test "simplest_form uses form_action for the action" do
|
50
54
|
form_open_tag = simplest_form.match(/<form[^>]*>/)[0]
|
51
|
-
assert_match 'action="/
|
55
|
+
assert_match 'action="/foos"', form_open_tag
|
52
56
|
end
|
53
57
|
|
54
58
|
test "express_form default method is POST" do
|
@@ -3,7 +3,19 @@ require 'test_helper'
|
|
3
3
|
class RadioTest < ActiveSupport::TestCase
|
4
4
|
|
5
5
|
def assigns
|
6
|
-
{
|
6
|
+
{person: ::Person.new}
|
7
|
+
end
|
8
|
+
|
9
|
+
def helpers
|
10
|
+
mock_action_view do
|
11
|
+
def people_path
|
12
|
+
'/people'
|
13
|
+
end
|
14
|
+
|
15
|
+
def employees_path
|
16
|
+
'/employees'
|
17
|
+
end
|
18
|
+
end
|
7
19
|
end
|
8
20
|
|
9
21
|
test "radio requires a parent component" do
|
@@ -58,7 +70,7 @@ class RadioTest < ActiveSupport::TestCase
|
|
58
70
|
end
|
59
71
|
|
60
72
|
def radio_with_options_omitted
|
61
|
-
html = arbre {
|
73
|
+
html = arbre(employee: resource) {
|
62
74
|
express_form(:employee) {
|
63
75
|
radio :department_id
|
64
76
|
}
|
@@ -3,7 +3,15 @@ require 'ostruct'
|
|
3
3
|
class SelectTest < ActiveSupport::TestCase
|
4
4
|
|
5
5
|
def assigns
|
6
|
-
{
|
6
|
+
{person: ::Person.new}
|
7
|
+
end
|
8
|
+
|
9
|
+
def helpers
|
10
|
+
mock_action_view do
|
11
|
+
def people_path
|
12
|
+
'/people'
|
13
|
+
end
|
14
|
+
end
|
7
15
|
end
|
8
16
|
|
9
17
|
|
@@ -112,8 +120,8 @@ class SelectTest < ActiveSupport::TestCase
|
|
112
120
|
}
|
113
121
|
}
|
114
122
|
assert_match 'tagging_ids', html
|
115
|
-
assert_match /<option value="1">Friend<\/option>/, html
|
116
|
-
assert_match /<option value="2">Enemy<\/option>/, html
|
123
|
+
assert_match /<option selected="selected" value="1">Friend<\/option>/, html
|
124
|
+
assert_match /<option selected="selected" value="2">Enemy<\/option>/, html
|
117
125
|
assert_match /<option value="3">Frenemy<\/option>/, html
|
118
126
|
end
|
119
127
|
|
data/test/test_helper.rb
CHANGED
@@ -53,18 +53,14 @@ module ActiveSupport
|
|
53
53
|
def helpers
|
54
54
|
mock_action_view
|
55
55
|
end
|
56
|
-
def mock_action_view
|
56
|
+
def mock_action_view &block
|
57
57
|
controller = ActionView::TestCase::TestController.new
|
58
58
|
ActionView::Base.send :include, ActionView::Helpers
|
59
59
|
ActionView::Base.send :include, ActionView::Helpers::UrlHelper
|
60
60
|
ActionView::Base.send :include, AdditionalHelpers
|
61
61
|
view = ActionView::Base.new(ActionController::Base.view_paths, assigns, controller)
|
62
|
-
eigenklass = class << view
|
63
|
-
|
64
|
-
end
|
65
|
-
assigns.each do |helper_name,value|
|
66
|
-
eigenklass.send(:define_method, helper_name) { value }
|
67
|
-
end
|
62
|
+
eigenklass = class << view; self; end
|
63
|
+
eigenklass.class_eval &block unless block.nil?
|
68
64
|
view
|
69
65
|
end
|
70
66
|
|
@@ -86,16 +82,6 @@ module ActiveSupport
|
|
86
82
|
end
|
87
83
|
|
88
84
|
|
89
|
-
class ExpressTemplates::Components::Forms::ExpressForm
|
90
|
-
def resource_path(resource)
|
91
|
-
"/resource/1"
|
92
|
-
end
|
93
|
-
|
94
|
-
def collection_path
|
95
|
-
"/resources"
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
85
|
|
100
86
|
class ::Gender
|
101
87
|
attr :id, :name
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: express_templates
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.10.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Steven Talcott Smith
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2015-08-
|
12
|
+
date: 2015-08-27 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activesupport
|
@@ -184,6 +184,7 @@ files:
|
|
184
184
|
- lib/express_templates.rb
|
185
185
|
- lib/express_templates/compiler.rb
|
186
186
|
- lib/express_templates/components.rb
|
187
|
+
- lib/express_templates/components/all.rb
|
187
188
|
- lib/express_templates/components/base.rb
|
188
189
|
- lib/express_templates/components/capabilities/resourceful.rb
|
189
190
|
- lib/express_templates/components/configurable.rb
|