dry-view 0.7.0 → 0.7.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/CHANGELOG.md +75 -54
- data/LICENSE +20 -0
- data/README.md +19 -36
- data/dry-view.gemspec +24 -15
- data/lib/dry/view.rb +19 -12
- data/lib/dry/view/context.rb +3 -3
- data/lib/dry/view/decorated_attributes.rb +2 -1
- data/lib/dry/view/errors.rb +3 -1
- data/lib/dry/view/exposure.rb +21 -13
- data/lib/dry/view/exposures.rb +5 -3
- data/lib/dry/view/part.rb +15 -6
- data/lib/dry/view/part_builder.rb +8 -4
- data/lib/dry/view/path.rb +1 -1
- data/lib/dry/view/render_environment.rb +4 -4
- data/lib/dry/view/render_environment_missing.rb +4 -4
- data/lib/dry/view/rendered.rb +1 -1
- data/lib/dry/view/renderer.rb +1 -1
- data/lib/dry/view/scope.rb +21 -7
- data/lib/dry/view/scope_builder.rb +4 -4
- data/lib/dry/view/tilt.rb +1 -1
- data/lib/dry/view/tilt/erb.rb +1 -1
- data/lib/dry/view/tilt/erbse.rb +1 -1
- data/lib/dry/view/version.rb +1 -1
- metadata +46 -47
- data/.codeclimate.yml +0 -18
- data/.gitignore +0 -26
- data/.rspec +0 -2
- data/.travis.yml +0 -28
- data/.yardopts +0 -5
- data/CONTRIBUTING.md +0 -29
- data/Gemfile +0 -32
- data/LICENSE.md +0 -10
- data/Rakefile +0 -6
- data/bin/console +0 -7
- data/bin/setup +0 -5
- data/bin/setup_helpers.rb +0 -27
data/lib/dry/view/context.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "dry/equalizer"
|
3
|
+
require "dry/core/equalizer"
|
4
4
|
require_relative "decorated_attributes"
|
5
5
|
|
6
6
|
module Dry
|
@@ -43,7 +43,7 @@ module Dry
|
|
43
43
|
|
44
44
|
# @api private
|
45
45
|
def for_render_env(render_env)
|
46
|
-
return self if render_env ==
|
46
|
+
return self if render_env == _render_env
|
47
47
|
|
48
48
|
self.class.new(**_options.merge(render_env: render_env))
|
49
49
|
end
|
@@ -72,7 +72,7 @@ module Dry
|
|
72
72
|
def with(**new_options)
|
73
73
|
self.class.new(
|
74
74
|
render_env: _render_env,
|
75
|
-
**_options.merge(new_options)
|
75
|
+
**_options.merge(new_options)
|
76
76
|
)
|
77
77
|
end
|
78
78
|
end
|
@@ -27,7 +27,8 @@ module Dry
|
|
27
27
|
#
|
28
28
|
# @param names [Array<Symbol>] the attribute names
|
29
29
|
# @param options [Hash] the options to pass to the Part Builder
|
30
|
-
# @option options [Symbol, Class] :as an alternative name or class to use when finding a
|
30
|
+
# @option options [Symbol, Class] :as an alternative name or class to use when finding a
|
31
|
+
# matching Part
|
31
32
|
#
|
32
33
|
# @api public
|
33
34
|
def decorate(*names, **options)
|
data/lib/dry/view/errors.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Dry
|
2
4
|
class View
|
3
5
|
# Error raised when critical settings are not configured
|
@@ -17,7 +19,7 @@ module Dry
|
|
17
19
|
def initialize(template_name, lookup_paths)
|
18
20
|
msg = [
|
19
21
|
"Template +#{template_name}+ could not be found in paths:",
|
20
|
-
lookup_paths.map { |path| " - #{path}"}
|
22
|
+
lookup_paths.map { |path| " - #{path}" }
|
21
23
|
].join("\n\n")
|
22
24
|
|
23
25
|
super(msg)
|
data/lib/dry/view/exposure.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "dry
|
3
|
+
require "dry/core/equalizer"
|
4
4
|
|
5
5
|
module Dry
|
6
6
|
class View
|
@@ -10,8 +10,8 @@ module Dry
|
|
10
10
|
class Exposure
|
11
11
|
include Dry::Equalizer(:name, :proc, :object, :options)
|
12
12
|
|
13
|
-
EXPOSURE_DEPENDENCY_PARAMETER_TYPES = [
|
14
|
-
INPUT_PARAMETER_TYPES = [
|
13
|
+
EXPOSURE_DEPENDENCY_PARAMETER_TYPES = %i[req opt].freeze
|
14
|
+
INPUT_PARAMETER_TYPES = %i[key keyreq keyrest].freeze
|
15
15
|
|
16
16
|
attr_reader :name
|
17
17
|
attr_reader :proc
|
@@ -26,7 +26,7 @@ module Dry
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def bind(obj)
|
29
|
-
self.class.new(name, proc, obj, options)
|
29
|
+
self.class.new(name, proc, obj, **options)
|
30
30
|
end
|
31
31
|
|
32
32
|
def dependency_names
|
@@ -76,23 +76,31 @@ module Dry
|
|
76
76
|
private
|
77
77
|
|
78
78
|
def call_proc(input, locals)
|
79
|
-
args = proc_args(input, locals)
|
80
|
-
|
81
|
-
if
|
82
|
-
proc.(
|
79
|
+
args, keywords = proc_args(input, locals)
|
80
|
+
|
81
|
+
if keywords.empty?
|
82
|
+
if proc.is_a?(Method)
|
83
|
+
proc.(*args)
|
84
|
+
else
|
85
|
+
object.instance_exec(*args, &proc)
|
86
|
+
end
|
83
87
|
else
|
84
|
-
|
88
|
+
if proc.is_a?(Method)
|
89
|
+
proc.(*args, **keywords)
|
90
|
+
else
|
91
|
+
object.instance_exec(*args, **keywords, &proc)
|
92
|
+
end
|
85
93
|
end
|
86
94
|
end
|
87
95
|
|
88
96
|
def proc_args(input, locals)
|
89
97
|
dependency_args = proc_dependency_args(locals)
|
90
|
-
|
98
|
+
keywords = proc_input_args(input)
|
91
99
|
|
92
|
-
if
|
93
|
-
dependency_args
|
100
|
+
if keywords.empty?
|
101
|
+
[dependency_args, {}]
|
94
102
|
else
|
95
|
-
dependency_args
|
103
|
+
[dependency_args, keywords]
|
96
104
|
end
|
97
105
|
end
|
98
106
|
|
data/lib/dry/view/exposures.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "tsort"
|
4
|
-
require "dry/equalizer"
|
4
|
+
require "dry/core/equalizer"
|
5
5
|
require "dry/view/exposure"
|
6
6
|
|
7
7
|
module Dry
|
@@ -30,7 +30,7 @@ module Dry
|
|
30
30
|
end
|
31
31
|
|
32
32
|
def add(name, proc = nil, **options)
|
33
|
-
exposures[name] = Exposure.new(name, proc, options)
|
33
|
+
exposures[name] = Exposure.new(name, proc, **options)
|
34
34
|
end
|
35
35
|
|
36
36
|
def import(name, exposure)
|
@@ -46,8 +46,9 @@ module Dry
|
|
46
46
|
end
|
47
47
|
|
48
48
|
def call(input)
|
49
|
+
# rubocop:disable Style/MultilineBlockChain
|
49
50
|
tsort.each_with_object({}) { |name, memo|
|
50
|
-
next unless exposure = self[name]
|
51
|
+
next unless (exposure = self[name])
|
51
52
|
|
52
53
|
value = exposure.(input, memo)
|
53
54
|
value = yield(value, exposure) if block_given?
|
@@ -56,6 +57,7 @@ module Dry
|
|
56
57
|
}.each_with_object({}) { |(name, value), memo|
|
57
58
|
memo[name] = value unless self[name].private?
|
58
59
|
}
|
60
|
+
# rubocop:enable Style/MultilineBlockChain
|
59
61
|
end
|
60
62
|
|
61
63
|
private
|
data/lib/dry/view/part.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "dry/equalizer"
|
3
|
+
require "dry/core/equalizer"
|
4
4
|
require_relative "decorated_attributes"
|
5
5
|
require_relative "render_environment_missing"
|
6
6
|
|
@@ -70,7 +70,11 @@ module Dry
|
|
70
70
|
# @param render_env [RenderEnvironment] render environment
|
71
71
|
#
|
72
72
|
# @api public
|
73
|
-
def initialize(
|
73
|
+
def initialize(
|
74
|
+
render_env: RenderEnvironmentMissing.new,
|
75
|
+
name: self.class.part_name(render_env.inflector),
|
76
|
+
value:
|
77
|
+
)
|
74
78
|
@_name = name
|
75
79
|
@_value = value
|
76
80
|
@_render_env = render_env
|
@@ -115,15 +119,18 @@ module Dry
|
|
115
119
|
# itself responds to `#render`.
|
116
120
|
#
|
117
121
|
# @param partial_name [Symbol, String] partial name
|
118
|
-
# @param as [Symbol] the name for the Part to assume in the partial's locals.
|
122
|
+
# @param as [Symbol] the name for the Part to assume in the partial's locals. Defaults to
|
123
|
+
# the Part's `_name`.
|
119
124
|
# @param locals [Hash<Symbol, Object>] other locals to provide the partial
|
120
125
|
#
|
121
126
|
# @return [String] rendered partial
|
122
127
|
#
|
123
128
|
# @api public
|
129
|
+
# rubocop:disable Naming/UncommunicativeMethodParamName
|
124
130
|
def _render(partial_name, as: _name, **locals, &block)
|
125
131
|
_render_env.partial(partial_name, _render_env.scope({as => self}.merge(locals)), &block)
|
126
132
|
end
|
133
|
+
# rubocop:enable Naming/UncommunicativeMethodParamName
|
127
134
|
|
128
135
|
# Builds a new scope with the part included in its locals.
|
129
136
|
#
|
@@ -133,7 +140,8 @@ module Dry
|
|
133
140
|
# A convenience alias for `#_scope`. Is available unless the value
|
134
141
|
# itself responds to `#scope`.
|
135
142
|
#
|
136
|
-
# @param scope_name [Symbol, nil] scope name, used by the scope builder to determine the
|
143
|
+
# @param scope_name [Symbol, nil] scope name, used by the scope builder to determine the
|
144
|
+
# scope class
|
137
145
|
# @param locals [Hash<Symbol, Object>] other locals to provide the partial
|
138
146
|
#
|
139
147
|
# @return [Dry::View::Scope] scope
|
@@ -168,12 +176,12 @@ module Dry
|
|
168
176
|
# @param options[Hash<Symbol, Object>] other options to provide when initializing the new part
|
169
177
|
#
|
170
178
|
# @api public
|
171
|
-
def new(klass =
|
179
|
+
def new(klass = self.class, name: _name, value: _value, **options)
|
172
180
|
klass.new(
|
173
181
|
name: name,
|
174
182
|
value: value,
|
175
183
|
render_env: _render_env,
|
176
|
-
**options
|
184
|
+
**options
|
177
185
|
)
|
178
186
|
end
|
179
187
|
|
@@ -199,6 +207,7 @@ module Dry
|
|
199
207
|
super
|
200
208
|
end
|
201
209
|
end
|
210
|
+
ruby2_keywords(:method_missing) if respond_to?(:ruby2_keywords, true)
|
202
211
|
|
203
212
|
def respond_to_missing?(name, include_private = false)
|
204
213
|
CONVENIENCE_METHODS.include?(name) || _value.respond_to?(name, include_private) || super
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "dry/core/cache"
|
4
|
-
require "dry/equalizer"
|
4
|
+
require "dry/core/equalizer"
|
5
5
|
require_relative "part"
|
6
6
|
|
7
7
|
module Dry
|
@@ -54,7 +54,7 @@ module Dry
|
|
54
54
|
klass.new(
|
55
55
|
name: name,
|
56
56
|
value: value,
|
57
|
-
render_env: render_env
|
57
|
+
render_env: render_env
|
58
58
|
)
|
59
59
|
end
|
60
60
|
|
@@ -69,11 +69,13 @@ module Dry
|
|
69
69
|
build_part(name, arr, **options.merge(as: collection_as))
|
70
70
|
end
|
71
71
|
|
72
|
+
# rubocop:disable Lint/UnusedMethodArgument
|
72
73
|
def collection_options(name:, **options)
|
73
74
|
collection_as = options[:as].is_a?(Array) ? options[:as].first : nil
|
74
75
|
|
75
76
|
options.merge(as: collection_as)
|
76
77
|
end
|
78
|
+
# rubocop:enable Lint/UnusedMethodArgument
|
77
79
|
|
78
80
|
def collection_item_options(name:, **options)
|
79
81
|
singular_name = inflector.singularize(name).to_sym
|
@@ -90,7 +92,7 @@ module Dry
|
|
90
92
|
|
91
93
|
options.merge(
|
92
94
|
name: singular_name,
|
93
|
-
as: singular_as
|
95
|
+
as: singular_as
|
94
96
|
)
|
95
97
|
end
|
96
98
|
|
@@ -106,6 +108,7 @@ module Dry
|
|
106
108
|
end
|
107
109
|
end
|
108
110
|
|
111
|
+
# rubocop:disable Metrics/PerceivedComplexity
|
109
112
|
def resolve_part_class(name:, fallback_class:)
|
110
113
|
return fallback_class unless namespace
|
111
114
|
|
@@ -114,7 +117,7 @@ module Dry
|
|
114
117
|
# Give autoloaders a chance to act
|
115
118
|
begin
|
116
119
|
klass = namespace.const_get(name)
|
117
|
-
rescue NameError
|
120
|
+
rescue NameError # rubocop:disable Lint/HandleExceptions
|
118
121
|
end
|
119
122
|
|
120
123
|
if !klass && namespace.const_defined?(name, false)
|
@@ -127,6 +130,7 @@ module Dry
|
|
127
130
|
fallback_class
|
128
131
|
end
|
129
132
|
end
|
133
|
+
# rubocop:enable Metrics/PerceivedComplexity
|
130
134
|
|
131
135
|
def inflector
|
132
136
|
render_env.inflector
|
data/lib/dry/view/path.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "dry/equalizer"
|
3
|
+
require "dry/core/equalizer"
|
4
4
|
|
5
5
|
module Dry
|
6
6
|
class View
|
@@ -12,7 +12,7 @@ module Dry
|
|
12
12
|
inflector: config.inflector,
|
13
13
|
context: context,
|
14
14
|
scope_builder: config.scope_builder.new(namespace: config.scope_namespace),
|
15
|
-
part_builder: config.part_builder.new(namespace: config.part_namespace)
|
15
|
+
part_builder: config.part_builder.new(namespace: config.part_namespace)
|
16
16
|
)
|
17
17
|
end
|
18
18
|
|
@@ -36,7 +36,7 @@ module Dry
|
|
36
36
|
part_builder.(name, value, **options)
|
37
37
|
end
|
38
38
|
|
39
|
-
def scope(name = nil, locals)
|
39
|
+
def scope(name = nil, locals) # rubocop:disable Style/OptionalArguments
|
40
40
|
scope_builder.(name, locals)
|
41
41
|
end
|
42
42
|
|
@@ -54,7 +54,7 @@ module Dry
|
|
54
54
|
inflector: inflector,
|
55
55
|
context: context,
|
56
56
|
scope_builder: scope_builder,
|
57
|
-
part_builder: part_builder
|
57
|
+
part_builder: part_builder
|
58
58
|
)
|
59
59
|
end
|
60
60
|
end
|
@@ -20,19 +20,19 @@ module Dry
|
|
20
20
|
raise MissingEnvironmentError
|
21
21
|
end
|
22
22
|
|
23
|
-
def part(
|
23
|
+
def part(_name, _value, **_options)
|
24
24
|
raise MissingEnvironmentError
|
25
25
|
end
|
26
26
|
|
27
|
-
def scope(
|
27
|
+
def scope(_name = nil, _locals) # rubocop:disable Style/OptionalArguments
|
28
28
|
raise MissingEnvironmentError
|
29
29
|
end
|
30
30
|
|
31
|
-
def template(
|
31
|
+
def template(_name, _scope)
|
32
32
|
raise MissingEnvironmentError
|
33
33
|
end
|
34
34
|
|
35
|
-
def partial(
|
35
|
+
def partial(_name, _scope)
|
36
36
|
raise MissingEnvironmentError
|
37
37
|
end
|
38
38
|
|
data/lib/dry/view/rendered.rb
CHANGED
data/lib/dry/view/renderer.rb
CHANGED
data/lib/dry/view/scope.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "dry/equalizer"
|
3
|
+
require "dry/core/equalizer"
|
4
4
|
require "dry/core/constants"
|
5
5
|
require_relative "render_environment_missing"
|
6
6
|
|
@@ -59,7 +59,11 @@ module Dry
|
|
59
59
|
# @return [Scope]
|
60
60
|
#
|
61
61
|
# @api public
|
62
|
-
def initialize(
|
62
|
+
def initialize(
|
63
|
+
name: nil,
|
64
|
+
locals: Dry::Core::Constants::EMPTY_HASH,
|
65
|
+
render_env: RenderEnvironmentMissing.new
|
66
|
+
)
|
63
67
|
@_name = name
|
64
68
|
@_locals = locals
|
65
69
|
@_render_env = render_env
|
@@ -83,10 +87,16 @@ module Dry
|
|
83
87
|
# @api public
|
84
88
|
def render(partial_name = nil, **locals, &block)
|
85
89
|
partial_name ||= _name
|
86
|
-
raise ArgumentError, "+partial_name+ must be provided for unnamed scopes" unless partial_name
|
87
|
-
partial_name = _inflector.underscore(_inflector.demodulize(partial_name.to_s)) if partial_name.is_a?(Class)
|
88
90
|
|
89
|
-
|
91
|
+
unless partial_name
|
92
|
+
raise ArgumentError, "+partial_name+ must be provided for unnamed scopes"
|
93
|
+
end
|
94
|
+
|
95
|
+
if partial_name.is_a?(Class)
|
96
|
+
partial_name = _inflector.underscore(_inflector.demodulize(partial_name.to_s))
|
97
|
+
end
|
98
|
+
|
99
|
+
_render_env.partial(partial_name, _render_scope(**locals), &block)
|
90
100
|
end
|
91
101
|
|
92
102
|
# Build a new scope using a scope class matching the provided name
|
@@ -150,9 +160,13 @@ module Dry
|
|
150
160
|
super
|
151
161
|
end
|
152
162
|
end
|
163
|
+
ruby2_keywords(:method_missing) if respond_to?(:ruby2_keywords, true)
|
153
164
|
|
154
165
|
def respond_to_missing?(name, include_private = false)
|
155
|
-
_locals.key?(name) ||
|
166
|
+
_locals.key?(name) ||
|
167
|
+
_render_env.context.respond_to?(name) ||
|
168
|
+
CONVENIENCE_METHODS.include?(name) ||
|
169
|
+
super
|
156
170
|
end
|
157
171
|
|
158
172
|
def _render_scope(**locals)
|
@@ -162,7 +176,7 @@ module Dry
|
|
162
176
|
self.class.new(
|
163
177
|
# FIXME: what about `name`?
|
164
178
|
locals: locals,
|
165
|
-
render_env: _render_env
|
179
|
+
render_env: _render_env
|
166
180
|
)
|
167
181
|
end
|
168
182
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "dry/core/cache"
|
4
|
-
require "dry/equalizer"
|
4
|
+
require "dry/core/equalizer"
|
5
5
|
require_relative "scope"
|
6
6
|
|
7
7
|
module Dry
|
@@ -46,11 +46,11 @@ module Dry
|
|
46
46
|
# @return [Dry::View::Scope]
|
47
47
|
#
|
48
48
|
# @api private
|
49
|
-
def call(name = nil, locals)
|
49
|
+
def call(name = nil, locals) # rubocop:disable Style/OptionalArguments
|
50
50
|
scope_class(name).new(
|
51
51
|
name: name,
|
52
52
|
locals: locals,
|
53
|
-
render_env: render_env
|
53
|
+
render_env: render_env
|
54
54
|
)
|
55
55
|
end
|
56
56
|
|
@@ -76,7 +76,7 @@ module Dry
|
|
76
76
|
# Give autoloaders a chance to act
|
77
77
|
begin
|
78
78
|
klass = namespace.const_get(name)
|
79
|
-
rescue NameError
|
79
|
+
rescue NameError # rubocop:disable Lint/HandleExceptions
|
80
80
|
end
|
81
81
|
|
82
82
|
if !klass && namespace.const_defined?(name, false)
|