hanami-view 2.3.1 → 3.0.0.rc1
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 +399 -184
- data/LICENSE +20 -0
- data/README.md +17 -22
- data/hanami-view.gemspec +19 -19
- data/lib/hanami/view/context.rb +11 -0
- data/lib/hanami/view/decorated_attributes.rb +0 -2
- data/lib/hanami/view/erb/filters/block.rb +2 -1
- data/lib/hanami/view/erb/filters/trimming.rb +14 -8
- data/lib/hanami/view/erb/parser.rb +5 -1
- data/lib/hanami/view/exposure.rb +5 -7
- data/lib/hanami/view/exposures.rb +6 -2
- data/lib/hanami/view/helpers/escape_helper.rb +3 -2
- data/lib/hanami/view/helpers/number_formatting_helper.rb +2 -4
- data/lib/hanami/view/helpers/tag_helper/tag_builder.rb +10 -7
- data/lib/hanami/view/helpers/tag_helper.rb +1 -3
- data/lib/hanami/view/html.rb +0 -2
- data/lib/hanami/view/html_safe_string_buffer.rb +1 -1
- data/lib/hanami/view/part.rb +2 -5
- data/lib/hanami/view/part_builder.rb +7 -9
- data/lib/hanami/view/renderer.rb +78 -28
- data/lib/hanami/view/rendering.rb +38 -22
- data/lib/hanami/view/rendering_missing.rb +11 -14
- data/lib/hanami/view/scope.rb +29 -15
- data/lib/hanami/view/scope_builder.rb +6 -6
- data/lib/hanami/view/tilt/haml_adapter.rb +1 -1
- data/lib/hanami/view/tilt/slim_adapter.rb +1 -1
- data/lib/hanami/view/version.rb +1 -2
- data/lib/hanami/view.rb +62 -30
- metadata +14 -53
|
@@ -3,54 +3,70 @@
|
|
|
3
3
|
module Hanami
|
|
4
4
|
class View
|
|
5
5
|
# @api private
|
|
6
|
-
# @since 2.1.0
|
|
7
6
|
class Rendering
|
|
8
7
|
# @api private
|
|
9
|
-
|
|
10
|
-
attr_reader :config, :format
|
|
8
|
+
attr_reader :format
|
|
11
9
|
|
|
12
|
-
# @api private
|
|
13
|
-
# @since 2.1.0
|
|
14
10
|
attr_reader :inflector, :part_builder, :scope_builder
|
|
15
11
|
|
|
16
|
-
|
|
17
|
-
|
|
12
|
+
attr_reader :part_class, :part_namespace, :scope_class, :scope_namespace
|
|
13
|
+
|
|
14
|
+
# Stable identity for the underlying config snapshot.
|
|
15
|
+
attr_reader :cache_key
|
|
16
|
+
|
|
18
17
|
attr_reader :context, :renderer
|
|
19
18
|
|
|
20
|
-
|
|
21
|
-
# @since 2.1.0
|
|
22
|
-
def initialize(config:, format:, context:)
|
|
23
|
-
@config = config
|
|
19
|
+
def initialize(config_data:, format:, context:)
|
|
24
20
|
@format = format
|
|
25
21
|
|
|
26
|
-
@inflector =
|
|
27
|
-
@part_builder =
|
|
28
|
-
@scope_builder =
|
|
22
|
+
@inflector = config_data.inflector
|
|
23
|
+
@part_builder = config_data.part_builder
|
|
24
|
+
@scope_builder = config_data.scope_builder
|
|
25
|
+
|
|
26
|
+
@part_class = config_data.part_class
|
|
27
|
+
@part_namespace = config_data.part_namespace
|
|
28
|
+
@scope_class = config_data.scope_class
|
|
29
|
+
@scope_namespace = config_data.scope_namespace
|
|
30
|
+
@cache_key = config_data.object_id
|
|
29
31
|
|
|
30
32
|
@context = context.dup_for_rendering(self)
|
|
31
|
-
@renderer = Renderer.new(
|
|
33
|
+
@renderer = Renderer.new(config_data)
|
|
32
34
|
end
|
|
33
35
|
|
|
36
|
+
# Returns the resolved name of the template or partial currently being rendered, or nil if
|
|
37
|
+
# no render is in progress.
|
|
38
|
+
#
|
|
39
|
+
# @return [String, nil]
|
|
40
|
+
#
|
|
41
|
+
# @api public
|
|
42
|
+
# @since x.x.x
|
|
43
|
+
def current_template_name
|
|
44
|
+
renderer.current_template_name
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Returns the stack of resolved names for the templates and partials currently being
|
|
48
|
+
# rendered.
|
|
49
|
+
#
|
|
50
|
+
# @return [Array<String>]
|
|
51
|
+
#
|
|
34
52
|
# @api private
|
|
35
|
-
# @since
|
|
53
|
+
# @since x.x.x
|
|
54
|
+
def current_template_names
|
|
55
|
+
renderer.current_template_names
|
|
56
|
+
end
|
|
57
|
+
|
|
36
58
|
def template(name, scope, &block)
|
|
37
59
|
renderer.template(name, format, scope, &block)
|
|
38
60
|
end
|
|
39
61
|
|
|
40
|
-
# @api private
|
|
41
|
-
# @since 2.1.0
|
|
42
62
|
def partial(name, scope, &block)
|
|
43
63
|
renderer.partial(name, format, scope, &block)
|
|
44
64
|
end
|
|
45
65
|
|
|
46
|
-
# @api private
|
|
47
|
-
# @since 2.1.0
|
|
48
66
|
def part(name, value, as: nil)
|
|
49
67
|
part_builder.(name, value, as: as, rendering: self)
|
|
50
68
|
end
|
|
51
69
|
|
|
52
|
-
# @api private
|
|
53
|
-
# @since 2.1.0
|
|
54
70
|
def scope(name = nil, locals) # rubocop:disable Style/OptionalArguments
|
|
55
71
|
scope_builder.(name, locals: locals, rendering: self)
|
|
56
72
|
end
|
|
@@ -8,47 +8,44 @@ module Hanami
|
|
|
8
8
|
# @api private
|
|
9
9
|
# @since 2.1.0
|
|
10
10
|
class RenderingMissing
|
|
11
|
-
# @api private
|
|
12
|
-
# @since 2.1.0
|
|
13
11
|
def format
|
|
14
12
|
raise RenderingMissingError
|
|
15
13
|
end
|
|
16
14
|
|
|
17
|
-
# @api private
|
|
18
|
-
# @since 2.1.0
|
|
19
15
|
def context
|
|
20
16
|
raise RenderingMissingError
|
|
21
17
|
end
|
|
22
18
|
|
|
23
|
-
# @api private
|
|
24
|
-
# @since 2.1.0
|
|
25
19
|
def part(_name, _value, **_options)
|
|
26
20
|
raise RenderingMissingError
|
|
27
21
|
end
|
|
28
22
|
|
|
29
|
-
# @api private
|
|
30
|
-
# @since 2.1.0
|
|
31
23
|
def scope(_name = nil, _locals) # rubocop:disable Style/OptionalArguments
|
|
32
24
|
raise RenderingMissingError
|
|
33
25
|
end
|
|
34
26
|
|
|
35
|
-
# @api private
|
|
36
|
-
# @since 2.1.0
|
|
37
27
|
def template(_name, _scope)
|
|
38
28
|
raise RenderingMissingError
|
|
39
29
|
end
|
|
40
30
|
|
|
41
|
-
# @api private
|
|
42
|
-
# @since 2.1.0
|
|
43
31
|
def partial(_name, _scope)
|
|
44
32
|
raise RenderingMissingError
|
|
45
33
|
end
|
|
46
34
|
|
|
47
|
-
# @api private
|
|
48
|
-
# @since 2.1.0
|
|
49
35
|
def inflector
|
|
50
36
|
@inflector ||= Dry::Inflector.new
|
|
51
37
|
end
|
|
38
|
+
|
|
39
|
+
def current_template_name
|
|
40
|
+
nil
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def current_template_names
|
|
44
|
+
EMPTY_TEMPLATE_NAMES
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
EMPTY_TEMPLATE_NAMES = [].freeze
|
|
48
|
+
private_constant :EMPTY_TEMPLATE_NAMES
|
|
52
49
|
end
|
|
53
50
|
end
|
|
54
51
|
end
|
data/lib/hanami/view/scope.rb
CHANGED
|
@@ -19,7 +19,7 @@ module Hanami
|
|
|
19
19
|
# @since 2.1.0
|
|
20
20
|
class Scope
|
|
21
21
|
# @api private
|
|
22
|
-
CONVENIENCE_METHODS = %i[format context locals].freeze
|
|
22
|
+
CONVENIENCE_METHODS = %i[format context locals template_name].freeze
|
|
23
23
|
|
|
24
24
|
include Dry::Equalizer(:_name, :_locals, :_rendering)
|
|
25
25
|
|
|
@@ -35,10 +35,10 @@ module Hanami
|
|
|
35
35
|
#
|
|
36
36
|
# @overload _locals
|
|
37
37
|
# Returns the locals.
|
|
38
|
+
# @return [Hash{Symbol => Object}]
|
|
38
39
|
# @overload locals
|
|
39
40
|
# A convenience alias for `#_locals.` Is available unless there is a local named `locals`
|
|
40
|
-
#
|
|
41
|
-
# @return [Hash[<Symbol, Object>]
|
|
41
|
+
# @return [Hash{Symbol => Object}]
|
|
42
42
|
#
|
|
43
43
|
# @api public
|
|
44
44
|
# @since 2.1.0
|
|
@@ -76,16 +76,16 @@ module Hanami
|
|
|
76
76
|
# Renders a partial using the scope.
|
|
77
77
|
#
|
|
78
78
|
# @param partial_name [Symbol, String] partial name
|
|
79
|
-
# @param locals [Hash
|
|
79
|
+
# @param locals [Hash{Symbol => Object}] partial locals
|
|
80
80
|
# @yieldreturn [String] string content to include where the partial calls `yield`
|
|
81
|
+
# @return [String] the rendered partial output
|
|
81
82
|
#
|
|
82
83
|
# @overload render(**locals, &block)
|
|
83
84
|
# Renders a partial (named after the scope's own name) using the scope.
|
|
84
85
|
#
|
|
85
|
-
# @param locals[Hash
|
|
86
|
+
# @param locals [Hash{Symbol => Object}] partial locals
|
|
86
87
|
# @yieldreturn [String] string content to include where the partial calls `yield`
|
|
87
|
-
#
|
|
88
|
-
# @return [String] the rendered partial output
|
|
88
|
+
# @return [String] the rendered partial output
|
|
89
89
|
#
|
|
90
90
|
# @api public
|
|
91
91
|
# @since 2.1.0
|
|
@@ -120,11 +120,10 @@ module Hanami
|
|
|
120
120
|
#
|
|
121
121
|
# @overload _format
|
|
122
122
|
# Returns the format.
|
|
123
|
+
# @return [Symbol] format
|
|
123
124
|
# @overload format
|
|
124
|
-
# A convenience alias for `#_format.` Is available unless there is a
|
|
125
|
-
#
|
|
126
|
-
#
|
|
127
|
-
# @return [Symbol] format
|
|
125
|
+
# A convenience alias for `#_format.` Is available unless there is a local named `format`.
|
|
126
|
+
# @return [Symbol] format
|
|
128
127
|
#
|
|
129
128
|
# @api public
|
|
130
129
|
# @since 2.1.0
|
|
@@ -136,11 +135,10 @@ module Hanami
|
|
|
136
135
|
#
|
|
137
136
|
# @overload _context
|
|
138
137
|
# Returns the context.
|
|
138
|
+
# @return [Context] context
|
|
139
139
|
# @overload context
|
|
140
|
-
# A convenience alias for `#_context`. Is available unless there is a
|
|
141
|
-
#
|
|
142
|
-
#
|
|
143
|
-
# @return [Context] context
|
|
140
|
+
# A convenience alias for `#_context`. Is available unless there is a local named `context`.
|
|
141
|
+
# @return [Context] context
|
|
144
142
|
#
|
|
145
143
|
# @api public
|
|
146
144
|
# @since 2.1.0
|
|
@@ -148,6 +146,22 @@ module Hanami
|
|
|
148
146
|
_rendering.context
|
|
149
147
|
end
|
|
150
148
|
|
|
149
|
+
# Returns the name of the template or partial currently being rendered.
|
|
150
|
+
#
|
|
151
|
+
# @overload _template_name
|
|
152
|
+
# Returns the current template name.
|
|
153
|
+
# @return [String, nil]
|
|
154
|
+
# @overload template_name
|
|
155
|
+
# A convenience alias for `#_template_name`. Is available unless there is a local named
|
|
156
|
+
# `template_name`.
|
|
157
|
+
# @return [String, nil]
|
|
158
|
+
#
|
|
159
|
+
# @api public
|
|
160
|
+
# @since x.x.x
|
|
161
|
+
def _template_name
|
|
162
|
+
_rendering.current_template_name
|
|
163
|
+
end
|
|
164
|
+
|
|
151
165
|
private
|
|
152
166
|
|
|
153
167
|
# Handles missing methods, according to the following rules:
|
|
@@ -17,7 +17,7 @@ module Hanami
|
|
|
17
17
|
#
|
|
18
18
|
# @api public
|
|
19
19
|
# @since 2.1.0
|
|
20
|
-
def call(name = nil, locals:, rendering:)
|
|
20
|
+
def call(name = nil, locals:, rendering:)
|
|
21
21
|
klass = scope_class(name, rendering: rendering)
|
|
22
22
|
|
|
23
23
|
klass.new(name: name, locals: locals, rendering: rendering)
|
|
@@ -27,11 +27,11 @@ module Hanami
|
|
|
27
27
|
|
|
28
28
|
def scope_class(name = nil, rendering:)
|
|
29
29
|
if name.nil?
|
|
30
|
-
rendering.
|
|
30
|
+
rendering.scope_class
|
|
31
31
|
elsif name.is_a?(Class)
|
|
32
32
|
name
|
|
33
33
|
else
|
|
34
|
-
View.cache.fetch_or_store(name, rendering.
|
|
34
|
+
View.cache.fetch_or_store(name, rendering.cache_key) do
|
|
35
35
|
resolve_scope_class(name: name, rendering: rendering)
|
|
36
36
|
end
|
|
37
37
|
end
|
|
@@ -40,12 +40,12 @@ module Hanami
|
|
|
40
40
|
def resolve_scope_class(name:, rendering:)
|
|
41
41
|
name = rendering.inflector.camelize(name.to_s)
|
|
42
42
|
|
|
43
|
-
namespace = rendering.
|
|
43
|
+
namespace = rendering.scope_namespace
|
|
44
44
|
|
|
45
45
|
# Give autoloaders a chance to act
|
|
46
46
|
begin
|
|
47
47
|
klass = namespace.const_get(name)
|
|
48
|
-
rescue NameError # rubocop:disable Lint/
|
|
48
|
+
rescue NameError # rubocop:disable Lint/SuppressedException
|
|
49
49
|
end
|
|
50
50
|
|
|
51
51
|
if !klass && namespace.const_defined?(name, false)
|
|
@@ -55,7 +55,7 @@ module Hanami
|
|
|
55
55
|
if klass && klass < Scope
|
|
56
56
|
klass
|
|
57
57
|
else
|
|
58
|
-
rendering.
|
|
58
|
+
rendering.scope_class
|
|
59
59
|
end
|
|
60
60
|
end
|
|
61
61
|
end
|
data/lib/hanami/view/version.rb
CHANGED
data/lib/hanami/view.rb
CHANGED
|
@@ -22,7 +22,6 @@ module Hanami
|
|
|
22
22
|
# @since 2.1.0
|
|
23
23
|
class View
|
|
24
24
|
# @api private
|
|
25
|
-
# @since 2.1.0
|
|
26
25
|
def self.gem_loader
|
|
27
26
|
@gem_loader ||= Zeitwerk::Loader.new.tap do |loader|
|
|
28
27
|
root = File.expand_path("..", __dir__)
|
|
@@ -31,13 +30,13 @@ module Hanami
|
|
|
31
30
|
loader.ignore(
|
|
32
31
|
"#{root}/hanami-view.rb",
|
|
33
32
|
"#{root}/hanami/view/version.rb",
|
|
34
|
-
"#{root}/hanami/view/errors.rb"
|
|
33
|
+
"#{root}/hanami/view/errors.rb"
|
|
35
34
|
)
|
|
36
35
|
loader.inflector = Zeitwerk::GemInflector.new("#{root}/hanami-view.rb")
|
|
37
36
|
loader.inflector.inflect(
|
|
38
37
|
"erb" => "ERB",
|
|
39
38
|
"html" => "HTML",
|
|
40
|
-
"html_safe_string_buffer" => "HTMLSafeStringBuffer"
|
|
39
|
+
"html_safe_string_buffer" => "HTMLSafeStringBuffer"
|
|
41
40
|
)
|
|
42
41
|
end
|
|
43
42
|
end
|
|
@@ -45,7 +44,6 @@ module Hanami
|
|
|
45
44
|
gem_loader.setup
|
|
46
45
|
|
|
47
46
|
# @api private
|
|
48
|
-
# @since 2.1.0
|
|
49
47
|
DEFAULT_RENDERER_OPTIONS = {default_encoding: "utf-8"}.freeze
|
|
50
48
|
|
|
51
49
|
include Dry::Equalizer(:config, :exposures)
|
|
@@ -235,6 +233,23 @@ module Hanami
|
|
|
235
233
|
# @!scope class
|
|
236
234
|
setting :inflector, default: Dry::Inflector.new
|
|
237
235
|
|
|
236
|
+
# @overload config.decorate_exposures=(value)
|
|
237
|
+
# Controls whether exposures are decorated by default.
|
|
238
|
+
#
|
|
239
|
+
# When set to `true`, all exposures will be decorated with matching Parts unless explicitly
|
|
240
|
+
# marked with `decorate: false`.
|
|
241
|
+
#
|
|
242
|
+
# When set to `false` (the default), exposures will not be decorated unless explicitly marked
|
|
243
|
+
# with `decorate: true`, or declared with `decorate`.
|
|
244
|
+
#
|
|
245
|
+
# Defaults to `false`.
|
|
246
|
+
#
|
|
247
|
+
# @param value [Boolean] whether to decorate exposures by default
|
|
248
|
+
# @api public
|
|
249
|
+
# @since x.x.x
|
|
250
|
+
# @!scope class
|
|
251
|
+
setting :decorate_exposures, default: false
|
|
252
|
+
|
|
238
253
|
# @overload config.renderer_options=(options)
|
|
239
254
|
# A hash of options to pass to the template engine. Template engines are
|
|
240
255
|
# provided by Tilt; see Tilt's documentation for what options your
|
|
@@ -273,7 +288,6 @@ module Hanami
|
|
|
273
288
|
# @!endgroup
|
|
274
289
|
|
|
275
290
|
# @api private
|
|
276
|
-
# @since 2.1.0
|
|
277
291
|
def self.inherited(klass)
|
|
278
292
|
super
|
|
279
293
|
|
|
@@ -288,13 +302,13 @@ module Hanami
|
|
|
288
302
|
# @param options [Hash] the exposure's options
|
|
289
303
|
# @option options [Boolean] :layout expose this value to the layout (defaults to false)
|
|
290
304
|
# @option options [Boolean] :decorate decorate this value in a matching Part (defaults to
|
|
291
|
-
#
|
|
305
|
+
# false, or the value of `config.decorate_exposures`)
|
|
292
306
|
# @option options [Symbol, Class] :as an alternative name or class to use when finding a
|
|
293
307
|
# matching Part
|
|
294
308
|
|
|
295
309
|
# @overload expose(name, **options, &block)
|
|
296
310
|
# Define a value to be passed to the template. The return value of the
|
|
297
|
-
# block will be
|
|
311
|
+
# block will be passed to the template.
|
|
298
312
|
#
|
|
299
313
|
# The block will be evaluated with the view instance as its `self`. The
|
|
300
314
|
# block's parameters will determine what it is given:
|
|
@@ -329,8 +343,8 @@ module Hanami
|
|
|
329
343
|
#
|
|
330
344
|
# @overload expose(name, **options)
|
|
331
345
|
# Define a value to be passed to the template, provided by an instance
|
|
332
|
-
# method matching the name. The method's return value will be
|
|
333
|
-
#
|
|
346
|
+
# method matching the name. The method's return value will be passed to
|
|
347
|
+
# the template.
|
|
334
348
|
#
|
|
335
349
|
# The method's parameters will determine what it is given:
|
|
336
350
|
#
|
|
@@ -369,8 +383,8 @@ module Hanami
|
|
|
369
383
|
#
|
|
370
384
|
# @overload expose(name, **options)
|
|
371
385
|
# Define a single value to pass through from the input data (when there is
|
|
372
|
-
# no instance method matching the `name`). This value will be
|
|
373
|
-
#
|
|
386
|
+
# no instance method matching the `name`). This value will be passed to
|
|
387
|
+
# the template.
|
|
374
388
|
#
|
|
375
389
|
# @param name [Symbol] name for the exposure
|
|
376
390
|
# @macro exposure_options
|
|
@@ -380,7 +394,7 @@ module Hanami
|
|
|
380
394
|
# @overload expose(*names, **options)
|
|
381
395
|
# Define multiple values to pass through from the input data (when there
|
|
382
396
|
# is no instance methods matching their names). These values will be
|
|
383
|
-
#
|
|
397
|
+
# passed through to the template.
|
|
384
398
|
#
|
|
385
399
|
# The provided options will be applied to all the exposures.
|
|
386
400
|
#
|
|
@@ -411,12 +425,23 @@ module Hanami
|
|
|
411
425
|
expose(*names, **options, private: true, &block)
|
|
412
426
|
end
|
|
413
427
|
|
|
428
|
+
# Defines an exposure that will be decorated with a matching Part.
|
|
429
|
+
#
|
|
430
|
+
# This is a shorthand for `expose(..., decorate: true)`.
|
|
431
|
+
#
|
|
432
|
+
# @see expose
|
|
433
|
+
#
|
|
434
|
+
# @api public
|
|
435
|
+
# @since 2.1.0
|
|
436
|
+
def self.decorate(*names, **options, &block)
|
|
437
|
+
expose(*names, **options, decorate: true, &block)
|
|
438
|
+
end
|
|
439
|
+
|
|
414
440
|
# Returns the defined exposures. These are unbound, since bound exposures
|
|
415
441
|
# are only created when initializing a View instance.
|
|
416
442
|
#
|
|
417
443
|
# @return [Exposures]
|
|
418
444
|
# @api private
|
|
419
|
-
# @since 2.1.0
|
|
420
445
|
def self.exposures
|
|
421
446
|
@exposures ||= Exposures.new
|
|
422
447
|
end
|
|
@@ -512,13 +537,6 @@ module Hanami
|
|
|
512
537
|
# @!endgroup
|
|
513
538
|
|
|
514
539
|
# @api private
|
|
515
|
-
# @since 2.1.0
|
|
516
|
-
def self.layout_path(layout)
|
|
517
|
-
File.join(*[config.layouts_dir, layout].compact)
|
|
518
|
-
end
|
|
519
|
-
|
|
520
|
-
# @api private
|
|
521
|
-
# @since 2.1.0
|
|
522
540
|
def self.cache
|
|
523
541
|
Cache
|
|
524
542
|
end
|
|
@@ -534,6 +552,7 @@ module Hanami
|
|
|
534
552
|
self.class.config.finalize!
|
|
535
553
|
ensure_config
|
|
536
554
|
|
|
555
|
+
@config_data = config.to_data
|
|
537
556
|
@exposures = self.class.exposures.bind(self)
|
|
538
557
|
end
|
|
539
558
|
|
|
@@ -550,8 +569,7 @@ module Hanami
|
|
|
550
569
|
# @return [Exposures]
|
|
551
570
|
#
|
|
552
571
|
# @api private
|
|
553
|
-
#
|
|
554
|
-
def exposures
|
|
572
|
+
def exposures # rubocop:disable Style/TrivialAccessors
|
|
555
573
|
@exposures
|
|
556
574
|
end
|
|
557
575
|
|
|
@@ -566,16 +584,20 @@ module Hanami
|
|
|
566
584
|
#
|
|
567
585
|
# @api public
|
|
568
586
|
# @since 2.1.0
|
|
569
|
-
def call(format:
|
|
587
|
+
def call(format: config_data.default_format,
|
|
588
|
+
context: config_data.default_context,
|
|
589
|
+
layout: config_data.layout,
|
|
590
|
+
**input)
|
|
570
591
|
rendering = self.rendering(format: format, context: context)
|
|
592
|
+
scope_class = config_data.scope
|
|
571
593
|
|
|
572
594
|
locals = locals(rendering, input)
|
|
573
|
-
output = rendering.template(
|
|
595
|
+
output = rendering.template(config_data.template, rendering.scope(scope_class, locals))
|
|
574
596
|
|
|
575
597
|
if layout
|
|
576
598
|
output = rendering.template(
|
|
577
|
-
|
|
578
|
-
rendering.scope(
|
|
599
|
+
layout_path(layout),
|
|
600
|
+
rendering.scope(scope_class, layout_locals(locals))
|
|
579
601
|
) { output }
|
|
580
602
|
end
|
|
581
603
|
|
|
@@ -583,13 +605,18 @@ module Hanami
|
|
|
583
605
|
end
|
|
584
606
|
|
|
585
607
|
# @api private
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
Rendering.new(config: config, format: format, context: context)
|
|
608
|
+
def rendering(format: config_data.default_format, context: config_data.default_context)
|
|
609
|
+
Rendering.new(config_data:, format:, context:)
|
|
589
610
|
end
|
|
590
611
|
|
|
591
612
|
private
|
|
592
613
|
|
|
614
|
+
# Frozen Data snapshot of the view's resolved configuration values.
|
|
615
|
+
# Used for fast hot-path reads during rendering.
|
|
616
|
+
#
|
|
617
|
+
# @api private
|
|
618
|
+
attr_reader :config_data
|
|
619
|
+
|
|
593
620
|
def ensure_config
|
|
594
621
|
raise UndefinedConfigError, :paths unless Array(config.paths).any?
|
|
595
622
|
raise UndefinedConfigError, :template unless config.template
|
|
@@ -597,7 +624,7 @@ module Hanami
|
|
|
597
624
|
|
|
598
625
|
def locals(rendering, input)
|
|
599
626
|
exposures.(context: rendering.context, **input) do |value, exposure|
|
|
600
|
-
if exposure.decorate? && value
|
|
627
|
+
if exposure.decorate?(default: config_data.decorate_exposures) && value
|
|
601
628
|
rendering.part(exposure.name, value, as: exposure.options[:as])
|
|
602
629
|
else
|
|
603
630
|
value
|
|
@@ -605,6 +632,11 @@ module Hanami
|
|
|
605
632
|
end
|
|
606
633
|
end
|
|
607
634
|
|
|
635
|
+
# @api private
|
|
636
|
+
def layout_path(layout)
|
|
637
|
+
File.join(*[config_data.layouts_dir, layout].compact)
|
|
638
|
+
end
|
|
639
|
+
|
|
608
640
|
def layout_locals(locals)
|
|
609
641
|
locals.each_with_object({}) do |(key, value), layout_locals|
|
|
610
642
|
layout_locals[key] = value if exposures[key].for_layout?
|
metadata
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: hanami-view
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 3.0.0.rc1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Hanakai team
|
|
8
|
-
bindir:
|
|
8
|
+
bindir: exe
|
|
9
9
|
cert_chain: []
|
|
10
10
|
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
@@ -15,14 +15,14 @@ dependencies:
|
|
|
15
15
|
requirements:
|
|
16
16
|
- - "~>"
|
|
17
17
|
- !ruby/object:Gem::Version
|
|
18
|
-
version: '1.
|
|
18
|
+
version: '1.4'
|
|
19
19
|
type: :runtime
|
|
20
20
|
prerelease: false
|
|
21
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
22
22
|
requirements:
|
|
23
23
|
- - "~>"
|
|
24
24
|
- !ruby/object:Gem::Version
|
|
25
|
-
version: '1.
|
|
25
|
+
version: '1.4'
|
|
26
26
|
- !ruby/object:Gem::Dependency
|
|
27
27
|
name: dry-core
|
|
28
28
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -105,57 +105,19 @@ dependencies:
|
|
|
105
105
|
- - "~>"
|
|
106
106
|
- !ruby/object:Gem::Version
|
|
107
107
|
version: '2.6'
|
|
108
|
-
- !ruby/object:Gem::Dependency
|
|
109
|
-
name: bundler
|
|
110
|
-
requirement: !ruby/object:Gem::Requirement
|
|
111
|
-
requirements:
|
|
112
|
-
- - ">="
|
|
113
|
-
- !ruby/object:Gem::Version
|
|
114
|
-
version: '0'
|
|
115
|
-
type: :development
|
|
116
|
-
prerelease: false
|
|
117
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
118
|
-
requirements:
|
|
119
|
-
- - ">="
|
|
120
|
-
- !ruby/object:Gem::Version
|
|
121
|
-
version: '0'
|
|
122
|
-
- !ruby/object:Gem::Dependency
|
|
123
|
-
name: rake
|
|
124
|
-
requirement: !ruby/object:Gem::Requirement
|
|
125
|
-
requirements:
|
|
126
|
-
- - ">="
|
|
127
|
-
- !ruby/object:Gem::Version
|
|
128
|
-
version: '0'
|
|
129
|
-
type: :development
|
|
130
|
-
prerelease: false
|
|
131
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
132
|
-
requirements:
|
|
133
|
-
- - ">="
|
|
134
|
-
- !ruby/object:Gem::Version
|
|
135
|
-
version: '0'
|
|
136
|
-
- !ruby/object:Gem::Dependency
|
|
137
|
-
name: rspec
|
|
138
|
-
requirement: !ruby/object:Gem::Requirement
|
|
139
|
-
requirements:
|
|
140
|
-
- - ">="
|
|
141
|
-
- !ruby/object:Gem::Version
|
|
142
|
-
version: '0'
|
|
143
|
-
type: :development
|
|
144
|
-
prerelease: false
|
|
145
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
146
|
-
requirements:
|
|
147
|
-
- - ">="
|
|
148
|
-
- !ruby/object:Gem::Version
|
|
149
|
-
version: '0'
|
|
150
108
|
description: A complete, standalone view rendering system that gives you everything
|
|
151
109
|
you need to write well-factored view code
|
|
152
110
|
email:
|
|
153
111
|
- info@hanakai.org
|
|
154
112
|
executables: []
|
|
155
113
|
extensions: []
|
|
156
|
-
extra_rdoc_files:
|
|
114
|
+
extra_rdoc_files:
|
|
115
|
+
- CHANGELOG.md
|
|
116
|
+
- LICENSE
|
|
117
|
+
- README.md
|
|
157
118
|
files:
|
|
158
119
|
- CHANGELOG.md
|
|
120
|
+
- LICENSE
|
|
159
121
|
- README.md
|
|
160
122
|
- hanami-view.gemspec
|
|
161
123
|
- lib/hanami-view.rb
|
|
@@ -194,11 +156,10 @@ homepage: https://hanamirb.org
|
|
|
194
156
|
licenses:
|
|
195
157
|
- MIT
|
|
196
158
|
metadata:
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
bug_tracker_uri: https://github.com/hanami/view/issues
|
|
159
|
+
changelog_uri: https://github.com/hanami/hanami-view/blob/main/CHANGELOG.md
|
|
160
|
+
source_code_uri: https://github.com/hanami/hanami-view
|
|
161
|
+
bug_tracker_uri: https://github.com/hanami/hanami-view/issues
|
|
162
|
+
funding_uri: https://github.com/sponsors/hanami
|
|
202
163
|
rdoc_options: []
|
|
203
164
|
require_paths:
|
|
204
165
|
- lib
|
|
@@ -206,7 +167,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
206
167
|
requirements:
|
|
207
168
|
- - ">="
|
|
208
169
|
- !ruby/object:Gem::Version
|
|
209
|
-
version: '3.
|
|
170
|
+
version: '3.3'
|
|
210
171
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
211
172
|
requirements:
|
|
212
173
|
- - ">="
|