hanami 2.1.0.beta2.1 → 2.1.0.rc2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +30 -0
- data/hanami.gemspec +3 -3
- data/lib/hanami/config/actions.rb +16 -3
- data/lib/hanami/config/assets.rb +1 -1
- data/lib/hanami/config/views.rb +10 -2
- data/lib/hanami/config.rb +21 -12
- data/lib/hanami/extensions/action/slice_configured_action.rb +5 -5
- data/lib/hanami/extensions/action.rb +4 -4
- data/lib/hanami/extensions/view/context.rb +111 -19
- data/lib/hanami/extensions/view/part.rb +64 -3
- data/lib/hanami/extensions/view/scope.rb +7 -0
- data/lib/hanami/extensions/view/slice_configured_context.rb +12 -8
- data/lib/hanami/extensions/view/slice_configured_helpers.rb +12 -1
- data/lib/hanami/extensions/view/slice_configured_part.rb +71 -0
- data/lib/hanami/extensions/view/slice_configured_view.rb +14 -6
- data/lib/hanami/extensions/view/standard_helpers.rb +4 -0
- data/lib/hanami/extensions/view.rb +5 -3
- data/lib/hanami/helpers/assets_helper.rb +47 -79
- data/lib/hanami/routes.rb +33 -2
- data/lib/hanami/slice.rb +12 -2
- data/lib/hanami/slice_registrar.rb +48 -23
- data/lib/hanami/version.rb +1 -1
- data/lib/hanami/web/rack_logger.rb +70 -2
- data/lib/hanami/web/welcome.html.erb +203 -0
- data/lib/hanami/web/welcome.rb +46 -0
- data/spec/integration/assets/assets_spec.rb +14 -3
- data/spec/integration/logging/request_logging_spec.rb +65 -7
- data/spec/integration/rack_app/method_override_spec.rb +97 -0
- data/spec/integration/slices_spec.rb +275 -5
- data/spec/integration/view/context/assets_spec.rb +0 -8
- data/spec/integration/view/context/inflector_spec.rb +0 -8
- data/spec/integration/view/context/settings_spec.rb +0 -8
- data/spec/integration/view/helpers/part_helpers_spec.rb +2 -2
- data/spec/integration/view/helpers/user_defined_helpers/part_helpers_spec.rb +10 -10
- data/spec/integration/view/parts/default_rendering_spec.rb +138 -0
- data/spec/integration/web/welcome_view_spec.rb +84 -0
- data/spec/support/app_integration.rb +22 -4
- data/spec/unit/hanami/config/render_detailed_errors_spec.rb +1 -1
- data/spec/unit/hanami/helpers/assets_helper/{audio_spec.rb → audio_tag_spec.rb} +10 -14
- data/spec/unit/hanami/helpers/assets_helper/{favicon_spec.rb → favicon_tag_spec.rb} +7 -11
- data/spec/unit/hanami/helpers/assets_helper/{image_spec.rb → image_tag_spec.rb} +8 -12
- data/spec/unit/hanami/helpers/assets_helper/{javascript_spec.rb → javascript_tag_spec.rb} +14 -18
- data/spec/unit/hanami/helpers/assets_helper/{stylesheet_spec.rb → stylesheet_tag_spec.rb} +12 -16
- data/spec/unit/hanami/helpers/assets_helper/{video_spec.rb → video_tag_spec.rb} +11 -11
- data/spec/unit/hanami/version_spec.rb +1 -1
- metadata +28 -19
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8a6835d72654251d1461ea2ad61c9fe56ad9b37b0ff333d23dc444e205b32ab1
|
4
|
+
data.tar.gz: 3daf6e28931aa6abf0c3579d95c8e403c1ba12bbcb5879549825e03ae8e81556
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4b79171920231066598260223766e9abaee75806c751bcf83ca9ddaa93ef2eabef1fabc3077674cb81f25e435fa8659a04f9c272200a4ed27fa02c271ac03531
|
7
|
+
data.tar.gz: 04072a74f320abda02874ace16c616db0f3db9bb63de4d3b00746f3c1898c1dc58a143abd47915c9ef0a32b0a5eda860bd9264bccd375779d87bb101e4686dc1
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,36 @@
|
|
2
2
|
|
3
3
|
The web, with simplicity.
|
4
4
|
|
5
|
+
## Changed
|
6
|
+
|
7
|
+
- [Tim Riley] Enable `config.render_detailed_errors` in development mode only by default. (#1365)
|
8
|
+
- [Tim Riley] Remove current_path from context (#1362)
|
9
|
+
|
10
|
+
## v2.1.0.rc1 - 2023-11-01
|
11
|
+
|
12
|
+
### Added
|
13
|
+
|
14
|
+
- [Aaron Moodie & Tim Riley] Render a welcome page when no routes are defined (#1353)
|
15
|
+
- [Luca Guidi] Allow _Method Override_ by default, by mounting `Rack::MethodOverride` middleware. (#1344)
|
16
|
+
|
17
|
+
### Fixed
|
18
|
+
|
19
|
+
- [Luca Guidi] Ensure compatibility with Ruby Logger from stdlib (#1352)
|
20
|
+
|
21
|
+
### Changed
|
22
|
+
|
23
|
+
- [Philip Arndt] Add support for a slice's class definition file to exist inside either `config/slices/[slice_name].rb` or `slices/[slice_name]/config/slice.rb`, in that order of precedence, so that a slice can provide its own definition which the app, or the slice's parent slice if that exists, can override if needed.
|
24
|
+
- [Tim Riley] Use `helpers` prefix to access helper methods from view parts (e.g. `helpers.format_number`)
|
25
|
+
- [Tim Riley] Make it possible to directly initialize view parts to ease their unit tests (#1357)
|
26
|
+
- [Tim Riley] Remove short names for assets helpers (#1356):
|
27
|
+
- Keep `javascript_tag` (remove `javascript` and `js` aliases)
|
28
|
+
- Keep `stylesheet_tag` (renamed from `stylesheet_link_tag`; remove `stylesheet` and `css` aliases)
|
29
|
+
- Keep `favicon_tag` (renamed from `favicon_link_tag`; remove `favicon` alias)
|
30
|
+
- Keep `image_tag` (remove `image` alias)
|
31
|
+
- Keep `video_tag` (remove `video` alias)
|
32
|
+
- Keep `audio_tag` (remove `audio` alias)
|
33
|
+
|
34
|
+
|
5
35
|
## v2.1.0.beta2.1 - 2023-10-04
|
6
36
|
|
7
37
|
### Added
|
data/hanami.gemspec
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
lib = File.expand_path("../lib", __FILE__)
|
4
|
-
$LOAD_PATH.
|
4
|
+
$LOAD_PATH.prepend(lib) unless $LOAD_PATH.include?(lib)
|
5
5
|
require "hanami/version"
|
6
6
|
|
7
7
|
Gem::Specification.new do |spec|
|
@@ -38,8 +38,8 @@ Gem::Specification.new do |spec|
|
|
38
38
|
spec.add_dependency "dry-monitor", "~> 1.0", ">= 1.0.1", "< 2"
|
39
39
|
spec.add_dependency "dry-system", "~> 1.0", "< 2"
|
40
40
|
spec.add_dependency "dry-logger", "~> 1.0", "< 2"
|
41
|
-
spec.add_dependency "hanami-cli", "~> 2.1.
|
42
|
-
spec.add_dependency "hanami-utils", "~> 2.1.
|
41
|
+
spec.add_dependency "hanami-cli", "~> 2.1.rc"
|
42
|
+
spec.add_dependency "hanami-utils", "~> 2.1.rc"
|
43
43
|
spec.add_dependency "zeitwerk", "~> 2.6"
|
44
44
|
|
45
45
|
spec.add_development_dependency "rspec", "~> 3.8"
|
@@ -74,20 +74,33 @@ module Hanami
|
|
74
74
|
# @since 2.0.0
|
75
75
|
attr_accessor :content_security_policy
|
76
76
|
|
77
|
-
#
|
78
|
-
#
|
79
|
-
#
|
77
|
+
# @!attribute [rw] method_override
|
78
|
+
# Sets or returns whether HTTP method override should be enabled for action classes.
|
79
|
+
#
|
80
|
+
# Defaults to true. You can override this by explicitly setting a
|
81
|
+
# true or false value.
|
82
|
+
#
|
83
|
+
# When true, this will mount `Rack::MethodOverride` in the Rack middleware stack of the App.
|
84
|
+
#
|
85
|
+
# @return [Boolean]
|
86
|
+
#
|
87
|
+
# @api public
|
88
|
+
# @since 2.1.0
|
89
|
+
setting :method_override, default: true
|
80
90
|
|
81
91
|
# @!attribute [rw] name_inference_base
|
82
92
|
# @api private
|
93
|
+
# @since 2.1.0
|
83
94
|
setting :name_inference_base, default: "actions"
|
84
95
|
|
85
96
|
# @!attribute [rw] view_name_inferrer
|
86
97
|
# @api private
|
98
|
+
# @since 2.1.0
|
87
99
|
setting :view_name_inferrer, default: Slice::ViewNameInferrer
|
88
100
|
|
89
101
|
# @!attribute [rw] view_name_inference_base
|
90
102
|
# @api private
|
103
|
+
# @since 2.1.0
|
91
104
|
setting :view_name_inference_base, default: "views"
|
92
105
|
|
93
106
|
# @api private
|
data/lib/hanami/config/assets.rb
CHANGED
@@ -9,7 +9,7 @@ module Hanami
|
|
9
9
|
#
|
10
10
|
# This exposes all the settings from the standalone `Hanami::Assets` class, pre-configured with
|
11
11
|
# sensible defaults for actions within a full Hanami app. It also provides additional settings
|
12
|
-
# for further integration of
|
12
|
+
# for further integration of assets with other full stack app components.
|
13
13
|
#
|
14
14
|
# @since 2.1.0
|
15
15
|
# @api public
|
data/lib/hanami/config/views.rb
CHANGED
@@ -7,16 +7,22 @@ module Hanami
|
|
7
7
|
class Config
|
8
8
|
# Hanami views config
|
9
9
|
#
|
10
|
-
# This
|
10
|
+
# This exposes all the settings from the standalone `Hanami::View` class, pre-configured with
|
11
|
+
# sensible defaults for actions within a full Hanami app. It also provides additional settings
|
12
|
+
# for further integration of views with other full stack app components.
|
11
13
|
#
|
12
|
-
# @
|
14
|
+
# @since 2.1.0
|
15
|
+
# @api public
|
13
16
|
class Views
|
14
17
|
include Dry::Configurable
|
15
18
|
|
19
|
+
# @api private
|
20
|
+
# @since 2.1.0
|
16
21
|
attr_reader :base_config
|
17
22
|
protected :base_config
|
18
23
|
|
19
24
|
# @api private
|
25
|
+
# @since 2.1.0
|
20
26
|
def initialize(*)
|
21
27
|
super
|
22
28
|
|
@@ -26,6 +32,7 @@ module Hanami
|
|
26
32
|
end
|
27
33
|
|
28
34
|
# @api private
|
35
|
+
# @since 2.1.0
|
29
36
|
def initialize_copy(source)
|
30
37
|
super
|
31
38
|
@base_config = source.base_config.dup
|
@@ -33,6 +40,7 @@ module Hanami
|
|
33
40
|
private :initialize_copy
|
34
41
|
|
35
42
|
# @api private
|
43
|
+
# @since 2.1.0
|
36
44
|
def finalize!
|
37
45
|
return self if frozen?
|
38
46
|
|
data/lib/hanami/config.rb
CHANGED
@@ -251,16 +251,30 @@ module Hanami
|
|
251
251
|
|
252
252
|
# Returns the app's views config, or a null config if hanami-view is not bundled.
|
253
253
|
#
|
254
|
-
#
|
254
|
+
# @example When hanami-view is bundled
|
255
|
+
# config.views.paths # => [...]
|
255
256
|
#
|
256
|
-
# @
|
257
|
+
# @example When hanami-view is not bundled
|
258
|
+
# config.views.paths # => NoMethodError
|
259
|
+
#
|
260
|
+
# @return [Hanami::Config::Views, Hanami::Config::NullConfig]
|
261
|
+
#
|
262
|
+
# @api public
|
263
|
+
# @since 2.1.0
|
257
264
|
attr_reader :views
|
258
265
|
|
259
|
-
# Returns the app's
|
266
|
+
# Returns the app's views config, or a null config if hanami-view is not bundled.
|
260
267
|
#
|
261
|
-
#
|
268
|
+
# @example When hanami-view is bundled
|
269
|
+
# config.views.paths # => [...]
|
262
270
|
#
|
263
|
-
# @
|
271
|
+
# @example When hanami-view is not bundled
|
272
|
+
# config.views.paths # => NoMethodError
|
273
|
+
#
|
274
|
+
# @return [Hanami::Config::Assets, Hanami::Config::NullConfig]
|
275
|
+
#
|
276
|
+
# @api public
|
277
|
+
# @since 2.1.0
|
264
278
|
attr_reader :assets
|
265
279
|
|
266
280
|
# @api private
|
@@ -272,7 +286,7 @@ module Hanami
|
|
272
286
|
# Apply default values that are only knowable at initialize-time (vs require-time)
|
273
287
|
self.root = Dir.pwd
|
274
288
|
self.render_errors = (env == :production)
|
275
|
-
self.render_detailed_errors = (env
|
289
|
+
self.render_detailed_errors = (env == :development)
|
276
290
|
load_from_env
|
277
291
|
|
278
292
|
@logger = Config::Logger.new(env: env, app_name: app_name)
|
@@ -296,13 +310,8 @@ module Hanami
|
|
296
310
|
@assets = load_dependent_config("hanami-assets") {
|
297
311
|
require_relative "config/assets"
|
298
312
|
|
299
|
-
public_dir = root.join("public")
|
300
|
-
|
301
313
|
Hanami::Config::Assets.new(
|
302
|
-
|
303
|
-
sources: root.join("app", "assets"),
|
304
|
-
destination: public_dir.join("assets"),
|
305
|
-
manifest_path: public_dir.join("assets.json")
|
314
|
+
manifest_path: root.join("public", "assets.json")
|
306
315
|
)
|
307
316
|
}
|
308
317
|
|
@@ -31,14 +31,14 @@ module Hanami
|
|
31
31
|
# @see Hanami::Extensions::Action::InstanceMethods#initialize
|
32
32
|
def define_new
|
33
33
|
resolve_view = method(:resolve_paired_view)
|
34
|
-
|
34
|
+
view_context_class = method(:view_context_class)
|
35
35
|
resolve_routes = method(:resolve_routes)
|
36
36
|
resolve_rack_monitor = method(:resolve_rack_monitor)
|
37
37
|
|
38
38
|
define_method(:new) do |**kwargs|
|
39
39
|
super(
|
40
40
|
view: kwargs.fetch(:view) { resolve_view.(self) },
|
41
|
-
|
41
|
+
view_context_class: kwargs.fetch(:view_context_class) { view_context_class.() },
|
42
42
|
routes: kwargs.fetch(:routes) { resolve_routes.() },
|
43
43
|
rack_monitor: kwargs.fetch(:rack_monitor) { resolve_rack_monitor.() },
|
44
44
|
**kwargs,
|
@@ -128,9 +128,9 @@ module Hanami
|
|
128
128
|
nil
|
129
129
|
end
|
130
130
|
|
131
|
-
def
|
131
|
+
def view_context_class
|
132
132
|
if Hanami.bundled?("hanami-view")
|
133
|
-
return Extensions::View::Context.context_class(slice)
|
133
|
+
return Extensions::View::Context.context_class(slice)
|
134
134
|
end
|
135
135
|
|
136
136
|
# If hanami-view isn't bundled, try and find a possible third party context class with the
|
@@ -139,7 +139,7 @@ module Hanami
|
|
139
139
|
views_namespace = slice.namespace.const_get(:Views)
|
140
140
|
|
141
141
|
if views_namespace.const_defined?(:Context)
|
142
|
-
views_namespace.const_get(:Context)
|
142
|
+
views_namespace.const_get(:Context)
|
143
143
|
end
|
144
144
|
end
|
145
145
|
end
|
@@ -40,7 +40,7 @@ module Hanami
|
|
40
40
|
attr_reader :view
|
41
41
|
|
42
42
|
# @api private
|
43
|
-
attr_reader :
|
43
|
+
attr_reader :view_context_class
|
44
44
|
|
45
45
|
# Returns the app or slice's {Hanami::Slice::RoutesHelper RoutesHelper} for use within
|
46
46
|
# action instance methods.
|
@@ -70,9 +70,9 @@ module Hanami
|
|
70
70
|
#
|
71
71
|
# @api public
|
72
72
|
# @since 2.0.0
|
73
|
-
def initialize(view: nil,
|
73
|
+
def initialize(view: nil, view_context_class: nil, rack_monitor: nil, routes: nil, **kwargs)
|
74
74
|
@view = view
|
75
|
-
@
|
75
|
+
@view_context_class = view_context_class
|
76
76
|
@routes = routes
|
77
77
|
@rack_monitor = rack_monitor
|
78
78
|
|
@@ -104,7 +104,7 @@ module Hanami
|
|
104
104
|
|
105
105
|
# @api private
|
106
106
|
def view_options(request, response)
|
107
|
-
{context:
|
107
|
+
{context: view_context_class&.new(**view_context_options(request, response))}.compact
|
108
108
|
end
|
109
109
|
|
110
110
|
# @api private
|
@@ -7,15 +7,15 @@ module Hanami
|
|
7
7
|
module View
|
8
8
|
# View context for views in Hanami apps.
|
9
9
|
#
|
10
|
-
#
|
11
|
-
#
|
12
|
-
# @api private
|
10
|
+
# @api public
|
11
|
+
# @since 2.1.0
|
13
12
|
module Context
|
14
13
|
class << self
|
15
14
|
# Returns a context class for the given slice. If a context class is not defined, defines
|
16
15
|
# a class named `Views::Context` within the slice's namespace.
|
17
16
|
#
|
18
17
|
# @api private
|
18
|
+
# @since 2.1.0
|
19
19
|
def context_class(slice)
|
20
20
|
views_namespace = views_namespace(slice)
|
21
21
|
|
@@ -30,6 +30,8 @@ module Hanami
|
|
30
30
|
|
31
31
|
private
|
32
32
|
|
33
|
+
# @api private
|
34
|
+
# @since 2.1.0
|
33
35
|
def context_superclass(slice)
|
34
36
|
return Hanami::View::Context if Hanami.app.equal?(slice)
|
35
37
|
|
@@ -44,8 +46,10 @@ module Hanami
|
|
44
46
|
end
|
45
47
|
end
|
46
48
|
|
47
|
-
#
|
49
|
+
# @api private
|
50
|
+
# @since 2.1.0
|
48
51
|
def views_namespace(slice)
|
52
|
+
# TODO: this could be moved into the top-level Extensions::View
|
49
53
|
if slice.namespace.const_defined?(:Views)
|
50
54
|
slice.namespace.const_get(:Views)
|
51
55
|
else
|
@@ -54,6 +58,8 @@ module Hanami
|
|
54
58
|
end
|
55
59
|
end
|
56
60
|
|
61
|
+
# @api private
|
62
|
+
# @since 2.1.0
|
57
63
|
module ClassExtension
|
58
64
|
def self.included(context_class)
|
59
65
|
super
|
@@ -63,18 +69,39 @@ module Hanami
|
|
63
69
|
context_class.prepend(InstanceMethods)
|
64
70
|
end
|
65
71
|
|
72
|
+
# @api private
|
73
|
+
# @since 2.1.0
|
66
74
|
module ClassMethods
|
75
|
+
# @api private
|
76
|
+
# @since 2.1.0
|
67
77
|
def configure_for_slice(slice)
|
68
78
|
extend SliceConfiguredContext.new(slice)
|
69
79
|
end
|
70
80
|
end
|
71
81
|
|
82
|
+
# @api public
|
83
|
+
# @since 2.1.0
|
72
84
|
module InstanceMethods
|
85
|
+
# Returns the app's inflector.
|
86
|
+
#
|
87
|
+
# @return [Dry::Inflector] the inflector
|
88
|
+
#
|
89
|
+
# @api public
|
90
|
+
# @since 2.1.0
|
73
91
|
attr_reader :inflector
|
74
92
|
|
93
|
+
# Returns the app's settings.
|
94
|
+
#
|
95
|
+
# @return [Hanami::Settings] the settings
|
96
|
+
#
|
97
|
+
# @api public
|
98
|
+
# @since 2.1.0
|
75
99
|
attr_reader :settings
|
76
100
|
|
77
101
|
# @see SliceConfiguredContext#define_new
|
102
|
+
#
|
103
|
+
# @api private
|
104
|
+
# @since 2.1.0
|
78
105
|
def initialize( # rubocop:disable Metrics/ParameterLists
|
79
106
|
inflector: nil,
|
80
107
|
settings: nil,
|
@@ -94,6 +121,8 @@ module Hanami
|
|
94
121
|
super(**args)
|
95
122
|
end
|
96
123
|
|
124
|
+
# @api private
|
125
|
+
# @since 2.1.0
|
97
126
|
def initialize_copy(source)
|
98
127
|
# The standard implementation of initialize_copy will make shallow copies of all
|
99
128
|
# instance variables from the source. This is fine for most of our ivars.
|
@@ -104,17 +133,14 @@ module Hanami
|
|
104
133
|
@content_for = source.instance_variable_get(:@content_for).dup
|
105
134
|
end
|
106
135
|
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
)
|
116
|
-
end
|
117
|
-
|
136
|
+
# Returns the app's assets.
|
137
|
+
#
|
138
|
+
# @return [Hanami::Assets] the assets
|
139
|
+
#
|
140
|
+
# @raise [Hanami::ComponentLoadError] if the hanami-assets gem is not bundled
|
141
|
+
#
|
142
|
+
# @api public
|
143
|
+
# @since 2.1.0
|
118
144
|
def assets
|
119
145
|
unless @assets
|
120
146
|
raise Hanami::ComponentLoadError, "the hanami-assets gem is required to access assets"
|
@@ -123,6 +149,14 @@ module Hanami
|
|
123
149
|
@assets
|
124
150
|
end
|
125
151
|
|
152
|
+
# Returns the current request, if the view is rendered from within an action.
|
153
|
+
#
|
154
|
+
# @return [Hanami::Action::Request] the request
|
155
|
+
#
|
156
|
+
# @raise [Hanami::ComponentLoadError] if the view is not rendered from within a request
|
157
|
+
#
|
158
|
+
# @api public
|
159
|
+
# @since 2.1.0
|
126
160
|
def request
|
127
161
|
unless @request
|
128
162
|
raise Hanami::ComponentLoadError, "only views rendered from Hanami::Action instances have a request"
|
@@ -131,6 +165,15 @@ module Hanami
|
|
131
165
|
@request
|
132
166
|
end
|
133
167
|
|
168
|
+
# Returns the app's routes helper.
|
169
|
+
#
|
170
|
+
# @return [Hanami::Slice::RoutesHelper] the routes helper
|
171
|
+
#
|
172
|
+
# @raise [Hanami::ComponentLoadError] if the hanami-router gem is not bundled or routes
|
173
|
+
# are not defined
|
174
|
+
#
|
175
|
+
# @api public
|
176
|
+
# @since 2.1.0
|
134
177
|
def routes
|
135
178
|
unless @routes
|
136
179
|
raise Hanami::ComponentLoadError, "the hanami-router gem is required to access routes"
|
@@ -139,6 +182,32 @@ module Hanami
|
|
139
182
|
@routes
|
140
183
|
end
|
141
184
|
|
185
|
+
# @overload content_for(key, value = nil, &block)
|
186
|
+
# Stores a string or block of template markup for later use.
|
187
|
+
#
|
188
|
+
# @param key [Symbol] the content key, for later retrieval
|
189
|
+
# @param value [String, nil] the content, if no block is given
|
190
|
+
#
|
191
|
+
# @return [String] the content
|
192
|
+
#
|
193
|
+
# @example
|
194
|
+
# content_for(:page_title, "Hello world")
|
195
|
+
#
|
196
|
+
# @example In a template
|
197
|
+
# <% content_for :page_title do %>
|
198
|
+
# <h1>Hello world</h1>
|
199
|
+
# <% end %>
|
200
|
+
#
|
201
|
+
# @overload content_for(key)
|
202
|
+
# Returns the previously stored content for the given key.
|
203
|
+
#
|
204
|
+
# @param key [Symbol] the content key
|
205
|
+
#
|
206
|
+
# @return [String, nil] the content, or nil if no content previously stored with the
|
207
|
+
# key
|
208
|
+
#
|
209
|
+
# @api public
|
210
|
+
# @since 2.1.0
|
142
211
|
def content_for(key, value = nil)
|
143
212
|
if block_given?
|
144
213
|
@content_for[key] = yield
|
@@ -149,18 +218,41 @@ module Hanami
|
|
149
218
|
end
|
150
219
|
end
|
151
220
|
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
221
|
+
# Returns the current request's CSRF token.
|
222
|
+
#
|
223
|
+
# @return [String] the token
|
224
|
+
#
|
225
|
+
# @raise [Hanami::ComponentLoadError] if the view is not rendered from within a request
|
226
|
+
# @raise [Hanami::Action::MissingSessionError] if sessions are not enabled
|
227
|
+
#
|
228
|
+
# @api public
|
229
|
+
# @since 2.1.0
|
156
230
|
def csrf_token
|
157
231
|
request.session[Hanami::Action::CSRFProtection::CSRF_TOKEN]
|
158
232
|
end
|
159
233
|
|
234
|
+
# Returns the session for the current request.
|
235
|
+
#
|
236
|
+
# @return [Rack::Session::Abstract::SessionHash] the session hash
|
237
|
+
#
|
238
|
+
# @raise [Hanami::ComponentLoadError] if the view is not rendered from within a request
|
239
|
+
# @raise [Hanami::Action::MissingSessionError] if sessions are not enabled
|
240
|
+
#
|
241
|
+
# @api public
|
242
|
+
# @since 2.1.0
|
160
243
|
def session
|
161
244
|
request.session
|
162
245
|
end
|
163
246
|
|
247
|
+
# Returns the flash hash for the current request.
|
248
|
+
#
|
249
|
+
# @return []
|
250
|
+
#
|
251
|
+
# @raise [Hanami::ComponentLoadError] if the view is not rendered from within a request
|
252
|
+
# @raise [Hanami::Action::MissingSessionError] if sessions are not enabled
|
253
|
+
#
|
254
|
+
# @api public
|
255
|
+
# @since 2.1.0
|
164
256
|
def flash
|
165
257
|
request.flash
|
166
258
|
end
|
@@ -3,21 +3,82 @@
|
|
3
3
|
module Hanami
|
4
4
|
module Extensions
|
5
5
|
module View
|
6
|
-
# @api
|
6
|
+
# @api public
|
7
|
+
# @since 2.1.0
|
7
8
|
module Part
|
9
|
+
# @api private
|
10
|
+
# @since 2.1.0
|
8
11
|
def self.included(part_class)
|
9
12
|
super
|
10
13
|
|
11
14
|
part_class.extend(Hanami::SliceConfigurable)
|
12
|
-
part_class.include(StandardHelpers)
|
13
15
|
part_class.extend(ClassMethods)
|
14
16
|
end
|
15
17
|
|
18
|
+
# @api private
|
19
|
+
# @since 2.1.0
|
16
20
|
module ClassMethods
|
21
|
+
# @api private
|
22
|
+
# @since 2.1.0
|
17
23
|
def configure_for_slice(slice)
|
18
|
-
extend
|
24
|
+
extend SliceConfiguredPart.new(slice)
|
25
|
+
|
26
|
+
const_set :PartHelpers, Class.new(PartHelpers) { |klass|
|
27
|
+
klass.configure_for_slice(slice)
|
28
|
+
}
|
19
29
|
end
|
20
30
|
end
|
31
|
+
|
32
|
+
# Returns an object including the default Hanami helpers as well as the user-defined helpers
|
33
|
+
# for the part's slice.
|
34
|
+
#
|
35
|
+
# Use this when you need to access helpers inside your part classes.
|
36
|
+
#
|
37
|
+
# @return [Object] the helpers object
|
38
|
+
#
|
39
|
+
# @api public
|
40
|
+
# @since 2.1.0
|
41
|
+
def helpers
|
42
|
+
@helpers ||= self.class.const_get(:PartHelpers).new(context: _context)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# Standalone helpers class including both {StandardHelpers} as well as the user-defined
|
47
|
+
# helpers for the slice.
|
48
|
+
#
|
49
|
+
# Used used where helpers should be addressed via an intermediary object (i.e. in parts),
|
50
|
+
# rather than mixed into a class directly.
|
51
|
+
#
|
52
|
+
# @api private
|
53
|
+
# @since 2.1.0
|
54
|
+
class PartHelpers
|
55
|
+
extend Hanami::SliceConfigurable
|
56
|
+
|
57
|
+
include StandardHelpers
|
58
|
+
|
59
|
+
# @api private
|
60
|
+
# @since 2.1.0
|
61
|
+
def self.configure_for_slice(slice)
|
62
|
+
extend SliceConfiguredHelpers.new(slice)
|
63
|
+
end
|
64
|
+
|
65
|
+
# Returns the context for the current view rendering.
|
66
|
+
#
|
67
|
+
# @return [Hanami::View::Context] the context
|
68
|
+
#
|
69
|
+
# @api public
|
70
|
+
# @since 2.1.0
|
71
|
+
attr_reader :_context
|
72
|
+
|
73
|
+
# @api public
|
74
|
+
# @since 2.1.0
|
75
|
+
alias_method :context, :_context
|
76
|
+
|
77
|
+
# @api private
|
78
|
+
# @since 2.1.0
|
79
|
+
def initialize(context:)
|
80
|
+
@_context = context
|
81
|
+
end
|
21
82
|
end
|
22
83
|
end
|
23
84
|
end
|
@@ -4,7 +4,10 @@ module Hanami
|
|
4
4
|
module Extensions
|
5
5
|
module View
|
6
6
|
# @api private
|
7
|
+
# @since 2.1.0
|
7
8
|
module Scope
|
9
|
+
# @api private
|
10
|
+
# @since 2.1.0
|
8
11
|
def self.included(scope_class)
|
9
12
|
super
|
10
13
|
|
@@ -13,7 +16,11 @@ module Hanami
|
|
13
16
|
scope_class.extend(ClassMethods)
|
14
17
|
end
|
15
18
|
|
19
|
+
# @api private
|
20
|
+
# @since 2.1.0
|
16
21
|
module ClassMethods
|
22
|
+
# @api private
|
23
|
+
# @since 2.1.0
|
17
24
|
def configure_for_slice(slice)
|
18
25
|
extend SliceConfiguredHelpers.new(slice)
|
19
26
|
end
|
@@ -3,35 +3,39 @@
|
|
3
3
|
module Hanami
|
4
4
|
module Extensions
|
5
5
|
module View
|
6
|
-
# Provides slice-specific configuration and behavior for any view context class
|
7
|
-
#
|
6
|
+
# Provides slice-specific configuration and behavior for any view context class defined within
|
7
|
+
# a slice's module namespace.
|
8
8
|
#
|
9
|
-
# @api
|
10
|
-
# @since 2.
|
9
|
+
# @api public
|
10
|
+
# @since 2.1.0
|
11
11
|
class SliceConfiguredContext < Module
|
12
12
|
attr_reader :slice
|
13
13
|
|
14
|
+
# @api private
|
15
|
+
# @since 2.1.0
|
14
16
|
def initialize(slice)
|
15
17
|
super()
|
16
18
|
@slice = slice
|
17
19
|
end
|
18
20
|
|
21
|
+
# @api private
|
22
|
+
# @since 2.1.0
|
19
23
|
def extended(_context_class)
|
20
24
|
define_new
|
21
25
|
end
|
22
26
|
|
27
|
+
# @api public
|
28
|
+
# @since 2.1.0
|
23
29
|
def inspect
|
24
30
|
"#<#{self.class.name}[#{slice.name}]>"
|
25
31
|
end
|
26
32
|
|
27
33
|
private
|
28
34
|
|
29
|
-
# Defines a {.new} method on the context class that resolves key components from
|
30
|
-
#
|
31
|
-
# dependencies.
|
35
|
+
# Defines a {.new} method on the context class that resolves key components from the app
|
36
|
+
# container and provides them to {#initialize} as injected dependencies.
|
32
37
|
#
|
33
38
|
# This includes the following app components:
|
34
|
-
#
|
35
39
|
# - the configured inflector as `inflector`
|
36
40
|
# - "settings" from the app container as `settings`
|
37
41
|
# - "routes" from the app container as `routes`
|