piko-lite-box 0.0.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 +7 -0
- data/hanami-3.0.1/CHANGELOG.md +1701 -0
- data/hanami-3.0.1/LICENSE +20 -0
- data/hanami-3.0.1/README.md +89 -0
- data/hanami-3.0.1/hanami.gemspec +49 -0
- data/hanami-3.0.1/lib/hanami/app.rb +197 -0
- data/hanami-3.0.1/lib/hanami/boot.rb +5 -0
- data/hanami-3.0.1/lib/hanami/config/actions/content_security_policy.rb +140 -0
- data/hanami-3.0.1/lib/hanami/config/actions/cookies.rb +57 -0
- data/hanami-3.0.1/lib/hanami/config/actions/sessions.rb +83 -0
- data/hanami-3.0.1/lib/hanami/config/actions.rb +189 -0
- data/hanami-3.0.1/lib/hanami/config/assets.rb +84 -0
- data/hanami-3.0.1/lib/hanami/config/console.rb +79 -0
- data/hanami-3.0.1/lib/hanami/config/db.rb +35 -0
- data/hanami-3.0.1/lib/hanami/config/i18n.rb +138 -0
- data/hanami-3.0.1/lib/hanami/config/logger.rb +207 -0
- data/hanami-3.0.1/lib/hanami/config/null_config.rb +17 -0
- data/hanami-3.0.1/lib/hanami/config/router.rb +48 -0
- data/hanami-3.0.1/lib/hanami/config/views.rb +103 -0
- data/hanami-3.0.1/lib/hanami/config.rb +564 -0
- data/hanami-3.0.1/lib/hanami/constants.rb +62 -0
- data/hanami-3.0.1/lib/hanami/env.rb +52 -0
- data/hanami-3.0.1/lib/hanami/errors.rb +41 -0
- data/hanami-3.0.1/lib/hanami/extensions/action/i18n_helper.rb +64 -0
- data/hanami-3.0.1/lib/hanami/extensions/action/name_inferrer.rb +34 -0
- data/hanami-3.0.1/lib/hanami/extensions/action/slice_configured_action.rb +190 -0
- data/hanami-3.0.1/lib/hanami/extensions/action.rb +147 -0
- data/hanami-3.0.1/lib/hanami/extensions/db/repo.rb +108 -0
- data/hanami-3.0.1/lib/hanami/extensions/mailer/slice_configured_mailer.rb +134 -0
- data/hanami-3.0.1/lib/hanami/extensions/mailer.rb +28 -0
- data/hanami-3.0.1/lib/hanami/extensions/operation/slice_configured_db_operation.rb +90 -0
- data/hanami-3.0.1/lib/hanami/extensions/operation.rb +33 -0
- data/hanami-3.0.1/lib/hanami/extensions/router/errors.rb +58 -0
- data/hanami-3.0.1/lib/hanami/extensions/view/context.rb +298 -0
- data/hanami-3.0.1/lib/hanami/extensions/view/part.rb +92 -0
- data/hanami-3.0.1/lib/hanami/extensions/view/scope.rb +36 -0
- data/hanami-3.0.1/lib/hanami/extensions/view/slice_configured_context.rb +73 -0
- data/hanami-3.0.1/lib/hanami/extensions/view/slice_configured_helpers.rb +55 -0
- data/hanami-3.0.1/lib/hanami/extensions/view/slice_configured_part.rb +73 -0
- data/hanami-3.0.1/lib/hanami/extensions/view/slice_configured_view.rb +243 -0
- data/hanami-3.0.1/lib/hanami/extensions/view/standard_helpers.rb +26 -0
- data/hanami-3.0.1/lib/hanami/extensions/view.rb +38 -0
- data/hanami-3.0.1/lib/hanami/extensions.rb +30 -0
- data/hanami-3.0.1/lib/hanami/helpers/assets_helper.rb +804 -0
- data/hanami-3.0.1/lib/hanami/helpers/form_helper/form_builder.rb +1389 -0
- data/hanami-3.0.1/lib/hanami/helpers/form_helper/values.rb +75 -0
- data/hanami-3.0.1/lib/hanami/helpers/form_helper.rb +213 -0
- data/hanami-3.0.1/lib/hanami/helpers/i18n_helper.rb +241 -0
- data/hanami-3.0.1/lib/hanami/logger/rack_formatter.rb +73 -0
- data/hanami-3.0.1/lib/hanami/logger/sql_formatter.rb +80 -0
- data/hanami-3.0.1/lib/hanami/logger/sql_logger.rb +48 -0
- data/hanami-3.0.1/lib/hanami/middleware/assets.rb +21 -0
- data/hanami-3.0.1/lib/hanami/middleware/content_security_policy_nonce.rb +53 -0
- data/hanami-3.0.1/lib/hanami/middleware/public_errors_app.rb +75 -0
- data/hanami-3.0.1/lib/hanami/middleware/render_errors.rb +90 -0
- data/hanami-3.0.1/lib/hanami/port.rb +45 -0
- data/hanami-3.0.1/lib/hanami/prepare.rb +5 -0
- data/hanami-3.0.1/lib/hanami/provider/source.rb +16 -0
- data/hanami-3.0.1/lib/hanami/provider_registrar.rb +28 -0
- data/hanami-3.0.1/lib/hanami/providers/assets.rb +28 -0
- data/hanami-3.0.1/lib/hanami/providers/db/adapter.rb +75 -0
- data/hanami-3.0.1/lib/hanami/providers/db/adapters.rb +66 -0
- data/hanami-3.0.1/lib/hanami/providers/db/config.rb +44 -0
- data/hanami-3.0.1/lib/hanami/providers/db/gateway.rb +87 -0
- data/hanami-3.0.1/lib/hanami/providers/db/sql_adapter.rb +100 -0
- data/hanami-3.0.1/lib/hanami/providers/db.rb +325 -0
- data/hanami-3.0.1/lib/hanami/providers/db_logging.rb +19 -0
- data/hanami-3.0.1/lib/hanami/providers/i18n/backend.rb +373 -0
- data/hanami-3.0.1/lib/hanami/providers/i18n/locale/en.yml +57 -0
- data/hanami-3.0.1/lib/hanami/providers/i18n.rb +114 -0
- data/hanami-3.0.1/lib/hanami/providers/inflector.rb +17 -0
- data/hanami-3.0.1/lib/hanami/providers/logger.rb +41 -0
- data/hanami-3.0.1/lib/hanami/providers/mailers.rb +101 -0
- data/hanami-3.0.1/lib/hanami/providers/rack.rb +47 -0
- data/hanami-3.0.1/lib/hanami/providers/relations.rb +31 -0
- data/hanami-3.0.1/lib/hanami/providers/routes.rb +29 -0
- data/hanami-3.0.1/lib/hanami/rake_tasks.rb +54 -0
- data/hanami-3.0.1/lib/hanami/routes.rb +146 -0
- data/hanami-3.0.1/lib/hanami/settings/composite_store.rb +53 -0
- data/hanami-3.0.1/lib/hanami/settings/env_store.rb +32 -0
- data/hanami-3.0.1/lib/hanami/settings.rb +234 -0
- data/hanami-3.0.1/lib/hanami/setup.rb +6 -0
- data/hanami-3.0.1/lib/hanami/slice/router.rb +280 -0
- data/hanami-3.0.1/lib/hanami/slice/routes_helper.rb +37 -0
- data/hanami-3.0.1/lib/hanami/slice/routing/middleware/stack.rb +216 -0
- data/hanami-3.0.1/lib/hanami/slice/routing/resolver.rb +88 -0
- data/hanami-3.0.1/lib/hanami/slice/view_name_inferrer.rb +63 -0
- data/hanami-3.0.1/lib/hanami/slice.rb +1239 -0
- data/hanami-3.0.1/lib/hanami/slice_configurable.rb +72 -0
- data/hanami-3.0.1/lib/hanami/slice_name.rb +111 -0
- data/hanami-3.0.1/lib/hanami/slice_registrar.rb +215 -0
- data/hanami-3.0.1/lib/hanami/universal_logger.rb +250 -0
- data/hanami-3.0.1/lib/hanami/version.rb +45 -0
- data/hanami-3.0.1/lib/hanami/web/rack_logger.rb +126 -0
- data/hanami-3.0.1/lib/hanami/web/welcome.html.erb +584 -0
- data/hanami-3.0.1/lib/hanami/web/welcome.rb +46 -0
- data/hanami-3.0.1/lib/hanami.rb +276 -0
- data/piko-lite-box.gemspec +11 -0
- metadata +137 -0
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Hanami
|
|
4
|
+
module Extensions
|
|
5
|
+
module Operation
|
|
6
|
+
# Extends operations to support the database.
|
|
7
|
+
#
|
|
8
|
+
# Add an initializer accepting a `rom:` dependency, which is supplied automatically from the
|
|
9
|
+
# `"db.rom"` component in the operation's slice.
|
|
10
|
+
#
|
|
11
|
+
# @api private
|
|
12
|
+
class SliceConfiguredDBOperation < Module
|
|
13
|
+
attr_reader :slice
|
|
14
|
+
|
|
15
|
+
def initialize(slice)
|
|
16
|
+
super()
|
|
17
|
+
@slice = slice
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def extended(operation_class)
|
|
21
|
+
require "dry/operation/extensions/rom"
|
|
22
|
+
operation_class.include Dry::Operation::Extensions::ROM
|
|
23
|
+
|
|
24
|
+
operation_class.include InstanceMethods
|
|
25
|
+
operation_class.include SliceInstanceMethods.new(slice)
|
|
26
|
+
define_new
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def inspect
|
|
30
|
+
"#<#{self.class.name}[#{slice.name}>"
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
private
|
|
34
|
+
|
|
35
|
+
def define_new
|
|
36
|
+
resolve_rom = method(:resolve_rom)
|
|
37
|
+
|
|
38
|
+
define_method(:new) do |**kwargs|
|
|
39
|
+
super(
|
|
40
|
+
**kwargs,
|
|
41
|
+
rom: kwargs.fetch(:rom) { resolve_rom.() },
|
|
42
|
+
)
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def resolve_rom
|
|
47
|
+
slice["db.rom"] if slice.key?("db.rom")
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
module InstanceMethods
|
|
51
|
+
attr_reader :rom
|
|
52
|
+
|
|
53
|
+
def initialize(rom:, **)
|
|
54
|
+
super()
|
|
55
|
+
@rom = rom
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
class SliceInstanceMethods < Module
|
|
60
|
+
attr_reader :slice
|
|
61
|
+
|
|
62
|
+
def initialize(slice)
|
|
63
|
+
super()
|
|
64
|
+
@slice = slice
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def included(operation_class)
|
|
68
|
+
define_transaction
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
private
|
|
72
|
+
|
|
73
|
+
def define_transaction
|
|
74
|
+
slice = self.slice
|
|
75
|
+
define_method(:transaction) do |**kwargs, &block|
|
|
76
|
+
unless rom
|
|
77
|
+
msg = <<~TEXT.strip
|
|
78
|
+
A configured db for #{slice} is required to run transactions.
|
|
79
|
+
TEXT
|
|
80
|
+
raise Hanami::ComponentLoadError, msg
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
super(**kwargs, &block)
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "dry/operation"
|
|
4
|
+
|
|
5
|
+
module Hanami
|
|
6
|
+
module Extensions
|
|
7
|
+
# Integrated behavior for `Dry::Operation` classes within Hanami apps.
|
|
8
|
+
#
|
|
9
|
+
# @see https://github.com/dry-rb/dry-operation
|
|
10
|
+
#
|
|
11
|
+
# @api public
|
|
12
|
+
# @since 2.2.0
|
|
13
|
+
module Operation
|
|
14
|
+
require_relative "operation/slice_configured_db_operation"
|
|
15
|
+
|
|
16
|
+
# @api private
|
|
17
|
+
def self.extended(operation_class)
|
|
18
|
+
super
|
|
19
|
+
|
|
20
|
+
operation_class.extend(Hanami::SliceConfigurable)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# private
|
|
24
|
+
|
|
25
|
+
# @api private
|
|
26
|
+
def configure_for_slice(slice)
|
|
27
|
+
extend SliceConfiguredDBOperation.new(slice) if Hanami.bundled?("hanami-db")
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
Dry::Operation.extend(Hanami::Extensions::Operation)
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "hanami/router"
|
|
4
|
+
|
|
5
|
+
module Hanami
|
|
6
|
+
class Router
|
|
7
|
+
# Error raised when a request is made for a missing route.
|
|
8
|
+
#
|
|
9
|
+
# Raised only when using hanami-router as part of a full Hanami app. When using hanami-router
|
|
10
|
+
# standalone, the behavior for such requests is to return a "Not Found" response.
|
|
11
|
+
#
|
|
12
|
+
# @api public
|
|
13
|
+
# @since 2.1.0
|
|
14
|
+
class NotFoundError < Hanami::Router::Error
|
|
15
|
+
# @return [Hash] the Rack environment for the request
|
|
16
|
+
#
|
|
17
|
+
# @api public
|
|
18
|
+
# @since 2.1.0
|
|
19
|
+
attr_reader :env
|
|
20
|
+
|
|
21
|
+
def initialize(env)
|
|
22
|
+
@env = env
|
|
23
|
+
|
|
24
|
+
message = "No route found for #{env["REQUEST_METHOD"]} #{env["PATH_INFO"]}"
|
|
25
|
+
super(message)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Error raised when a request is made for a route using a HTTP method not allowed on the route.
|
|
30
|
+
#
|
|
31
|
+
# Raised only when using hanami-router as part of a full Hanami app. When using hanami-router
|
|
32
|
+
# standalone, the behavior for such requests is to return a "Method Not Allowed" response.
|
|
33
|
+
#
|
|
34
|
+
# @api public
|
|
35
|
+
# @since 2.1.0
|
|
36
|
+
class NotAllowedError < Hanami::Router::Error
|
|
37
|
+
# @return [Hash] the Rack environment for the request
|
|
38
|
+
#
|
|
39
|
+
# @api public
|
|
40
|
+
# @since 2.1.0
|
|
41
|
+
attr_reader :env
|
|
42
|
+
|
|
43
|
+
# @return [Array<String>] the allowed methods for the route
|
|
44
|
+
#
|
|
45
|
+
# @api public
|
|
46
|
+
# @since 2.1.0
|
|
47
|
+
attr_reader :allowed_methods
|
|
48
|
+
|
|
49
|
+
def initialize(env, allowed_methods)
|
|
50
|
+
@env = env
|
|
51
|
+
@allowed_methods = allowed_methods
|
|
52
|
+
|
|
53
|
+
message = "Only #{allowed_methods.join(', ')} requests are allowed at #{env["PATH_INFO"]}"
|
|
54
|
+
super(message)
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "../../errors"
|
|
4
|
+
require_relative "slice_configured_context"
|
|
5
|
+
|
|
6
|
+
module Hanami
|
|
7
|
+
module Extensions
|
|
8
|
+
module View
|
|
9
|
+
# View context for views in Hanami apps.
|
|
10
|
+
#
|
|
11
|
+
# @api public
|
|
12
|
+
# @since 2.1.0
|
|
13
|
+
module Context
|
|
14
|
+
class << self
|
|
15
|
+
# Returns a context class for the given slice. If a context class is not defined, defines
|
|
16
|
+
# a class named `Views::Context` within the slice's namespace.
|
|
17
|
+
#
|
|
18
|
+
# @api private
|
|
19
|
+
# @since 2.1.0
|
|
20
|
+
def context_class(slice)
|
|
21
|
+
views_namespace = views_namespace(slice)
|
|
22
|
+
|
|
23
|
+
if views_namespace.const_defined?(:Context)
|
|
24
|
+
return views_namespace.const_get(:Context)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
views_namespace.const_set(:Context, Class.new(context_superclass(slice)).tap { |klass|
|
|
28
|
+
# Call configure_for_slice explicitly, since this is an anonymous class at this point,
|
|
29
|
+
# so the slice cannot be inferred from its name.
|
|
30
|
+
klass.configure_for_slice(slice)
|
|
31
|
+
})
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
private
|
|
35
|
+
|
|
36
|
+
# @api private
|
|
37
|
+
# @since 2.1.0
|
|
38
|
+
def context_superclass(slice)
|
|
39
|
+
return Hanami::View::Context if Hanami.app.equal?(slice)
|
|
40
|
+
|
|
41
|
+
begin
|
|
42
|
+
slice.inflector.constantize(
|
|
43
|
+
slice.inflector.camelize("#{slice.app.slice_name.name}/views/context")
|
|
44
|
+
)
|
|
45
|
+
rescue NameError => exception
|
|
46
|
+
raise exception unless %i[Views Context].include?(exception.name)
|
|
47
|
+
|
|
48
|
+
Hanami::View::Context
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# @api private
|
|
53
|
+
# @since 2.1.0
|
|
54
|
+
def views_namespace(slice)
|
|
55
|
+
# TODO: this could be moved into the top-level Extensions::View
|
|
56
|
+
if slice.namespace.const_defined?(:Views)
|
|
57
|
+
slice.namespace.const_get(:Views)
|
|
58
|
+
else
|
|
59
|
+
slice.namespace.const_set(:Views, Module.new)
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# @api private
|
|
65
|
+
# @since 2.1.0
|
|
66
|
+
module ClassExtension
|
|
67
|
+
def self.included(context_class)
|
|
68
|
+
super
|
|
69
|
+
|
|
70
|
+
context_class.extend(Hanami::SliceConfigurable)
|
|
71
|
+
context_class.extend(ClassMethods)
|
|
72
|
+
context_class.prepend(InstanceMethods)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# @api private
|
|
76
|
+
# @since 2.1.0
|
|
77
|
+
module ClassMethods
|
|
78
|
+
# @api private
|
|
79
|
+
# @since 2.1.0
|
|
80
|
+
def configure_for_slice(slice)
|
|
81
|
+
extend SliceConfiguredContext.new(slice)
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# @api public
|
|
86
|
+
# @since 2.1.0
|
|
87
|
+
module InstanceMethods
|
|
88
|
+
# Returns the app's inflector.
|
|
89
|
+
#
|
|
90
|
+
# @return [Dry::Inflector] the inflector
|
|
91
|
+
#
|
|
92
|
+
# @api public
|
|
93
|
+
# @since 2.1.0
|
|
94
|
+
attr_reader :inflector
|
|
95
|
+
|
|
96
|
+
# @see SliceConfiguredContext#define_new
|
|
97
|
+
#
|
|
98
|
+
# @api private
|
|
99
|
+
# @since 2.1.0
|
|
100
|
+
def initialize(
|
|
101
|
+
inflector: nil,
|
|
102
|
+
routes: nil,
|
|
103
|
+
assets: nil,
|
|
104
|
+
request: nil,
|
|
105
|
+
i18n: nil,
|
|
106
|
+
**args
|
|
107
|
+
)
|
|
108
|
+
@inflector = inflector
|
|
109
|
+
@routes = routes
|
|
110
|
+
@assets = assets
|
|
111
|
+
@request = request
|
|
112
|
+
@i18n = i18n
|
|
113
|
+
|
|
114
|
+
@content_for = {}
|
|
115
|
+
|
|
116
|
+
super(**args)
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
# @api private
|
|
120
|
+
# @since 2.1.0
|
|
121
|
+
def initialize_copy(source)
|
|
122
|
+
# The standard implementation of initialize_copy will make shallow copies of all
|
|
123
|
+
# instance variables from the source. This is fine for most of our ivars.
|
|
124
|
+
super
|
|
125
|
+
|
|
126
|
+
# Dup any objects that will be mutated over a given rendering to ensure no leakage of
|
|
127
|
+
# state across distinct view renderings.
|
|
128
|
+
@content_for = source.instance_variable_get(:@content_for).dup
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
# Returns the app's assets.
|
|
132
|
+
#
|
|
133
|
+
# @return [Hanami::Assets] the assets
|
|
134
|
+
#
|
|
135
|
+
# @raise [Hanami::ComponentLoadError] if the hanami-assets gem is not bundled
|
|
136
|
+
#
|
|
137
|
+
# @api public
|
|
138
|
+
# @since 2.1.0
|
|
139
|
+
def assets
|
|
140
|
+
unless @assets
|
|
141
|
+
msg =
|
|
142
|
+
if Hanami.bundled?("hanami-assets")
|
|
143
|
+
"Have you put files into your assets directory?"
|
|
144
|
+
else
|
|
145
|
+
"The hanami-assets gem is required to access assets."
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
raise Hanami::ComponentLoadError, "Assets not available. #{msg}"
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
@assets
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
# Returns the current request, if the view is rendered from within an action.
|
|
155
|
+
#
|
|
156
|
+
# @return [Hanami::Action::Request] the request
|
|
157
|
+
#
|
|
158
|
+
# @raise [Hanami::ComponentLoadError] if the view is not rendered from within a request
|
|
159
|
+
#
|
|
160
|
+
# @api public
|
|
161
|
+
# @since 2.1.0
|
|
162
|
+
def request
|
|
163
|
+
unless @request
|
|
164
|
+
raise Hanami::ComponentLoadError, <<~STR
|
|
165
|
+
Request not available. Only views rendered from Hanami::Action instances have a request.
|
|
166
|
+
STR
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
@request
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
# Returns true if the view is rendered from within an action and a request is available.
|
|
173
|
+
#
|
|
174
|
+
# @return [Boolean]
|
|
175
|
+
#
|
|
176
|
+
# @api public
|
|
177
|
+
# @since 2.3.0
|
|
178
|
+
def request?
|
|
179
|
+
!!@request
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
# Returns the app's routes helper.
|
|
183
|
+
#
|
|
184
|
+
# @return [Hanami::Slice::RoutesHelper] the routes helper
|
|
185
|
+
#
|
|
186
|
+
# @raise [Hanami::ComponentLoadError] if the hanami-router gem is not bundled or routes
|
|
187
|
+
# are not defined
|
|
188
|
+
#
|
|
189
|
+
# @api public
|
|
190
|
+
# @since 2.1.0
|
|
191
|
+
def routes
|
|
192
|
+
unless @routes
|
|
193
|
+
raise Hanami::ComponentLoadError, "the hanami-router gem is required to access routes"
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
@routes
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
# Returns the slice's i18n backend.
|
|
200
|
+
#
|
|
201
|
+
# @return [Hanami::Providers::I18n::Backend] the i18n backend
|
|
202
|
+
#
|
|
203
|
+
# @raise [Hanami::ComponentLoadError] if the i18n gem is not bundled
|
|
204
|
+
#
|
|
205
|
+
# @api public
|
|
206
|
+
# @since 3.0.0
|
|
207
|
+
def i18n
|
|
208
|
+
unless @i18n
|
|
209
|
+
raise Hanami::ComponentLoadError, "the i18n gem is required to access translations"
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
@i18n
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
# @overload content_for(key, value = nil, &block)
|
|
216
|
+
# Stores a string or block of template markup for later use.
|
|
217
|
+
#
|
|
218
|
+
# @param key [Symbol] the content key, for later retrieval
|
|
219
|
+
# @param value [String, nil] the content, if no block is given
|
|
220
|
+
#
|
|
221
|
+
# @return [String] the content
|
|
222
|
+
#
|
|
223
|
+
# @example
|
|
224
|
+
# content_for(:page_title, "Hello world")
|
|
225
|
+
#
|
|
226
|
+
# @example In a template
|
|
227
|
+
# <%= content_for :page_title do %>
|
|
228
|
+
# <h1>Hello world</h1>
|
|
229
|
+
# <% end %>
|
|
230
|
+
#
|
|
231
|
+
# @overload content_for(key)
|
|
232
|
+
# Returns the previously stored content for the given key.
|
|
233
|
+
#
|
|
234
|
+
# @param key [Symbol] the content key
|
|
235
|
+
#
|
|
236
|
+
# @return [String, nil] the content, or nil if no content previously stored with the
|
|
237
|
+
# key
|
|
238
|
+
#
|
|
239
|
+
# @api public
|
|
240
|
+
# @since 2.1.0
|
|
241
|
+
def content_for(key, value = nil)
|
|
242
|
+
if block_given?
|
|
243
|
+
@content_for[key] = yield
|
|
244
|
+
nil
|
|
245
|
+
elsif value
|
|
246
|
+
@content_for[key] = value
|
|
247
|
+
nil
|
|
248
|
+
else
|
|
249
|
+
@content_for[key]
|
|
250
|
+
end
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
# Returns the current request's CSRF token.
|
|
254
|
+
#
|
|
255
|
+
# @return [String] the token
|
|
256
|
+
#
|
|
257
|
+
# @raise [Hanami::ComponentLoadError] if the view is not rendered from within a request
|
|
258
|
+
# @raise [Hanami::Action::MissingSessionError] if sessions are not enabled
|
|
259
|
+
#
|
|
260
|
+
# @api public
|
|
261
|
+
# @since 2.1.0
|
|
262
|
+
def csrf_token
|
|
263
|
+
request.session[Hanami::Action::CSRFProtection::CSRF_TOKEN]
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
# Returns the session for the current request.
|
|
267
|
+
#
|
|
268
|
+
# @return [Rack::Session::Abstract::SessionHash] the session hash
|
|
269
|
+
#
|
|
270
|
+
# @raise [Hanami::ComponentLoadError] if the view is not rendered from within a request
|
|
271
|
+
# @raise [Hanami::Action::MissingSessionError] if sessions are not enabled
|
|
272
|
+
#
|
|
273
|
+
# @api public
|
|
274
|
+
# @since 2.1.0
|
|
275
|
+
def session
|
|
276
|
+
request.session
|
|
277
|
+
end
|
|
278
|
+
|
|
279
|
+
# Returns the flash hash for the current request.
|
|
280
|
+
#
|
|
281
|
+
# @return []
|
|
282
|
+
#
|
|
283
|
+
# @raise [Hanami::ComponentLoadError] if the view is not rendered from within a request
|
|
284
|
+
# @raise [Hanami::Action::MissingSessionError] if sessions are not enabled
|
|
285
|
+
#
|
|
286
|
+
# @api public
|
|
287
|
+
# @since 2.1.0
|
|
288
|
+
def flash
|
|
289
|
+
request.flash
|
|
290
|
+
end
|
|
291
|
+
end
|
|
292
|
+
end
|
|
293
|
+
end
|
|
294
|
+
end
|
|
295
|
+
end
|
|
296
|
+
end
|
|
297
|
+
|
|
298
|
+
Hanami::View::Context.include(Hanami::Extensions::View::Context::ClassExtension)
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "standard_helpers"
|
|
4
|
+
require_relative "slice_configured_part"
|
|
5
|
+
|
|
6
|
+
module Hanami
|
|
7
|
+
module Extensions
|
|
8
|
+
module View
|
|
9
|
+
# @api public
|
|
10
|
+
# @since 2.1.0
|
|
11
|
+
module Part
|
|
12
|
+
# @api private
|
|
13
|
+
# @since 2.1.0
|
|
14
|
+
def self.included(part_class)
|
|
15
|
+
super
|
|
16
|
+
|
|
17
|
+
part_class.extend(Hanami::SliceConfigurable)
|
|
18
|
+
part_class.extend(ClassMethods)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# @api private
|
|
22
|
+
# @since 2.1.0
|
|
23
|
+
module ClassMethods
|
|
24
|
+
# @api private
|
|
25
|
+
# @since 2.1.0
|
|
26
|
+
def configure_for_slice(slice)
|
|
27
|
+
extend SliceConfiguredPart.new(slice)
|
|
28
|
+
|
|
29
|
+
const_set :PartHelpers, Class.new(PartHelpers) { |klass|
|
|
30
|
+
# Call configure_for_slice explicitly, since this is an anonymous class at this point,
|
|
31
|
+
# so the slice cannot be inferred from its name.
|
|
32
|
+
klass.configure_for_slice(slice)
|
|
33
|
+
}
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Returns an object including the default Hanami helpers as well as the user-defined helpers
|
|
38
|
+
# for the part's slice.
|
|
39
|
+
#
|
|
40
|
+
# Use this when you need to access helpers inside your part classes.
|
|
41
|
+
#
|
|
42
|
+
# @return [Object] the helpers object
|
|
43
|
+
#
|
|
44
|
+
# @api public
|
|
45
|
+
# @since 2.1.0
|
|
46
|
+
def helpers
|
|
47
|
+
@helpers ||= self.class.const_get(:PartHelpers).new(context: _context)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Standalone helpers class including both {StandardHelpers} as well as the user-defined
|
|
52
|
+
# helpers for the slice.
|
|
53
|
+
#
|
|
54
|
+
# Used where helpers should be addressed via an intermediary object (i.e. in parts),
|
|
55
|
+
# rather than mixed into a class directly.
|
|
56
|
+
#
|
|
57
|
+
# @api private
|
|
58
|
+
# @since 2.1.0
|
|
59
|
+
class PartHelpers
|
|
60
|
+
extend Hanami::SliceConfigurable
|
|
61
|
+
|
|
62
|
+
include StandardHelpers
|
|
63
|
+
|
|
64
|
+
# @api private
|
|
65
|
+
# @since 2.1.0
|
|
66
|
+
def self.configure_for_slice(slice)
|
|
67
|
+
extend SliceConfiguredHelpers.new(slice)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# Returns the context for the current view rendering.
|
|
71
|
+
#
|
|
72
|
+
# @return [Hanami::View::Context] the context
|
|
73
|
+
#
|
|
74
|
+
# @api public
|
|
75
|
+
# @since 2.1.0
|
|
76
|
+
attr_reader :_context
|
|
77
|
+
|
|
78
|
+
# @api public
|
|
79
|
+
# @since 2.1.0
|
|
80
|
+
alias_method :context, :_context
|
|
81
|
+
|
|
82
|
+
# @api private
|
|
83
|
+
# @since 2.1.0
|
|
84
|
+
def initialize(context:)
|
|
85
|
+
@_context = context
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
Hanami::View::Part.include(Hanami::Extensions::View::Part)
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "slice_configured_helpers"
|
|
4
|
+
require_relative "standard_helpers"
|
|
5
|
+
|
|
6
|
+
module Hanami
|
|
7
|
+
module Extensions
|
|
8
|
+
module View
|
|
9
|
+
# @api private
|
|
10
|
+
# @since 2.1.0
|
|
11
|
+
module Scope
|
|
12
|
+
# @api private
|
|
13
|
+
# @since 2.1.0
|
|
14
|
+
def self.included(scope_class)
|
|
15
|
+
super
|
|
16
|
+
|
|
17
|
+
scope_class.extend(Hanami::SliceConfigurable)
|
|
18
|
+
scope_class.include(StandardHelpers)
|
|
19
|
+
scope_class.extend(ClassMethods)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# @api private
|
|
23
|
+
# @since 2.1.0
|
|
24
|
+
module ClassMethods
|
|
25
|
+
# @api private
|
|
26
|
+
# @since 2.1.0
|
|
27
|
+
def configure_for_slice(slice)
|
|
28
|
+
extend SliceConfiguredHelpers.new(slice)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
Hanami::View::Scope.include(Hanami::Extensions::View::Scope)
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Hanami
|
|
4
|
+
module Extensions
|
|
5
|
+
module View
|
|
6
|
+
# Provides slice-specific configuration and behavior for any view context class defined within
|
|
7
|
+
# a slice's module namespace.
|
|
8
|
+
#
|
|
9
|
+
# @api public
|
|
10
|
+
# @since 2.1.0
|
|
11
|
+
class SliceConfiguredContext < Module
|
|
12
|
+
attr_reader :slice
|
|
13
|
+
|
|
14
|
+
# @api private
|
|
15
|
+
# @since 2.1.0
|
|
16
|
+
def initialize(slice)
|
|
17
|
+
super()
|
|
18
|
+
@slice = slice
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# @api private
|
|
22
|
+
# @since 2.1.0
|
|
23
|
+
def extended(_context_class)
|
|
24
|
+
define_new
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# @api public
|
|
28
|
+
# @since 2.1.0
|
|
29
|
+
def inspect
|
|
30
|
+
"#<#{self.class.name}[#{slice.name}]>"
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
private
|
|
34
|
+
|
|
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.
|
|
37
|
+
#
|
|
38
|
+
# This includes the following app components:
|
|
39
|
+
# - the configured inflector as `inflector`
|
|
40
|
+
# - "routes" from the app container as `routes`
|
|
41
|
+
# - "assets" from the app container as `assets`
|
|
42
|
+
# - "i18n" from the slice container as `i18n`
|
|
43
|
+
def define_new
|
|
44
|
+
inflector = slice.inflector
|
|
45
|
+
resolve_routes = method(:resolve_routes)
|
|
46
|
+
resolve_assets = method(:resolve_assets)
|
|
47
|
+
resolve_i18n = method(:resolve_i18n)
|
|
48
|
+
|
|
49
|
+
define_method :new do |**kwargs|
|
|
50
|
+
kwargs[:inflector] ||= inflector
|
|
51
|
+
kwargs[:routes] ||= resolve_routes.()
|
|
52
|
+
kwargs[:assets] ||= resolve_assets.()
|
|
53
|
+
kwargs[:i18n] ||= resolve_i18n.()
|
|
54
|
+
|
|
55
|
+
super(**kwargs)
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def resolve_routes
|
|
60
|
+
slice["routes"] if slice.key?("routes")
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def resolve_assets
|
|
64
|
+
slice["assets"] if slice.key?("assets")
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def resolve_i18n
|
|
68
|
+
slice["i18n"] if slice.key?("i18n")
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|