lotus-view 0.0.0 → 0.1.0
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/.gitignore +6 -15
- data/.travis.yml +6 -0
- data/.yardopts +3 -0
- data/Gemfile +13 -2
- data/README.md +514 -3
- data/Rakefile +17 -1
- data/lib/lotus/layout.rb +132 -0
- data/lib/lotus/presenter.rb +70 -0
- data/lib/lotus/view/dsl.rb +247 -0
- data/lib/lotus/view/inheritable.rb +50 -0
- data/lib/lotus/view/rendering/layout_finder.rb +104 -0
- data/lib/lotus/view/rendering/layout_registry.rb +63 -0
- data/lib/lotus/view/rendering/layout_scope.rb +138 -0
- data/lib/lotus/view/rendering/null_layout.rb +52 -0
- data/lib/lotus/view/rendering/null_template.rb +79 -0
- data/lib/lotus/view/rendering/partial.rb +29 -0
- data/lib/lotus/view/rendering/partial_finder.rb +41 -0
- data/lib/lotus/view/rendering/registry.rb +129 -0
- data/lib/lotus/view/rendering/scope.rb +48 -0
- data/lib/lotus/view/rendering/template.rb +56 -0
- data/lib/lotus/view/rendering/template_finder.rb +53 -0
- data/lib/lotus/view/rendering/templates_finder.rb +85 -0
- data/lib/lotus/view/rendering/view_finder.rb +37 -0
- data/lib/lotus/view/rendering.rb +265 -0
- data/lib/lotus/view/template.rb +45 -0
- data/lib/lotus/view/version.rb +4 -1
- data/lib/lotus/view.rb +180 -2
- data/lib/lotus-view.rb +1 -0
- data/lotus-view.gemspec +15 -11
- data/test/fixtures/templates/app/app_view.html.erb +0 -0
- data/test/fixtures/templates/app/view.html.erb +0 -0
- data/test/fixtures/templates/application.html.erb +10 -0
- data/test/fixtures/templates/articles/_form.html.erb +4 -0
- data/test/fixtures/templates/articles/alternative_new.html.erb +1 -0
- data/test/fixtures/templates/articles/index.atom.erb +5 -0
- data/test/fixtures/templates/articles/index.html.erb +3 -0
- data/test/fixtures/templates/articles/index.json.erb +9 -0
- data/test/fixtures/templates/articles/index.rss.erb +0 -0
- data/test/fixtures/templates/articles/new.html.erb +7 -0
- data/test/fixtures/templates/articles/show.html.erb +1 -0
- data/test/fixtures/templates/articles/show.json.erb +5 -0
- data/test/fixtures/templates/contacts/show.html.haml +1 -0
- data/test/fixtures/templates/dashboard/index.html.erb +2 -0
- data/test/fixtures/templates/hello_world_view.html.erb +1 -0
- data/test/fixtures/templates/index_view.html.erb +1 -0
- data/test/fixtures/templates/json_render_view.json.erb +3 -0
- data/test/fixtures/templates/render_view.html.erb +1 -0
- data/test/fixtures/templates/shared/_sidebar.html.erb +1 -0
- data/test/fixtures.rb +187 -0
- data/test/layout_test.rb +10 -0
- data/test/load_test.rb +79 -0
- data/test/presenter_test.rb +31 -0
- data/test/rendering_test.rb +125 -0
- data/test/root_test.rb +38 -0
- data/test/test_helper.rb +24 -0
- data/test/version_test.rb +7 -0
- data/test/view_test.rb +27 -0
- metadata +137 -10
data/lib/lotus/layout.rb
ADDED
@@ -0,0 +1,132 @@
|
|
1
|
+
require 'lotus/view/rendering/layout_registry'
|
2
|
+
require 'lotus/view/rendering/layout_scope'
|
3
|
+
require 'lotus/view/rendering/null_layout'
|
4
|
+
|
5
|
+
module Lotus
|
6
|
+
# Layout
|
7
|
+
#
|
8
|
+
# @since 0.1.0
|
9
|
+
#
|
10
|
+
# @see Lotus::Layout::ClassMethods
|
11
|
+
module Layout
|
12
|
+
# Register a layout
|
13
|
+
#
|
14
|
+
# @api private
|
15
|
+
# @since 0.1.0
|
16
|
+
#
|
17
|
+
# @example
|
18
|
+
# require 'lotus/view'
|
19
|
+
#
|
20
|
+
# class ApplicationLayout
|
21
|
+
# include Lotus::Layout
|
22
|
+
# end
|
23
|
+
def self.included(base)
|
24
|
+
base.class_eval do
|
25
|
+
extend Lotus::View::Dsl.dup
|
26
|
+
extend ClassMethods
|
27
|
+
end
|
28
|
+
|
29
|
+
Lotus::View.layouts.add(base)
|
30
|
+
end
|
31
|
+
|
32
|
+
# Class level API
|
33
|
+
#
|
34
|
+
# @since 0.1.0
|
35
|
+
module ClassMethods
|
36
|
+
# Template name suffix
|
37
|
+
#
|
38
|
+
# @api private
|
39
|
+
# @since 0.1.0
|
40
|
+
#
|
41
|
+
# @see Lotus::Layout::ClassMethods#suffix
|
42
|
+
# @see Lotus::Layout::ClassMethods#template
|
43
|
+
SUFFIX = '_layout'.freeze
|
44
|
+
|
45
|
+
# A registry that holds all the registered layouts.
|
46
|
+
#
|
47
|
+
# @api private
|
48
|
+
# @since 0.1.0
|
49
|
+
#
|
50
|
+
# @see Lotus::View::Rendering::LayoutRegistry
|
51
|
+
def registry
|
52
|
+
@@registry ||= View::Rendering::LayoutRegistry.new(self)
|
53
|
+
end
|
54
|
+
|
55
|
+
# Template name
|
56
|
+
#
|
57
|
+
# @api private
|
58
|
+
# @since 0.1.0
|
59
|
+
#
|
60
|
+
# @see Lotus::Layout::ClassMethods#SUFFIX
|
61
|
+
# @see Lotus::Layout::ClassMethods#suffix
|
62
|
+
#
|
63
|
+
# @example
|
64
|
+
# # Given a template 'templates/application.html.erb'
|
65
|
+
#
|
66
|
+
# class ApplicationLayout
|
67
|
+
# include Lotus::Layout
|
68
|
+
# end
|
69
|
+
#
|
70
|
+
# ApplicationLayout.template # => 'application'
|
71
|
+
def template
|
72
|
+
super.gsub(suffix, '')
|
73
|
+
end
|
74
|
+
|
75
|
+
# Template name suffix
|
76
|
+
#
|
77
|
+
# @api private
|
78
|
+
# @since 0.1.0
|
79
|
+
#
|
80
|
+
# @see Lotus::Layout::ClassMethods#SUFFIX
|
81
|
+
# @see Lotus::Layout::ClassMethods#template
|
82
|
+
def suffix
|
83
|
+
SUFFIX
|
84
|
+
end
|
85
|
+
|
86
|
+
protected
|
87
|
+
# Loading mechanism hook.
|
88
|
+
#
|
89
|
+
# @api private
|
90
|
+
# @since 0.1.0
|
91
|
+
#
|
92
|
+
# @see Lotus::View.load!
|
93
|
+
def load!
|
94
|
+
registry.freeze
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
# Initialize a layout
|
99
|
+
#
|
100
|
+
# @param scope [Lotus::View::Rendering::Scope] view rendering scope
|
101
|
+
# @param rendered [String] the output of the view rendering process
|
102
|
+
#
|
103
|
+
# @api private
|
104
|
+
# @since 0.1.0
|
105
|
+
#
|
106
|
+
# @see Lotus::View::Rendering#render
|
107
|
+
def initialize(scope, rendered)
|
108
|
+
@scope, @rendered = View::Rendering::LayoutScope.new(self, scope), rendered
|
109
|
+
end
|
110
|
+
|
111
|
+
# Render the layout
|
112
|
+
#
|
113
|
+
# @return [String] the output of the rendering process
|
114
|
+
#
|
115
|
+
# @api private
|
116
|
+
# @since 0.1.0
|
117
|
+
#
|
118
|
+
# @see Lotus::View::Rendering#render
|
119
|
+
def render
|
120
|
+
template.render(@scope, &Proc.new{@rendered})
|
121
|
+
end
|
122
|
+
|
123
|
+
protected
|
124
|
+
# The template for the current format
|
125
|
+
#
|
126
|
+
# @api private
|
127
|
+
# @since 0.1.0
|
128
|
+
def template
|
129
|
+
self.class.registry.resolve({format: @scope.format})
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module Lotus
|
2
|
+
# Presenter pattern implementation
|
3
|
+
#
|
4
|
+
# @since 0.1.0
|
5
|
+
#
|
6
|
+
# @example
|
7
|
+
# require 'lotus/view'
|
8
|
+
#
|
9
|
+
# class Map
|
10
|
+
# attr_reader :locations
|
11
|
+
#
|
12
|
+
# def initialize(locations)
|
13
|
+
# @locations = locations
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
# def location_names
|
17
|
+
# @locations.join(', ')
|
18
|
+
# end
|
19
|
+
# end
|
20
|
+
#
|
21
|
+
# class MapPresenter
|
22
|
+
# include Lotus::Presenter
|
23
|
+
#
|
24
|
+
# def count
|
25
|
+
# locations.count
|
26
|
+
# end
|
27
|
+
#
|
28
|
+
# def location_names
|
29
|
+
# super.upcase
|
30
|
+
# end
|
31
|
+
#
|
32
|
+
# def inspect_object
|
33
|
+
# @object.inspect
|
34
|
+
# end
|
35
|
+
# end
|
36
|
+
#
|
37
|
+
# map = Map.new(['Rome', 'Boston'])
|
38
|
+
# presenter = MapPresenter.new(map)
|
39
|
+
#
|
40
|
+
# # access a map method
|
41
|
+
# puts presenter.locations # => ['Rome', 'Boston']
|
42
|
+
#
|
43
|
+
# # access presenter concrete methods
|
44
|
+
# puts presenter.count # => 1
|
45
|
+
#
|
46
|
+
# # uses super to access original object implementation
|
47
|
+
# puts presenter.location_names # => 'ROME, BOSTON'
|
48
|
+
#
|
49
|
+
# # it has private access to the original object
|
50
|
+
# puts presenter.inspect_object # => #<Map:0x007fdeada0b2f0 @locations=["Rome", "Boston"]>
|
51
|
+
module Presenter
|
52
|
+
# Initialize the presenter
|
53
|
+
#
|
54
|
+
# @param object [Object] the object to present
|
55
|
+
#
|
56
|
+
# @since 0.1.0
|
57
|
+
def initialize(object)
|
58
|
+
@object = object
|
59
|
+
end
|
60
|
+
|
61
|
+
protected
|
62
|
+
def method_missing(m, *args, &blk)
|
63
|
+
if @object.respond_to?(m)
|
64
|
+
@object.__send__ m, *args, &blk
|
65
|
+
else
|
66
|
+
super
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,247 @@
|
|
1
|
+
require 'lotus/utils/string'
|
2
|
+
require 'lotus/view/rendering/layout_finder'
|
3
|
+
|
4
|
+
module Lotus
|
5
|
+
module View
|
6
|
+
# Class level DSL
|
7
|
+
#
|
8
|
+
# @since 0.1.0
|
9
|
+
module Dsl
|
10
|
+
# When a value is given, specify a templates root path for the view.
|
11
|
+
# Otherwise, it returns templates root path.
|
12
|
+
#
|
13
|
+
# When not initialized, it will return the global value from `Lotus::View.root`.
|
14
|
+
#
|
15
|
+
# @param value [String] the templates root for this view
|
16
|
+
#
|
17
|
+
# @return [Pathname] the specified root for this view or the global value
|
18
|
+
#
|
19
|
+
# @since 0.1.0
|
20
|
+
#
|
21
|
+
# @example Default usage
|
22
|
+
# require 'lotus/view'
|
23
|
+
#
|
24
|
+
# module Articles
|
25
|
+
# class Show
|
26
|
+
# include Lotus::View
|
27
|
+
# end
|
28
|
+
# end
|
29
|
+
#
|
30
|
+
# Lotus::View.root # => 'app/templates'
|
31
|
+
# Articles::Show.root # => 'app/templates'
|
32
|
+
#
|
33
|
+
# @example Custom root
|
34
|
+
# require 'lotus/view'
|
35
|
+
#
|
36
|
+
# module Articles
|
37
|
+
# class Show
|
38
|
+
# include Lotus::View
|
39
|
+
# root 'path/to/articles/templates'
|
40
|
+
# end
|
41
|
+
# end
|
42
|
+
#
|
43
|
+
# Lotus::View.root # => 'app/templates'
|
44
|
+
# Articles::Show.root # => 'path/to/articles/templates'
|
45
|
+
def root(value = nil)
|
46
|
+
if value
|
47
|
+
@@root = Pathname.new value
|
48
|
+
else
|
49
|
+
@@root ||= Lotus::View.root
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# When a value is given, specify the handled format.
|
54
|
+
# Otherwise, it returns the previously specified format.
|
55
|
+
#
|
56
|
+
# @param value [Symbol] the format
|
57
|
+
#
|
58
|
+
# @return [Symbol, nil] the specified format for this view, if set
|
59
|
+
#
|
60
|
+
# @since 0.1.0
|
61
|
+
#
|
62
|
+
# @example
|
63
|
+
# require 'lotus/view'
|
64
|
+
#
|
65
|
+
# module Articles
|
66
|
+
# class Show
|
67
|
+
# include Lotus::View
|
68
|
+
# end
|
69
|
+
#
|
70
|
+
# class JsonShow < Show
|
71
|
+
# format :json
|
72
|
+
# end
|
73
|
+
# end
|
74
|
+
#
|
75
|
+
# Articles::Show.format # => nil
|
76
|
+
# Articles::JsonShow.format # => :json
|
77
|
+
def format(value = nil)
|
78
|
+
if value
|
79
|
+
@format = value
|
80
|
+
else
|
81
|
+
@format
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
# When a value is given, specify the relative path to the template.
|
86
|
+
# Otherwise, it returns the name that follows Lotus::View conventions.
|
87
|
+
#
|
88
|
+
# @param value [String] relative template path
|
89
|
+
#
|
90
|
+
# @return [String] the specified template for this view or the name
|
91
|
+
# that follows the convention
|
92
|
+
#
|
93
|
+
# @since 0.1.0
|
94
|
+
#
|
95
|
+
# @example Default usage
|
96
|
+
# require 'lotus/view'
|
97
|
+
#
|
98
|
+
# module Articles
|
99
|
+
# class Show
|
100
|
+
# include Lotus::View
|
101
|
+
# end
|
102
|
+
#
|
103
|
+
# class JsonShow < Show
|
104
|
+
# format :json
|
105
|
+
# end
|
106
|
+
# end
|
107
|
+
#
|
108
|
+
# Articles::Show.template # => 'articles/show'
|
109
|
+
# Articles::JsonShow.template # => 'articles/show'
|
110
|
+
#
|
111
|
+
# @example Custom template
|
112
|
+
# require 'lotus/view'
|
113
|
+
#
|
114
|
+
# module Articles
|
115
|
+
# class Show
|
116
|
+
# include Lotus::View
|
117
|
+
# template 'articles/single_article'
|
118
|
+
# end
|
119
|
+
#
|
120
|
+
# class JsonShow < Show
|
121
|
+
# format :json
|
122
|
+
# end
|
123
|
+
# end
|
124
|
+
#
|
125
|
+
# Articles::Show.template # => 'articles/single_article'
|
126
|
+
# Articles::JsonShow.template # => 'articles/single_article'
|
127
|
+
def template(value = nil)
|
128
|
+
if value
|
129
|
+
@@template = value
|
130
|
+
else
|
131
|
+
@@template ||= Utils::String.new(name).underscore
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
# When a value is given, it specifies the layout.
|
136
|
+
# Otherwise, it returns the previously specified layout.
|
137
|
+
#
|
138
|
+
# When the global configuration is set (`Lotus::View.layout=`), after the
|
139
|
+
# loading process, it will return that layout if not otherwise specified.
|
140
|
+
#
|
141
|
+
# @param value [Symbol,nil] the layout name
|
142
|
+
#
|
143
|
+
# @return [Symbol, nil] the specified layout for this view, if set
|
144
|
+
#
|
145
|
+
# @since 0.1.0
|
146
|
+
#
|
147
|
+
# @see Lotus::Layout
|
148
|
+
#
|
149
|
+
# @example Default usage
|
150
|
+
# require 'lotus/view'
|
151
|
+
#
|
152
|
+
# module Articles
|
153
|
+
# class Show
|
154
|
+
# include Lotus::View
|
155
|
+
# end
|
156
|
+
# end
|
157
|
+
#
|
158
|
+
# Articles::Show.layout # => nil
|
159
|
+
#
|
160
|
+
# @example Custom layout
|
161
|
+
# require 'lotus/view'
|
162
|
+
#
|
163
|
+
# class ArticlesLayout
|
164
|
+
# include Lotus::Layout
|
165
|
+
# end
|
166
|
+
#
|
167
|
+
# module Articles
|
168
|
+
# class Show
|
169
|
+
# include Lotus::View
|
170
|
+
# layout :articles
|
171
|
+
# end
|
172
|
+
# end
|
173
|
+
#
|
174
|
+
# Articles::Show.layout # => :articles
|
175
|
+
#
|
176
|
+
# @example Global configuration
|
177
|
+
# require 'lotus/view'
|
178
|
+
#
|
179
|
+
# class ApplicationLayout
|
180
|
+
# include Lotus::Layout
|
181
|
+
# end
|
182
|
+
#
|
183
|
+
# module Articles
|
184
|
+
# class Show
|
185
|
+
# include Lotus::View
|
186
|
+
# end
|
187
|
+
# end
|
188
|
+
#
|
189
|
+
# Lotus::View.layout = :application
|
190
|
+
# Articles::Show.layout # => nil
|
191
|
+
#
|
192
|
+
# Lotus::View.load!
|
193
|
+
# Articles::Show.layout # => :application
|
194
|
+
#
|
195
|
+
# @example Global configuration with custom layout
|
196
|
+
# require 'lotus/view'
|
197
|
+
#
|
198
|
+
# class ApplicationLayout
|
199
|
+
# include Lotus::Layout
|
200
|
+
# end
|
201
|
+
#
|
202
|
+
# class ArticlesLayout
|
203
|
+
# include Lotus::Layout
|
204
|
+
# end
|
205
|
+
#
|
206
|
+
# module Articles
|
207
|
+
# class Show
|
208
|
+
# include Lotus::View
|
209
|
+
# layout :articles
|
210
|
+
# end
|
211
|
+
# end
|
212
|
+
#
|
213
|
+
# Lotus::View.layout = :application
|
214
|
+
# Articles::Show.layout # => :articles
|
215
|
+
#
|
216
|
+
# Lotus::View.load!
|
217
|
+
# Articles::Show.layout # => :articles
|
218
|
+
def layout(value = nil)
|
219
|
+
if value
|
220
|
+
@layout = value
|
221
|
+
else
|
222
|
+
@layout
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
protected
|
227
|
+
|
228
|
+
# Loading mechanism hook.
|
229
|
+
#
|
230
|
+
# @api private
|
231
|
+
# @since 0.1.0
|
232
|
+
#
|
233
|
+
# @see Lotus::View.load!
|
234
|
+
def load!
|
235
|
+
super
|
236
|
+
|
237
|
+
views.each do |v|
|
238
|
+
v.root.freeze
|
239
|
+
v.format.freeze
|
240
|
+
v.template.freeze
|
241
|
+
v.layout(Rendering::LayoutFinder.new(v).find)
|
242
|
+
v.layout.freeze
|
243
|
+
end
|
244
|
+
end
|
245
|
+
end
|
246
|
+
end
|
247
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module Lotus
|
2
|
+
module View
|
3
|
+
# Inheriting mechanisms
|
4
|
+
#
|
5
|
+
# @since 0.1.0
|
6
|
+
module Inheritable
|
7
|
+
# Register a view subclass
|
8
|
+
#
|
9
|
+
# @api private
|
10
|
+
# @since 0.1.0
|
11
|
+
#
|
12
|
+
# @example
|
13
|
+
# require 'lotus/view'
|
14
|
+
#
|
15
|
+
# class IndexView
|
16
|
+
# include Lotus::View
|
17
|
+
# end
|
18
|
+
#
|
19
|
+
# class JsonIndexView < IndexView
|
20
|
+
# end
|
21
|
+
def inherited(base)
|
22
|
+
subclasses.add base
|
23
|
+
end
|
24
|
+
|
25
|
+
# Set of registered subclasses
|
26
|
+
#
|
27
|
+
# @api private
|
28
|
+
# @since 0.1.0
|
29
|
+
def subclasses
|
30
|
+
@@subclasses ||= Set.new
|
31
|
+
end
|
32
|
+
|
33
|
+
protected
|
34
|
+
# Loading mechanism hook.
|
35
|
+
#
|
36
|
+
# @api private
|
37
|
+
# @since 0.1.0
|
38
|
+
#
|
39
|
+
# @see Lotus::View.load!
|
40
|
+
def load!
|
41
|
+
subclasses.freeze
|
42
|
+
views.freeze
|
43
|
+
end
|
44
|
+
|
45
|
+
def views
|
46
|
+
@@views ||= [ self ] + subclasses.to_a
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
require 'lotus/utils/string'
|
2
|
+
|
3
|
+
module Lotus
|
4
|
+
module View
|
5
|
+
module Rendering
|
6
|
+
# Defines the logic to find a layout
|
7
|
+
#
|
8
|
+
# @api private
|
9
|
+
# @since 0.1.0
|
10
|
+
#
|
11
|
+
# @see Lotus::Layout
|
12
|
+
class LayoutFinder
|
13
|
+
# Layout class name suffix
|
14
|
+
#
|
15
|
+
# @api private
|
16
|
+
# @since 0.1.0
|
17
|
+
SUFFIX = 'Layout'.freeze
|
18
|
+
|
19
|
+
# Find a layout from the given name.
|
20
|
+
#
|
21
|
+
# @param layout [Symbol,String,NilClass] layout name or nil if you want
|
22
|
+
# to fallback to the framework defaults (see `Lotus::View.layout`).
|
23
|
+
#
|
24
|
+
# @return [Lotus::Layout] the layout for the given name or
|
25
|
+
# `Lotus::View.layout`
|
26
|
+
#
|
27
|
+
# @api private
|
28
|
+
# @since 0.1.0
|
29
|
+
#
|
30
|
+
# @example With given name
|
31
|
+
# require 'lotus/view'
|
32
|
+
#
|
33
|
+
# Lotus::View::Rendering::LayoutFinder.find(:article) # =>
|
34
|
+
# ArticleLayout
|
35
|
+
#
|
36
|
+
# @example With nil
|
37
|
+
# require 'lotus/view'
|
38
|
+
#
|
39
|
+
# Lotus::View.layout # => :application
|
40
|
+
# Lotus::View::Rendering::LayoutFinder.find(nil) # =>
|
41
|
+
# ApplicationLayout
|
42
|
+
def self.find(layout)
|
43
|
+
case layout
|
44
|
+
when Symbol, String
|
45
|
+
class_name = "#{ Utils::String.new(layout).classify }#{ SUFFIX }"
|
46
|
+
Object.const_get(class_name)
|
47
|
+
when nil
|
48
|
+
Lotus::View.layout
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# Initialize the finder
|
53
|
+
#
|
54
|
+
# @param view [Class, #layout]
|
55
|
+
#
|
56
|
+
# @api private
|
57
|
+
# @since 0.1.0
|
58
|
+
def initialize(view)
|
59
|
+
@view = view
|
60
|
+
end
|
61
|
+
|
62
|
+
# Find the layout for the view
|
63
|
+
#
|
64
|
+
# @return [Lotus::Layout] the layout associated to the view
|
65
|
+
#
|
66
|
+
# @see Lotus::View::Rendering::LayoutFinder.find
|
67
|
+
# @see Lotus::View::Rendering::LayoutFinder#initialize
|
68
|
+
#
|
69
|
+
# @api private
|
70
|
+
# @since 0.1.0
|
71
|
+
#
|
72
|
+
# @example With layout
|
73
|
+
# require 'lotus/view'
|
74
|
+
#
|
75
|
+
# module Articles
|
76
|
+
# class Show
|
77
|
+
# include Lotus::View
|
78
|
+
# layout :article
|
79
|
+
# end
|
80
|
+
# end
|
81
|
+
#
|
82
|
+
# Lotus::View::Rendering::LayoutFinder.new(Articles::Show) # =>
|
83
|
+
# ArticleLayout
|
84
|
+
#
|
85
|
+
# @example Without layout
|
86
|
+
# require 'lotus/view'
|
87
|
+
#
|
88
|
+
# module Dashboard
|
89
|
+
# class Index
|
90
|
+
# include Lotus::View
|
91
|
+
# end
|
92
|
+
# end
|
93
|
+
#
|
94
|
+
# Lotus::View.layout # => :application
|
95
|
+
#
|
96
|
+
# Lotus::View::Rendering::LayoutFinder.new(Dashboard::Index) # =>
|
97
|
+
# ApplicationLayout
|
98
|
+
def find
|
99
|
+
self.class.find(@view.layout)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'lotus/view/rendering/null_template'
|
2
|
+
require 'lotus/view/rendering/templates_finder'
|
3
|
+
|
4
|
+
module Lotus
|
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 Lotus::Layout::ClassMethods#registry
|
14
|
+
class LayoutRegistry < ::Hash
|
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
|
+
super()
|
23
|
+
|
24
|
+
@view = view
|
25
|
+
prepare!
|
26
|
+
end
|
27
|
+
|
28
|
+
# Returns the layout for the given context.
|
29
|
+
#
|
30
|
+
# @param context [Hash] the rendering context
|
31
|
+
# @option context [Symbol] :format the requested format
|
32
|
+
#
|
33
|
+
# @return [Lotus::Layout, Lotus::View::Rendering::NullTemplate]
|
34
|
+
# the layout associated with the given context or a `NullTemplate` if
|
35
|
+
# it can't be found.
|
36
|
+
#
|
37
|
+
# @raise [Lotus::View::MissingFormatError] if the given context doesn't
|
38
|
+
# have the :format key
|
39
|
+
#
|
40
|
+
# @api private
|
41
|
+
# @since 0.1.0
|
42
|
+
def resolve(context)
|
43
|
+
fetch(format(context)) { NullTemplate.new }
|
44
|
+
end
|
45
|
+
|
46
|
+
protected
|
47
|
+
def prepare!
|
48
|
+
templates.each do |template|
|
49
|
+
merge! template.format => template
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def templates
|
54
|
+
TemplatesFinder.new(@view).find
|
55
|
+
end
|
56
|
+
|
57
|
+
def format(context)
|
58
|
+
context.fetch(:format) { raise MissingFormatError }
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|