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
@@ -1,128 +0,0 @@
|
|
1
|
-
require 'hanami/utils/string'
|
2
|
-
require 'hanami/utils/class'
|
3
|
-
require 'hanami/view/rendering/null_layout'
|
4
|
-
|
5
|
-
module Hanami
|
6
|
-
module View
|
7
|
-
module Rendering
|
8
|
-
# Defines the logic to find a layout
|
9
|
-
#
|
10
|
-
# @api private
|
11
|
-
# @since 0.1.0
|
12
|
-
#
|
13
|
-
# @see Hanami::Layout
|
14
|
-
class LayoutFinder
|
15
|
-
# Layout class name suffix
|
16
|
-
#
|
17
|
-
# @api private
|
18
|
-
# @since 0.1.0
|
19
|
-
SUFFIX = 'Layout'.freeze
|
20
|
-
|
21
|
-
# Find a layout from the given name.
|
22
|
-
#
|
23
|
-
# @param layout [Symbol,String,NilClass] layout name or nil if you want
|
24
|
-
# to fallback to the framework defaults (see `Hanami::View.layout`).
|
25
|
-
#
|
26
|
-
# @param namespace [Class,Module] a Ruby namespace where to lookup
|
27
|
-
#
|
28
|
-
# @return [Hanami::Layout] the layout for the given name or
|
29
|
-
# `Hanami::View.layout`
|
30
|
-
#
|
31
|
-
# @api private
|
32
|
-
# @since 0.1.0
|
33
|
-
#
|
34
|
-
# @example With given name
|
35
|
-
# require 'hanami/view'
|
36
|
-
#
|
37
|
-
# Hanami::View::Rendering::LayoutFinder.find(:article) # =>
|
38
|
-
# ArticleLayout
|
39
|
-
#
|
40
|
-
# @example With a class
|
41
|
-
# require 'hanami/view'
|
42
|
-
#
|
43
|
-
# Hanami::View::Rendering::LayoutFinder.find(ArticleLayout) # =>
|
44
|
-
# ArticleLayout
|
45
|
-
#
|
46
|
-
# @example With namespace
|
47
|
-
# require 'hanami/view'
|
48
|
-
#
|
49
|
-
# Hanami::View::Rendering::LayoutFinder.find(:application, CardDeck) # =>
|
50
|
-
# CardDeck::ApplicationLayout
|
51
|
-
#
|
52
|
-
# @example With nil
|
53
|
-
# require 'hanami/view'
|
54
|
-
#
|
55
|
-
# Hanami::View::Rendering::LayoutFinder.find(nil) # =>
|
56
|
-
# Hanami::View::Rendering::NullLayout
|
57
|
-
#
|
58
|
-
# @example With unknown layout
|
59
|
-
# require 'hanami/view'
|
60
|
-
#
|
61
|
-
# Hanami::View::Rendering::LayoutFinder.find(:unknown) # =>
|
62
|
-
# Hanami::View::Rendering::NullLayout
|
63
|
-
#
|
64
|
-
def self.find(layout, namespace = Object)
|
65
|
-
case layout
|
66
|
-
when Symbol, String
|
67
|
-
# TODO Move this low level logic into a Hanami::Utils solution
|
68
|
-
class_name = "#{ Utils::String.classify(layout) }#{ SUFFIX }"
|
69
|
-
namespace = Utils::Class.load!(namespace)
|
70
|
-
namespace.const_get(class_name)
|
71
|
-
when Class
|
72
|
-
layout
|
73
|
-
end || NullLayout
|
74
|
-
end
|
75
|
-
|
76
|
-
# Initialize the finder
|
77
|
-
#
|
78
|
-
# @param view [Class, #layout]
|
79
|
-
#
|
80
|
-
# @api private
|
81
|
-
# @since 0.1.0
|
82
|
-
def initialize(view)
|
83
|
-
@view = view
|
84
|
-
end
|
85
|
-
|
86
|
-
# Find the layout for the view
|
87
|
-
#
|
88
|
-
# @return [Hanami::Layout] the layout associated to the view
|
89
|
-
#
|
90
|
-
# @see Hanami::View::Rendering::LayoutFinder.find
|
91
|
-
# @see Hanami::View::Rendering::LayoutFinder#initialize
|
92
|
-
#
|
93
|
-
# @api private
|
94
|
-
# @since 0.1.0
|
95
|
-
#
|
96
|
-
# @example With layout
|
97
|
-
# require 'hanami/view'
|
98
|
-
#
|
99
|
-
# module Articles
|
100
|
-
# class Show
|
101
|
-
# include Hanami::View
|
102
|
-
# layout :article
|
103
|
-
# end
|
104
|
-
# end
|
105
|
-
#
|
106
|
-
# Hanami::View::Rendering::LayoutFinder.new(Articles::Show) # =>
|
107
|
-
# ArticleLayout
|
108
|
-
#
|
109
|
-
# @example Without layout
|
110
|
-
# require 'hanami/view'
|
111
|
-
#
|
112
|
-
# module Dashboard
|
113
|
-
# class Index
|
114
|
-
# include Hanami::View
|
115
|
-
# end
|
116
|
-
# end
|
117
|
-
#
|
118
|
-
# Hanami::View.layout # => :application
|
119
|
-
#
|
120
|
-
# Hanami::View::Rendering::LayoutFinder.new(Dashboard::Index) # =>
|
121
|
-
# ApplicationLayout
|
122
|
-
def find
|
123
|
-
self.class.find(@view.layout)
|
124
|
-
end
|
125
|
-
end
|
126
|
-
end
|
127
|
-
end
|
128
|
-
end
|
@@ -1,69 +0,0 @@
|
|
1
|
-
require 'hanami/view/rendering/null_template'
|
2
|
-
require 'hanami/view/rendering/templates_finder'
|
3
|
-
|
4
|
-
module Hanami
|
5
|
-
module View
|
6
|
-
module Rendering
|
7
|
-
# Holds the references of all the registered layouts.
|
8
|
-
# As now the registry is unique at the level of the framework.
|
9
|
-
#
|
10
|
-
# @api private
|
11
|
-
# @since 0.1.0
|
12
|
-
#
|
13
|
-
# @see Hanami::Layout::ClassMethods#registry
|
14
|
-
class LayoutRegistry
|
15
|
-
# Initialize the registry
|
16
|
-
#
|
17
|
-
# @param view [Class] the view
|
18
|
-
#
|
19
|
-
# @api private
|
20
|
-
# @since 0.1.0
|
21
|
-
def initialize(view)
|
22
|
-
@registry = {}
|
23
|
-
@view = view
|
24
|
-
prepare!
|
25
|
-
end
|
26
|
-
|
27
|
-
# Returns the layout for the given context.
|
28
|
-
#
|
29
|
-
# @param context [Hash] the rendering context
|
30
|
-
# @option context [Symbol] :format the requested format
|
31
|
-
#
|
32
|
-
# @return [Hanami::Layout, Hanami::View::Rendering::NullTemplate]
|
33
|
-
# the layout associated with the given context or a `NullTemplate` if
|
34
|
-
# it can't be found.
|
35
|
-
#
|
36
|
-
# @raise [Hanami::View::MissingFormatError] if the given context doesn't
|
37
|
-
# have the :format key
|
38
|
-
#
|
39
|
-
# @api private
|
40
|
-
# @since 0.1.0
|
41
|
-
def resolve(context)
|
42
|
-
@registry.fetch(format(context)) { NullTemplate.new }
|
43
|
-
end
|
44
|
-
|
45
|
-
protected
|
46
|
-
# @api private
|
47
|
-
# @since 0.1.0
|
48
|
-
def prepare!
|
49
|
-
templates.each do |template|
|
50
|
-
@registry.merge! template.format => template
|
51
|
-
end
|
52
|
-
@registry.any? or raise MissingTemplateLayoutError.new(@view)
|
53
|
-
end
|
54
|
-
|
55
|
-
# @api private
|
56
|
-
# @since 0.1.0
|
57
|
-
def templates
|
58
|
-
TemplatesFinder.new(@view).find
|
59
|
-
end
|
60
|
-
|
61
|
-
# @api private
|
62
|
-
# @since 0.1.0
|
63
|
-
def format(context)
|
64
|
-
context.fetch(:format) { raise MissingFormatError }
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
@@ -1,274 +0,0 @@
|
|
1
|
-
require 'hanami/view/rendering/null_local'
|
2
|
-
require 'hanami/view/rendering/options'
|
3
|
-
require 'hanami/utils/escape'
|
4
|
-
|
5
|
-
module Hanami
|
6
|
-
module View
|
7
|
-
module Rendering
|
8
|
-
# List of render types that exactly one of must be included when calling `#render`.
|
9
|
-
# For example, when calling `<%= render something: 'my_thing', locals: {} %>`,
|
10
|
-
# 'something' must be one of the values listed here.
|
11
|
-
#
|
12
|
-
# @since 1.1.0
|
13
|
-
# @api private
|
14
|
-
KNOWN_RENDER_TYPES = [:partial, :template].freeze
|
15
|
-
|
16
|
-
# Scope for layout rendering
|
17
|
-
#
|
18
|
-
# @since 0.1.0
|
19
|
-
class LayoutScope < BasicObject
|
20
|
-
# Initialize the scope
|
21
|
-
#
|
22
|
-
# @param layout [Hanami::Layout] the layout to render
|
23
|
-
# @param scope [Hanami::View::Rendering::Scope] the scope of the current
|
24
|
-
# view
|
25
|
-
#
|
26
|
-
# @api private
|
27
|
-
# @since 0.1.0
|
28
|
-
def initialize(layout, scope)
|
29
|
-
@layout = layout
|
30
|
-
@scope = scope
|
31
|
-
@view = nil
|
32
|
-
@locals = nil
|
33
|
-
end
|
34
|
-
|
35
|
-
# Returns the classname as string
|
36
|
-
#
|
37
|
-
# @return classname
|
38
|
-
#
|
39
|
-
# @since 0.3.0
|
40
|
-
def class
|
41
|
-
(class << self; self end).superclass
|
42
|
-
end
|
43
|
-
|
44
|
-
# Returns an inspect String
|
45
|
-
#
|
46
|
-
# @return [String] inspect String (contains classname, objectid in hex, available ivars)
|
47
|
-
#
|
48
|
-
# @since 0.3.0
|
49
|
-
def inspect
|
50
|
-
base = "#<#{ self.class }:#{'%x' % (self.object_id << 1)}"
|
51
|
-
base << " @layout=\"#{@layout.inspect}\"" if @layout
|
52
|
-
base << " @scope=\"#{@scope.inspect}\"" if @scope
|
53
|
-
base << ">"
|
54
|
-
end
|
55
|
-
|
56
|
-
# Render a partial or a template within a layout template.
|
57
|
-
#
|
58
|
-
# @param options [Hash]
|
59
|
-
# @option options [String] :partial the partial template to render
|
60
|
-
# @option options [String] :template the template to render
|
61
|
-
#
|
62
|
-
# @return [String] the output of the rendering process
|
63
|
-
#
|
64
|
-
# @raise [Hanami::Error::UnknownRenderTypeError] if the given type to
|
65
|
-
# be rendered is unknown
|
66
|
-
#
|
67
|
-
# @since 0.1.0
|
68
|
-
#
|
69
|
-
# @example Rendering partial
|
70
|
-
# # Given a partial under:
|
71
|
-
# # templates/shared/_sidebar.html.erb
|
72
|
-
# #
|
73
|
-
# # In the layout template:
|
74
|
-
# # templates/application.html.erb
|
75
|
-
# #
|
76
|
-
# # Use like this:
|
77
|
-
# <%= render partial: 'shared/sidebar' %>
|
78
|
-
#
|
79
|
-
# @example Rendering template
|
80
|
-
# # Given a template under:
|
81
|
-
# # templates/articles/index.html.erb
|
82
|
-
# #
|
83
|
-
# # In the layout template:
|
84
|
-
# # templates/application.html.erb
|
85
|
-
# #
|
86
|
-
# # Use like this:
|
87
|
-
# <%= render template: 'articles/index' %>
|
88
|
-
#
|
89
|
-
# @example Rendering partial, using optional :locals
|
90
|
-
# # Given a partial under:
|
91
|
-
# # templates/shared/_sidebar.html.erb
|
92
|
-
# #
|
93
|
-
# # In the layout template:
|
94
|
-
# # templates/application.html.erb
|
95
|
-
# #
|
96
|
-
# # Use like this:
|
97
|
-
# <%= render partial: 'shared/sidebar', { user: current_user } %>
|
98
|
-
#
|
99
|
-
# #
|
100
|
-
# # `user` will be available in the scope of the sidebar rendering
|
101
|
-
def render(options)
|
102
|
-
renderer(options).render
|
103
|
-
end
|
104
|
-
|
105
|
-
# Returns the requested format.
|
106
|
-
#
|
107
|
-
# @return [Symbol] the requested format (eg. :html, :json, :xml, etc..)
|
108
|
-
#
|
109
|
-
# @since 0.1.0
|
110
|
-
def format
|
111
|
-
@scope.format
|
112
|
-
end
|
113
|
-
|
114
|
-
# The current view.
|
115
|
-
#
|
116
|
-
# @return [Hanami::View] the current view
|
117
|
-
#
|
118
|
-
# @since 0.1.0
|
119
|
-
def view
|
120
|
-
@view || @scope.view
|
121
|
-
end
|
122
|
-
|
123
|
-
# The current locals.
|
124
|
-
#
|
125
|
-
# @return [Hash] the current locals
|
126
|
-
#
|
127
|
-
# @since 0.1.0
|
128
|
-
def locals
|
129
|
-
(@locals || @scope.locals).dup
|
130
|
-
end
|
131
|
-
|
132
|
-
# It tries to invoke a method for the view or a local for the given key.
|
133
|
-
# If the lookup fails, it returns a null object.
|
134
|
-
#
|
135
|
-
# @return [Object,Hanami::View::Rendering::NullLocal] the returning value
|
136
|
-
#
|
137
|
-
# @since 0.7.0
|
138
|
-
#
|
139
|
-
# @example Safe method navigation
|
140
|
-
# <% if local(:plan).overdue? %>
|
141
|
-
# <h2>Your plan is overdue.</h2>
|
142
|
-
# <% end %>
|
143
|
-
#
|
144
|
-
# @example Optional Contents
|
145
|
-
# # Given the following layout template
|
146
|
-
#
|
147
|
-
# <!doctype HTML>
|
148
|
-
# <html>
|
149
|
-
# <!-- ... -->
|
150
|
-
# <body>
|
151
|
-
# <!-- ... -->
|
152
|
-
# <%= local :footer %>
|
153
|
-
# </body>
|
154
|
-
# </html>
|
155
|
-
#
|
156
|
-
# # Case 1:
|
157
|
-
# # Products::Index doesn't respond to #footer, local will return nil
|
158
|
-
# #
|
159
|
-
# # Case 2:
|
160
|
-
# # Products::Show responds to #footer, local will send back
|
161
|
-
# # #footer returning value
|
162
|
-
#
|
163
|
-
# module Products
|
164
|
-
# class Index
|
165
|
-
# include Hanami::View
|
166
|
-
# end
|
167
|
-
#
|
168
|
-
# class Show
|
169
|
-
# include Hanami::View
|
170
|
-
#
|
171
|
-
# def footer
|
172
|
-
# "contents for footer"
|
173
|
-
# end
|
174
|
-
# end
|
175
|
-
# end
|
176
|
-
def local(key)
|
177
|
-
if respond_to?(key)
|
178
|
-
__send__(key)
|
179
|
-
else
|
180
|
-
locals.fetch(key) { NullLocal.new(key) }
|
181
|
-
end
|
182
|
-
end
|
183
|
-
|
184
|
-
# Implements "respond to" logic
|
185
|
-
#
|
186
|
-
# @return [TrueClass,FalseClass]
|
187
|
-
#
|
188
|
-
# @since 0.3.0
|
189
|
-
# @api private
|
190
|
-
#
|
191
|
-
# @see http://ruby-doc.org/core/Object.html#method-i-respond_to-3F
|
192
|
-
def respond_to?(m, include_all = false)
|
193
|
-
respond_to_missing?(m, include_all)
|
194
|
-
end
|
195
|
-
|
196
|
-
# Implements "respond to" logic
|
197
|
-
#
|
198
|
-
# @return [TrueClass,FalseClass]
|
199
|
-
#
|
200
|
-
# @since 0.3.0
|
201
|
-
# @api private
|
202
|
-
#
|
203
|
-
# @see http://ruby-doc.org/core/Object.html#method-i-respond_to_missing-3F
|
204
|
-
def respond_to_missing?(m, include_all)
|
205
|
-
@layout.respond_to?(m, include_all) ||
|
206
|
-
@scope.respond_to?(m, include_all)
|
207
|
-
end
|
208
|
-
|
209
|
-
protected
|
210
|
-
|
211
|
-
# Forward all the missing methods to the view scope or to the layout.
|
212
|
-
#
|
213
|
-
# @api private
|
214
|
-
# @since 0.1.0
|
215
|
-
#
|
216
|
-
# @see Hanami::View::Rendering::Scope
|
217
|
-
# @see Hanami::Layout
|
218
|
-
#
|
219
|
-
# @example
|
220
|
-
# # In the layout template:
|
221
|
-
# # templates/application.html.erb
|
222
|
-
# #
|
223
|
-
# # Use like this:
|
224
|
-
# <title><%= article.title %></title>
|
225
|
-
#
|
226
|
-
# # `article` will be looked up in the view scope first.
|
227
|
-
# # If not found, it will be searched within the layout.
|
228
|
-
def method_missing(m, *args, &blk)
|
229
|
-
# FIXME: this isn't compatible with Hanami 2.0, as it extends a view
|
230
|
-
# that we want to be frozen in the future
|
231
|
-
#
|
232
|
-
# See https://github.com/hanami/view/issues/130#issuecomment-319326236
|
233
|
-
if @scope.respond_to?(m, true) && @scope.locals.has_key?(m) && layout.respond_to?(m, true)
|
234
|
-
layout.__send__(m, *args, &blk)
|
235
|
-
elsif @scope.respond_to?(m, true)
|
236
|
-
@scope.__send__(m, *args, &blk)
|
237
|
-
elsif layout.respond_to?(m, true)
|
238
|
-
layout.__send__(m, *args, &blk)
|
239
|
-
else
|
240
|
-
::Hanami::View::Escape.html(super)
|
241
|
-
end
|
242
|
-
end
|
243
|
-
|
244
|
-
# @api private
|
245
|
-
def renderer(options)
|
246
|
-
if options[:partial]
|
247
|
-
Rendering::Partial
|
248
|
-
elsif options[:template]
|
249
|
-
Rendering::Template
|
250
|
-
else
|
251
|
-
::Kernel.raise UnknownRenderTypeError.new(KNOWN_RENDER_TYPES, options)
|
252
|
-
end.new(view, _options(options))
|
253
|
-
end
|
254
|
-
|
255
|
-
private
|
256
|
-
|
257
|
-
# @api private
|
258
|
-
def _options(options)
|
259
|
-
current_locals = locals.reject do |key, _|
|
260
|
-
@scope.respond_to?(key, true) &&
|
261
|
-
(layout.respond_to?(key, true) || @scope.view.respond_to?(:name, true))
|
262
|
-
end
|
263
|
-
Options.build(options, current_locals, format)
|
264
|
-
end
|
265
|
-
|
266
|
-
# @since 0.4.2
|
267
|
-
# @api private
|
268
|
-
def layout
|
269
|
-
@layout || @layout.class.layout.new(@scope, "")
|
270
|
-
end
|
271
|
-
end
|
272
|
-
end
|
273
|
-
end
|
274
|
-
end
|
@@ -1,52 +0,0 @@
|
|
1
|
-
module Hanami
|
2
|
-
module View
|
3
|
-
module Rendering
|
4
|
-
# Null Object pattern for Layout.
|
5
|
-
# It's used when a view doesn't require a layout.
|
6
|
-
#
|
7
|
-
# @api private
|
8
|
-
# @since 0.1.0
|
9
|
-
#
|
10
|
-
# @example
|
11
|
-
# require 'hanami/view'
|
12
|
-
#
|
13
|
-
# module Articles
|
14
|
-
# class Show
|
15
|
-
# include Hanami::View
|
16
|
-
# layout false
|
17
|
-
# end
|
18
|
-
# end
|
19
|
-
#
|
20
|
-
# # In this scenario we will use a `NullLayout`.
|
21
|
-
class NullLayout
|
22
|
-
|
23
|
-
# Initialize a layout
|
24
|
-
#
|
25
|
-
# @param scope [Hanami::View::Rendering::Scope] view rendering scope
|
26
|
-
# @param rendered [String] the output of the view rendering process
|
27
|
-
#
|
28
|
-
# @api private
|
29
|
-
# @since 0.1.0
|
30
|
-
#
|
31
|
-
# @see Hanami::Layout#initialize
|
32
|
-
# @see Hanami::View::Rendering#render
|
33
|
-
def initialize(scope, rendered)
|
34
|
-
@rendered = rendered
|
35
|
-
end
|
36
|
-
|
37
|
-
# Render the layout
|
38
|
-
#
|
39
|
-
# @return [String] the output of the rendering process
|
40
|
-
#
|
41
|
-
# @api private
|
42
|
-
# @since 0.1.0
|
43
|
-
#
|
44
|
-
# @see Hanami::Layout#render
|
45
|
-
# @see Hanami::View::Rendering#render
|
46
|
-
def render
|
47
|
-
@rendered
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
@@ -1,82 +0,0 @@
|
|
1
|
-
require 'hanami/utils/basic_object'
|
2
|
-
|
3
|
-
module Hanami
|
4
|
-
module View
|
5
|
-
module Rendering
|
6
|
-
# Null local
|
7
|
-
#
|
8
|
-
# @since 0.7.0
|
9
|
-
#
|
10
|
-
# @see Hanami::View::Rendering#local
|
11
|
-
class NullLocal < Utils::BasicObject
|
12
|
-
# @since 0.7.0
|
13
|
-
# @api private
|
14
|
-
TO_STR = "".freeze
|
15
|
-
|
16
|
-
# @since 0.7.0
|
17
|
-
# @api private
|
18
|
-
def initialize(local)
|
19
|
-
@local = local
|
20
|
-
end
|
21
|
-
|
22
|
-
# @since 0.7.0
|
23
|
-
# @api private
|
24
|
-
def all?
|
25
|
-
false
|
26
|
-
end
|
27
|
-
|
28
|
-
# @since 0.7.0
|
29
|
-
# @api private
|
30
|
-
def any?
|
31
|
-
false
|
32
|
-
end
|
33
|
-
|
34
|
-
# @since 0.7.0
|
35
|
-
# @api private
|
36
|
-
def empty?
|
37
|
-
true
|
38
|
-
end
|
39
|
-
|
40
|
-
# @since 0.7.0
|
41
|
-
# @api private
|
42
|
-
def nil?
|
43
|
-
true
|
44
|
-
end
|
45
|
-
|
46
|
-
# @since 0.7.0
|
47
|
-
# @api private
|
48
|
-
def to_str
|
49
|
-
TO_STR
|
50
|
-
end
|
51
|
-
|
52
|
-
# @since 0.8.0
|
53
|
-
# @api private
|
54
|
-
alias to_s to_str
|
55
|
-
|
56
|
-
# @since 0.7.0
|
57
|
-
# @api private
|
58
|
-
def method_missing(m, *)
|
59
|
-
if m.match(/\?\z/)
|
60
|
-
false
|
61
|
-
else
|
62
|
-
self.class.new("#{ @local }.#{ m }")
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
private
|
67
|
-
|
68
|
-
# @since 0.7.0
|
69
|
-
# @api private
|
70
|
-
def respond_to_missing?(method_name, include_all)
|
71
|
-
true
|
72
|
-
end
|
73
|
-
|
74
|
-
# @since 0.7.0
|
75
|
-
# @api private
|
76
|
-
def __inspect
|
77
|
-
" :#{ @local }"
|
78
|
-
end
|
79
|
-
end
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
@@ -1,83 +0,0 @@
|
|
1
|
-
module Hanami
|
2
|
-
module View
|
3
|
-
module Rendering
|
4
|
-
# Null Object pattern for layout template
|
5
|
-
#
|
6
|
-
# It's used when a layout doesn't have an associated template.
|
7
|
-
#
|
8
|
-
# A common scenario is for non-html requests.
|
9
|
-
# Usually we have a template for the application layout
|
10
|
-
# (eg `templates/application.html.erb`), but we don't use to have the
|
11
|
-
# template for JSON requests (eg `templates/application.json.erb`).
|
12
|
-
# Because most of the times, we only return the output of the view.
|
13
|
-
#
|
14
|
-
# @api private
|
15
|
-
# @since 0.1.0
|
16
|
-
#
|
17
|
-
# @example
|
18
|
-
# require 'hanami/view'
|
19
|
-
#
|
20
|
-
# # We have an ApplicationLayout (views/application_layout.rb):
|
21
|
-
# class ApplicationLayout
|
22
|
-
# include Hanami::Layout
|
23
|
-
# end
|
24
|
-
#
|
25
|
-
# # Our layout has a template for HTML requests, located at:
|
26
|
-
# # templates/application.html.erb
|
27
|
-
#
|
28
|
-
# # We set it as global layout
|
29
|
-
# Hanami::View.layout = :application
|
30
|
-
#
|
31
|
-
# # We have two views for HTML and JSON articles.
|
32
|
-
# # They have a template each:
|
33
|
-
# #
|
34
|
-
# # * templates/articles/show.html.erb
|
35
|
-
# # * templates/articles/show.json.erb
|
36
|
-
# module Articles
|
37
|
-
# class Show
|
38
|
-
# include Hanami::View
|
39
|
-
# format :html
|
40
|
-
# end
|
41
|
-
#
|
42
|
-
# class JsonShow < Show
|
43
|
-
# format :json
|
44
|
-
# end
|
45
|
-
# end
|
46
|
-
#
|
47
|
-
# # We initialize the framework
|
48
|
-
# Hanami::View.load!
|
49
|
-
#
|
50
|
-
#
|
51
|
-
#
|
52
|
-
# # When we ask for a HTML rendering, it will use `Articles::Show` and
|
53
|
-
# # ApplicationLayout. The output will be a composition of:
|
54
|
-
# #
|
55
|
-
# # * templates/articles/show.html.erb
|
56
|
-
# # * templates/application.html.erb
|
57
|
-
#
|
58
|
-
# # When we ask for a JSON rendering, it will use `Articles::JsonShow`
|
59
|
-
# # and ApplicationLayout. Since, the layout doesn't have any associated
|
60
|
-
# # template for JSON, the output will be a composition of:
|
61
|
-
# #
|
62
|
-
# # * templates/articles/show.json.erb
|
63
|
-
class NullTemplate
|
64
|
-
# Render the layout template
|
65
|
-
#
|
66
|
-
# @param scope [Hanami::View::Scope] the rendering scope
|
67
|
-
# @param locals [Hash] a set of objects available during the rendering
|
68
|
-
# @yield [Proc] yields the given block
|
69
|
-
#
|
70
|
-
# @return [String] the output of the rendering process
|
71
|
-
#
|
72
|
-
# @api private
|
73
|
-
# @since 0.1.0
|
74
|
-
#
|
75
|
-
# @see Hanami::Layout#render
|
76
|
-
# @see Hanami::View::Rendering#render
|
77
|
-
def render(scope, locals = {})
|
78
|
-
yield
|
79
|
-
end
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
83
|
-
end
|
@@ -1,26 +0,0 @@
|
|
1
|
-
module Hanami
|
2
|
-
module View
|
3
|
-
module Rendering
|
4
|
-
# Null Object pattern for view
|
5
|
-
#
|
6
|
-
# It's used when a layout is rendered direcly for testing purposes
|
7
|
-
#
|
8
|
-
# @api private
|
9
|
-
# @since 1.2.1
|
10
|
-
class NullView
|
11
|
-
# Render the layout template
|
12
|
-
#
|
13
|
-
# @return [String] an empty string
|
14
|
-
#
|
15
|
-
# @api private
|
16
|
-
# @since 1.2.1
|
17
|
-
#
|
18
|
-
# @see Hanami::Layout#render
|
19
|
-
# @see Hanami::View::Rendering#render
|
20
|
-
def render
|
21
|
-
""
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|