hanami-view 1.3.1 → 2.0.0.alpha3
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 +11 -0
- data/LICENSE +20 -0
- data/README.md +17 -835
- data/hanami-view.gemspec +26 -16
- data/lib/hanami/view/application_configuration.rb +77 -0
- data/lib/hanami/view/application_context.rb +35 -0
- data/lib/hanami/view/application_view.rb +89 -0
- data/lib/hanami/view/context.rb +97 -0
- data/lib/hanami/view/context_helpers/content_helpers.rb +26 -0
- data/lib/hanami/view/decorated_attributes.rb +82 -0
- data/lib/hanami/view/errors.rb +31 -53
- data/lib/hanami/view/exposure.rb +126 -0
- data/lib/hanami/view/exposures.rb +74 -0
- data/lib/hanami/view/part.rb +217 -0
- data/lib/hanami/view/part_builder.rb +140 -0
- data/lib/hanami/view/path.rb +68 -0
- data/lib/hanami/view/render_environment.rb +62 -0
- data/lib/hanami/view/render_environment_missing.rb +44 -0
- data/lib/hanami/view/rendered.rb +55 -0
- data/lib/hanami/view/renderer.rb +79 -0
- data/lib/hanami/view/scope.rb +189 -0
- data/lib/hanami/view/scope_builder.rb +98 -0
- data/lib/hanami/view/standalone_view.rb +400 -0
- data/lib/hanami/view/tilt/erb.rb +26 -0
- data/lib/hanami/view/tilt/erbse.rb +21 -0
- data/lib/hanami/view/tilt/haml.rb +26 -0
- data/lib/hanami/view/tilt.rb +78 -0
- data/lib/hanami/view/version.rb +5 -5
- data/lib/hanami/view.rb +208 -223
- data/lib/hanami-view.rb +3 -1
- metadata +120 -70
- data/LICENSE.md +0 -22
- data/lib/hanami/layout.rb +0 -190
- data/lib/hanami/presenter.rb +0 -98
- data/lib/hanami/view/configuration.rb +0 -504
- data/lib/hanami/view/dsl.rb +0 -347
- data/lib/hanami/view/escape.rb +0 -225
- data/lib/hanami/view/inheritable.rb +0 -54
- data/lib/hanami/view/rendering/layout_finder.rb +0 -128
- data/lib/hanami/view/rendering/layout_registry.rb +0 -69
- data/lib/hanami/view/rendering/layout_scope.rb +0 -274
- data/lib/hanami/view/rendering/null_layout.rb +0 -52
- data/lib/hanami/view/rendering/null_local.rb +0 -82
- data/lib/hanami/view/rendering/null_template.rb +0 -83
- data/lib/hanami/view/rendering/null_view.rb +0 -26
- data/lib/hanami/view/rendering/options.rb +0 -24
- data/lib/hanami/view/rendering/partial.rb +0 -31
- data/lib/hanami/view/rendering/partial_file.rb +0 -29
- data/lib/hanami/view/rendering/partial_finder.rb +0 -75
- data/lib/hanami/view/rendering/partial_templates_finder.rb +0 -73
- data/lib/hanami/view/rendering/registry.rb +0 -134
- data/lib/hanami/view/rendering/scope.rb +0 -108
- data/lib/hanami/view/rendering/subscope.rb +0 -56
- data/lib/hanami/view/rendering/template.rb +0 -69
- data/lib/hanami/view/rendering/template_finder.rb +0 -55
- data/lib/hanami/view/rendering/template_name.rb +0 -50
- data/lib/hanami/view/rendering/templates_finder.rb +0 -144
- data/lib/hanami/view/rendering/view_finder.rb +0 -37
- data/lib/hanami/view/rendering.rb +0 -294
- data/lib/hanami/view/template.rb +0 -57
data/lib/hanami/view.rb
CHANGED
@@ -1,267 +1,252 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dry/configurable"
|
4
|
+
require "dry/core/cache"
|
5
|
+
require "dry/core/equalizer"
|
6
|
+
require "dry/inflector"
|
7
|
+
|
8
|
+
require_relative "view/application_view"
|
9
|
+
require_relative "view/context"
|
10
|
+
require_relative "view/exposures"
|
11
|
+
require_relative "view/errors"
|
12
|
+
require_relative "view/part_builder"
|
13
|
+
require_relative "view/path"
|
14
|
+
require_relative "view/render_environment"
|
15
|
+
require_relative "view/rendered"
|
16
|
+
require_relative "view/renderer"
|
17
|
+
require_relative "view/scope_builder"
|
18
|
+
require_relative "view/standalone_view"
|
13
19
|
|
14
|
-
# Hanami
|
15
|
-
#
|
16
|
-
# @since 0.1.0
|
17
20
|
module Hanami
|
18
|
-
#
|
21
|
+
# A standalone, template-based view rendering system that offers everything
|
22
|
+
# you need to write well-factored view code.
|
19
23
|
#
|
20
|
-
#
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
24
|
+
# This represents a single view, holding the configuration and exposures
|
25
|
+
# necessary for rendering its template.
|
26
|
+
#
|
27
|
+
# @abstract Subclass this and provide your own configuration and exposures to
|
28
|
+
# define your own view (along with a custom `#initialize` if you wish to
|
29
|
+
# inject dependencies into your subclass)
|
30
|
+
#
|
31
|
+
# @see https://dry-rb.org/gems/dry-view/
|
32
|
+
#
|
33
|
+
# @api public
|
34
|
+
class View
|
26
35
|
# @api private
|
27
|
-
|
28
|
-
|
36
|
+
DEFAULT_RENDERER_OPTIONS = {default_encoding: "utf-8"}.freeze
|
37
|
+
|
38
|
+
include Dry::Equalizer(:config, :exposures)
|
39
|
+
|
40
|
+
extend Dry::Core::Cache
|
41
|
+
|
42
|
+
extend Dry::Configurable
|
43
|
+
|
44
|
+
# @!group Configuration
|
29
45
|
|
30
|
-
#
|
31
|
-
#
|
46
|
+
# @overload config.paths=(paths)
|
47
|
+
# Set an array of directories that will be searched for all templates
|
48
|
+
# (templates, partials, and layouts).
|
32
49
|
#
|
33
|
-
#
|
50
|
+
# These will be converted into Path objects and used for template lookup
|
51
|
+
# when rendering.
|
34
52
|
#
|
35
|
-
#
|
53
|
+
# This is a **required setting**.
|
36
54
|
#
|
37
|
-
#
|
55
|
+
# @param paths [String, Path, Array<String, Path>] the paths
|
38
56
|
#
|
39
|
-
#
|
40
|
-
#
|
57
|
+
# @api public
|
58
|
+
# @!scope class
|
59
|
+
setting :paths, constructor: -> paths {
|
60
|
+
Array(paths).map { |path| Path[path] }
|
61
|
+
}
|
62
|
+
|
63
|
+
# @overload config.template=(name)
|
64
|
+
# Set the name of the template for rendering this view. Template name
|
65
|
+
# should be relative to the configured `paths`.
|
41
66
|
#
|
42
|
-
#
|
43
|
-
#
|
44
|
-
#
|
45
|
-
|
46
|
-
|
47
|
-
|
67
|
+
# This is a **required setting**.
|
68
|
+
#
|
69
|
+
# @param name [String] template name
|
70
|
+
# @api public
|
71
|
+
# @!scope class
|
72
|
+
setting :template
|
48
73
|
|
49
|
-
#
|
50
|
-
#
|
74
|
+
# @overload config.template_inference_base=(base_path)
|
75
|
+
# Set the base path to strip away when when inferring a view's template
|
76
|
+
# names from its class name.
|
51
77
|
#
|
52
|
-
#
|
53
|
-
# original. It will inherit the configuration, but all the changes that
|
54
|
-
# happen after the duplication, won't be reflected on the other copies.
|
78
|
+
# **This setting only applies for views within an Hanami application.**
|
55
79
|
#
|
56
|
-
#
|
80
|
+
# For example, given a view `Main::Views::Articles::Index`, in the `Main`
|
81
|
+
# slice, and a template_inference_base of "views", the inferred template
|
82
|
+
# name will be "articles/index".
|
57
83
|
#
|
58
|
-
#
|
59
|
-
#
|
84
|
+
# @param base_path [String, nil] base templates path
|
85
|
+
# @api public
|
86
|
+
# @!scope class
|
87
|
+
setting :template_inference_base
|
88
|
+
|
89
|
+
# @overload config.layout=(name)
|
90
|
+
# Set the name of the layout to render templates within. Layouts will be
|
91
|
+
# looked up within the configured `layouts_dir`, within the configured
|
92
|
+
# `paths`.
|
60
93
|
#
|
61
|
-
#
|
62
|
-
# require 'hanami/view'
|
94
|
+
# A false or nil value will use no layout. Defaults to `nil`.
|
63
95
|
#
|
64
|
-
#
|
65
|
-
#
|
66
|
-
#
|
96
|
+
# @param name [String, FalseClass, nil] layout name, or false to indicate no layout
|
97
|
+
# @api public
|
98
|
+
# @!scope class
|
99
|
+
setting :layout, default: false
|
100
|
+
|
101
|
+
# @overload config.layouts_dir=(dir)
|
102
|
+
# Set the name of the directory (within the configured `paths`) holding
|
103
|
+
# the layouts. Defaults to `"layouts"`
|
104
|
+
#
|
105
|
+
# @param dir [String] directory name
|
106
|
+
# @api public
|
107
|
+
# @!scope class
|
108
|
+
setting :layouts_dir, default: "layouts"
|
109
|
+
|
110
|
+
# @overload config.scope=(scope_class)
|
111
|
+
# Set the scope class to use when rendering the view's template.
|
67
112
|
#
|
68
|
-
#
|
113
|
+
# Configuring a custom scope class allows you to provide extra behaviour
|
114
|
+
# (alongside exposures) to the template.
|
69
115
|
#
|
70
|
-
#
|
71
|
-
# Hanami::View.configuration # => false
|
116
|
+
# @see https://dry-rb.org/gems/dry-view/scopes/
|
72
117
|
#
|
73
|
-
#
|
74
|
-
#
|
118
|
+
# @param scope_class [Class] scope class (inheriting from `Hanami::View::Scope`)
|
119
|
+
# @api public
|
120
|
+
# @!scope class
|
121
|
+
setting :scope
|
122
|
+
|
123
|
+
# @overload config.default_context=(context)
|
124
|
+
# Set the default context object to use when rendering. This will be used
|
125
|
+
# unless another context object is applied at render-time to `View#call`
|
75
126
|
#
|
76
|
-
# Hanami::View
|
77
|
-
# root '/path/to/root'
|
78
|
-
# end
|
127
|
+
# Defaults to a frozen instance of `Hanami::View::Context`.
|
79
128
|
#
|
80
|
-
#
|
81
|
-
# View = Hanami::View.dupe
|
82
|
-
# end
|
129
|
+
# @see View#call
|
83
130
|
#
|
84
|
-
#
|
85
|
-
#
|
86
|
-
#
|
87
|
-
|
88
|
-
|
89
|
-
#
|
131
|
+
# @param context [Hanami::View::Context] context object
|
132
|
+
# @api public
|
133
|
+
# @!scope class
|
134
|
+
setting :default_context, default: Context.new.freeze
|
135
|
+
|
136
|
+
# @overload config.default_format=(format)
|
137
|
+
# Set the default format to use when rendering.
|
90
138
|
#
|
91
|
-
#
|
92
|
-
#
|
93
|
-
#
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
end
|
98
|
-
end
|
139
|
+
# Defaults to `:html`.
|
140
|
+
#
|
141
|
+
# @param format [Symbol]
|
142
|
+
# @api public
|
143
|
+
# @!scope class
|
144
|
+
setting :default_format, default: :html
|
99
145
|
|
100
|
-
#
|
146
|
+
# @overload config.scope_namespace=(namespace)
|
147
|
+
# Set a namespace that will be searched when building scope classes.
|
148
|
+
#
|
149
|
+
# @param namespace [Module, Class]
|
101
150
|
#
|
102
|
-
#
|
103
|
-
# @param views [String] the optional namespace where the application's
|
104
|
-
# views will live
|
105
|
-
# @param blk [Proc] an optional block to configure the framework
|
151
|
+
# @see Scope
|
106
152
|
#
|
107
|
-
#
|
108
|
-
#
|
109
|
-
|
110
|
-
#
|
111
|
-
# @see Hanami::View#dupe
|
112
|
-
# @see Hanami::View::Configuration
|
113
|
-
# @see Hanami::View::Configuration#namespace
|
114
|
-
#
|
115
|
-
# @example Basic usage
|
116
|
-
# require 'hanami/view'
|
117
|
-
#
|
118
|
-
# module MyApp
|
119
|
-
# View = Hanami::View.duplicate(self)
|
120
|
-
# end
|
121
|
-
#
|
122
|
-
# # It will:
|
123
|
-
# #
|
124
|
-
# # 1. Generate MyApp::View
|
125
|
-
# # 2. Generate MyApp::Layout
|
126
|
-
# # 3. Generate MyApp::Presenter
|
127
|
-
# # 4. Generate MyApp::Views
|
128
|
-
# # 5. Configure MyApp::Views as the default namespace for views
|
129
|
-
#
|
130
|
-
# module MyApp::Views::Dashboard
|
131
|
-
# class Index
|
132
|
-
# include MyApp::View
|
133
|
-
# end
|
134
|
-
# end
|
135
|
-
#
|
136
|
-
# @example Compare code
|
137
|
-
# require 'hanami/view'
|
138
|
-
#
|
139
|
-
# module MyApp
|
140
|
-
# View = Hanami::View.duplicate(self) do
|
141
|
-
# # ...
|
142
|
-
# end
|
143
|
-
# end
|
144
|
-
#
|
145
|
-
# # it's equivalent to:
|
146
|
-
#
|
147
|
-
# module MyApp
|
148
|
-
# View = Hanami::View.dupe
|
149
|
-
# Layout = Hanami::Layout.dup
|
150
|
-
#
|
151
|
-
# module Views
|
152
|
-
# end
|
153
|
-
#
|
154
|
-
# View.configure do
|
155
|
-
# namespace 'MyApp::Views'
|
156
|
-
# end
|
157
|
-
#
|
158
|
-
# View.configure do
|
159
|
-
# # ...
|
160
|
-
# end
|
161
|
-
# end
|
162
|
-
#
|
163
|
-
# @example Custom views module
|
164
|
-
# require 'hanami/view
|
165
|
-
#
|
166
|
-
# module MyApp
|
167
|
-
# View = Hanami::View.duplicate(self, 'Vs')
|
168
|
-
# end
|
169
|
-
#
|
170
|
-
# defined?(MyApp::Views) # => nil
|
171
|
-
# defined?(MyApp::Vs) # => "constant"
|
172
|
-
#
|
173
|
-
# # Developers can namespace views under Vs
|
174
|
-
# module MyApp::Vs::Dashboard
|
175
|
-
# # ...
|
176
|
-
# end
|
177
|
-
#
|
178
|
-
# @example Nil views module
|
179
|
-
# require 'hanami/view'
|
180
|
-
#
|
181
|
-
# module MyApp
|
182
|
-
# View = Hanami::View.duplicate(self, nil)
|
183
|
-
# end
|
184
|
-
#
|
185
|
-
# defined?(MyApp::Views) # => nil
|
186
|
-
#
|
187
|
-
# # Developers can namespace views under MyApp
|
188
|
-
# module MyApp
|
189
|
-
# # ...
|
190
|
-
# end
|
191
|
-
#
|
192
|
-
# @example Block usage
|
193
|
-
# require 'hanami/view'
|
194
|
-
#
|
195
|
-
# module MyApp
|
196
|
-
# View = Hanami::View.duplicate(self) do
|
197
|
-
# root '/path/to/root'
|
198
|
-
# end
|
199
|
-
# end
|
200
|
-
#
|
201
|
-
# Hanami::View.configuration.root # => #<Pathname:.>
|
202
|
-
# MyApp::View.configuration.root # => #<Pathname:/path/to/root>
|
203
|
-
def self.duplicate(mod, views = 'Views', &blk)
|
204
|
-
dupe.tap do |duplicated|
|
205
|
-
mod.module_eval %{ module #{ views }; end } if views
|
206
|
-
mod.module_eval %{
|
207
|
-
Layout = Hanami::Layout.dup
|
208
|
-
Presenter = Hanami::Presenter.dup
|
209
|
-
}
|
153
|
+
# @api public
|
154
|
+
# @!scope class
|
155
|
+
setting :part_namespace
|
210
156
|
|
211
|
-
|
212
|
-
|
213
|
-
|
157
|
+
# @overload config.part_builder=(part_builder)
|
158
|
+
# Set a custom part builder class
|
159
|
+
#
|
160
|
+
# @see https://dry-rb.org/gems/dry-view/parts/
|
161
|
+
#
|
162
|
+
# @param part_builder [Class]
|
163
|
+
# @api public
|
164
|
+
# @!scope class
|
165
|
+
setting :part_builder, default: PartBuilder
|
214
166
|
|
215
|
-
|
216
|
-
|
217
|
-
|
167
|
+
# @overload config.scope_namespace=(namespace)
|
168
|
+
# Set a namespace that will be searched when building scope classes.
|
169
|
+
#
|
170
|
+
# @param namespace [Module, Class]
|
171
|
+
#
|
172
|
+
# @see Scope
|
173
|
+
#
|
174
|
+
# @api public
|
175
|
+
# @!scope class
|
176
|
+
setting :scope_namespace
|
218
177
|
|
219
|
-
#
|
220
|
-
#
|
221
|
-
# It sets a copy of the framework configuration
|
178
|
+
# @overload config.scope_builder=(scope_builder)
|
179
|
+
# Set a custom scope builder class
|
222
180
|
#
|
223
|
-
#
|
181
|
+
# @see https://dry-rb.org/gems/dry-view/scopes/
|
224
182
|
#
|
225
|
-
#
|
226
|
-
#
|
183
|
+
# @param scope_builder [Class]
|
184
|
+
# @api public
|
185
|
+
# @!scope class
|
186
|
+
setting :scope_builder, default: ScopeBuilder
|
187
|
+
|
188
|
+
# @overload config.inflector=(inflector)
|
189
|
+
# Set an inflector to provide to the part_builder and scope_builder.
|
190
|
+
#
|
191
|
+
# Defaults to `Dry::Inflector.new`.
|
227
192
|
#
|
228
|
-
#
|
193
|
+
# @param inflector
|
194
|
+
# @api public
|
195
|
+
# @!scope class
|
196
|
+
setting :inflector, default: Dry::Inflector.new
|
197
|
+
|
198
|
+
# @overload config.renderer_options=(options)
|
199
|
+
# A hash of options to pass to the template engine. Template engines are
|
200
|
+
# provided by Tilt; see Tilt's documentation for what options your
|
201
|
+
# template engine may support.
|
202
|
+
#
|
203
|
+
# Defaults to `{default_encoding: "utf-8"}`. Any options passed will be
|
204
|
+
# merged onto the defaults.
|
205
|
+
#
|
206
|
+
# @see https://github.com/rtomayko/tilt
|
207
|
+
#
|
208
|
+
# @param options [Hash] renderer options
|
209
|
+
# @api public
|
210
|
+
# @!scope class
|
211
|
+
setting :renderer_options, default: DEFAULT_RENDERER_OPTIONS, constructor: -> options {
|
212
|
+
DEFAULT_RENDERER_OPTIONS.merge(options.to_h).freeze
|
213
|
+
}
|
214
|
+
|
215
|
+
# @overload config.renderer_engine_mapping=(mapping)
|
216
|
+
# A hash specifying the (Tilt-compatible) template engine class to use
|
217
|
+
# for a given format. Template engine detection is automatic based on
|
218
|
+
# format; use this setting only if you want to force a non-preferred
|
219
|
+
# engine.
|
229
220
|
#
|
230
|
-
#
|
231
|
-
#
|
232
|
-
# @see Hanami::View::Rendering
|
221
|
+
# @example
|
222
|
+
# config.renderer_engine_mapping = {erb: Tilt::ErubiTemplate}
|
233
223
|
#
|
234
|
-
#
|
235
|
-
# require 'hanami/view'
|
224
|
+
# @see https://github.com/rtomayko/tilt
|
236
225
|
#
|
237
|
-
#
|
238
|
-
#
|
239
|
-
#
|
240
|
-
|
241
|
-
conf = self.configuration
|
242
|
-
conf.add_view(base)
|
226
|
+
# @param mapping [Hash<Symbol, Class>] engine mapping
|
227
|
+
# @api public
|
228
|
+
# @!scope class
|
229
|
+
setting :renderer_engine_mapping
|
243
230
|
|
244
|
-
|
245
|
-
extend Inheritable
|
246
|
-
extend Dsl
|
247
|
-
extend Rendering
|
248
|
-
extend Escape
|
231
|
+
# @!endgroup
|
249
232
|
|
250
|
-
|
251
|
-
class_attribute :configuration
|
233
|
+
include StandaloneView
|
252
234
|
|
253
|
-
|
254
|
-
|
235
|
+
def self.inherited(subclass)
|
236
|
+
super
|
255
237
|
|
256
|
-
|
238
|
+
# If inheriting directly from Hanami::View within an Hanami app, configure
|
239
|
+
# the view for the application
|
240
|
+
if subclass.superclass == View && (provider = application_provider(subclass))
|
241
|
+
subclass.include ApplicationView.new(provider)
|
242
|
+
end
|
257
243
|
end
|
258
244
|
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
def self.load!
|
264
|
-
configuration.load!
|
245
|
+
def self.application_provider(subclass)
|
246
|
+
if Hanami.respond_to?(:application?) && Hanami.application?
|
247
|
+
Hanami.application.component_provider(subclass)
|
248
|
+
end
|
265
249
|
end
|
250
|
+
private_class_method :application_provider
|
266
251
|
end
|
267
252
|
end
|
data/lib/hanami-view.rb
CHANGED