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
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'lotus/view/template'
|
2
|
+
|
3
|
+
module Lotus
|
4
|
+
module View
|
5
|
+
module Rendering
|
6
|
+
# Find templates for a view
|
7
|
+
#
|
8
|
+
# @api private
|
9
|
+
# @since 0.1.0
|
10
|
+
#
|
11
|
+
# @see View::Template
|
12
|
+
class TemplatesFinder
|
13
|
+
FORMAT = '*'.freeze
|
14
|
+
ENGINES = '*'.freeze
|
15
|
+
|
16
|
+
# Initialize a finder
|
17
|
+
#
|
18
|
+
# @param view [Class] the view
|
19
|
+
#
|
20
|
+
# @api private
|
21
|
+
# @since 0.1.0
|
22
|
+
def initialize(view)
|
23
|
+
@view = view
|
24
|
+
end
|
25
|
+
|
26
|
+
# Find all the associated templates to the view.
|
27
|
+
# It looks for templates under the root path of the view, that are
|
28
|
+
# matching the template name
|
29
|
+
#
|
30
|
+
# @return [Array<Lotus::View::Template>] the templates
|
31
|
+
#
|
32
|
+
# @api private
|
33
|
+
# @since 0.1.0
|
34
|
+
#
|
35
|
+
# @see Lotus::View::Dsl#root
|
36
|
+
# @see Lotus::View::Dsl#template
|
37
|
+
#
|
38
|
+
# @example
|
39
|
+
# require 'lotus/view'
|
40
|
+
#
|
41
|
+
# module Articles
|
42
|
+
# class Show
|
43
|
+
# include Lotus::View
|
44
|
+
# end
|
45
|
+
# end
|
46
|
+
#
|
47
|
+
# Articles::Show.root # => "/path/to/templates"
|
48
|
+
# Articles::Show.template # => "articles/show"
|
49
|
+
#
|
50
|
+
# # This view has a template:
|
51
|
+
# #
|
52
|
+
# # "/path/to/templates/articles/show.html.erb"
|
53
|
+
#
|
54
|
+
# Lotus::View::Rendering::TemplatesFinder.new(Articles::Show).find
|
55
|
+
# # => [#<Lotus::View::Template:0x007f8a0a86a970 ... @file="/path/to/templates/articles/show.html.erb">]
|
56
|
+
def find
|
57
|
+
Dir.glob( "#{ [root, template_name].join(separator) }.#{ format }.#{ engines }" ).map do |template|
|
58
|
+
View::Template.new template
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
protected
|
63
|
+
def template_name
|
64
|
+
@view.template
|
65
|
+
end
|
66
|
+
|
67
|
+
def root
|
68
|
+
@view.root
|
69
|
+
end
|
70
|
+
|
71
|
+
def separator
|
72
|
+
::File::SEPARATOR
|
73
|
+
end
|
74
|
+
|
75
|
+
def format
|
76
|
+
FORMAT
|
77
|
+
end
|
78
|
+
|
79
|
+
def engines
|
80
|
+
ENGINES
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Lotus
|
2
|
+
module View
|
3
|
+
module Rendering
|
4
|
+
# Find a view
|
5
|
+
#
|
6
|
+
# @api private
|
7
|
+
# @since 0.1.0
|
8
|
+
#
|
9
|
+
# @see Lotus::View::Rendering::Registry
|
10
|
+
class ViewFinder
|
11
|
+
# Initialize a finder
|
12
|
+
#
|
13
|
+
# @param view [Class] the superclass view
|
14
|
+
#
|
15
|
+
# @api private
|
16
|
+
# @since 0.1.0
|
17
|
+
def initialize(view)
|
18
|
+
@view = view
|
19
|
+
end
|
20
|
+
|
21
|
+
# Find a view for the given template.
|
22
|
+
# It looks up for the current view and its subclasses.
|
23
|
+
#
|
24
|
+
# @param template [Lotus::View::Template] a template to be associated
|
25
|
+
# to a view
|
26
|
+
#
|
27
|
+
# @return [Class] a view associated with the given template
|
28
|
+
#
|
29
|
+
# @api private
|
30
|
+
# @since 0.1.0
|
31
|
+
def find(template)
|
32
|
+
@view.subclasses.find {|v| v.format == template.format } || @view
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,265 @@
|
|
1
|
+
require 'lotus/view/rendering/registry'
|
2
|
+
require 'lotus/view/rendering/scope'
|
3
|
+
|
4
|
+
module Lotus
|
5
|
+
module View
|
6
|
+
# Rendering methods
|
7
|
+
#
|
8
|
+
# @since 0.1.0
|
9
|
+
#
|
10
|
+
# @see Lotus::View::Rendering::InstanceMethods
|
11
|
+
module Rendering
|
12
|
+
def self.extended(base)
|
13
|
+
base.class_eval do
|
14
|
+
include InstanceMethods
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
module InstanceMethods
|
19
|
+
# Initialize a view
|
20
|
+
#
|
21
|
+
# @param template [Lotus::View::Template] the template to render
|
22
|
+
# @param locals [Hash] a set of objects available during the rendering
|
23
|
+
# process.
|
24
|
+
#
|
25
|
+
# @since 0.1.0
|
26
|
+
#
|
27
|
+
# @see Lotus::View::Template
|
28
|
+
#
|
29
|
+
# @example
|
30
|
+
# require 'lotus/view'
|
31
|
+
#
|
32
|
+
# class IndexView
|
33
|
+
# include Lotus::View
|
34
|
+
# end
|
35
|
+
#
|
36
|
+
# template = Lotus::View::Template.new('index.html.erb')
|
37
|
+
# view = IndexView.new(template, {article: article})
|
38
|
+
def initialize(template, locals)
|
39
|
+
@template = template
|
40
|
+
@locals = locals
|
41
|
+
@scope = Scope.new(self, @locals)
|
42
|
+
end
|
43
|
+
|
44
|
+
# Render the template by bounding the local scope.
|
45
|
+
# If it uses a layout, it renders the template first and then the
|
46
|
+
# control passes to the layout.
|
47
|
+
#
|
48
|
+
# Override this method for custom rendering policies.
|
49
|
+
# For instance, when a serializer is used and there isn't the need of
|
50
|
+
# a template.
|
51
|
+
#
|
52
|
+
# @return [String] the output of the rendering process
|
53
|
+
#
|
54
|
+
# @raise [Lotus::View::MissingTemplateError] if the template is nil
|
55
|
+
#
|
56
|
+
# @since 0.1.0
|
57
|
+
#
|
58
|
+
# @see Lotus::View::Layout
|
59
|
+
#
|
60
|
+
# @example with template
|
61
|
+
# require 'lotus/view'
|
62
|
+
#
|
63
|
+
# class IndexView
|
64
|
+
# include Lotus::View
|
65
|
+
# end
|
66
|
+
#
|
67
|
+
# template = Lotus::View::Template.new('index.html.erb')
|
68
|
+
# view = IndexView.new(template, {article: article})
|
69
|
+
#
|
70
|
+
# view.render # => <h1>Introducing Lotus::view</h1> ...
|
71
|
+
#
|
72
|
+
# @example with template and layout
|
73
|
+
# require 'lotus/view'
|
74
|
+
#
|
75
|
+
# class ApplicationLayout
|
76
|
+
# include Lotus::View::Layout
|
77
|
+
# end
|
78
|
+
#
|
79
|
+
# class IndexView
|
80
|
+
# include Lotus::View
|
81
|
+
# layout :application
|
82
|
+
# end
|
83
|
+
#
|
84
|
+
# template = Lotus::View::Template.new('index.html.erb')
|
85
|
+
# view = IndexView.new(template, {article: article})
|
86
|
+
#
|
87
|
+
# view.render # => <html> ... <h1>Introducing Lotus::view</h1> ...
|
88
|
+
#
|
89
|
+
# @example with custom rendering
|
90
|
+
# require 'lotus/view'
|
91
|
+
#
|
92
|
+
# class IndexView
|
93
|
+
# include Lotus::View
|
94
|
+
#
|
95
|
+
# def render
|
96
|
+
# ArticleSerializer.new(article).render
|
97
|
+
# end
|
98
|
+
# end
|
99
|
+
#
|
100
|
+
# view = IndexView.new(nil, {article: article})
|
101
|
+
#
|
102
|
+
# view.render # => {title: ...}
|
103
|
+
def render
|
104
|
+
layout.render
|
105
|
+
end
|
106
|
+
|
107
|
+
protected
|
108
|
+
# The output of the template rendering process.
|
109
|
+
#
|
110
|
+
# @return [String] the rendering output
|
111
|
+
#
|
112
|
+
# @raise [Lotus::View::MissingTemplateError] if the template is nil
|
113
|
+
#
|
114
|
+
# @api private
|
115
|
+
# @since 0.1.0
|
116
|
+
def rendered
|
117
|
+
template.render @scope
|
118
|
+
end
|
119
|
+
|
120
|
+
# The layout.
|
121
|
+
#
|
122
|
+
# @return [Class, Lotus::View::Rendering::NullLayout]
|
123
|
+
#
|
124
|
+
# @see Lotus::View::Layout
|
125
|
+
# @see Lotus::View.layout
|
126
|
+
# @see Lotus::View::Dsl#layout
|
127
|
+
#
|
128
|
+
# @api private
|
129
|
+
# @since 0.1.0
|
130
|
+
def layout
|
131
|
+
@layout ||= self.class.layout.new(@scope, rendered)
|
132
|
+
end
|
133
|
+
|
134
|
+
# The template.
|
135
|
+
#
|
136
|
+
# @return [Lotus::View::Template] the template
|
137
|
+
#
|
138
|
+
# @raise [Lotus::View::MissingTemplateError] if the template is nil
|
139
|
+
#
|
140
|
+
# @api private
|
141
|
+
# @since 0.1.0
|
142
|
+
def template
|
143
|
+
@template or raise MissingTemplateError.new(self.class.template, @scope.format)
|
144
|
+
end
|
145
|
+
|
146
|
+
# A set of objects available during the rendering process.
|
147
|
+
#
|
148
|
+
# @return [Hash]
|
149
|
+
#
|
150
|
+
# @see Lotus::View#initialize
|
151
|
+
#
|
152
|
+
# @api private
|
153
|
+
# @since 0.1.0
|
154
|
+
def locals
|
155
|
+
@locals
|
156
|
+
end
|
157
|
+
|
158
|
+
# Delegates missing methods to the scope.
|
159
|
+
#
|
160
|
+
# @see Lotus::View::Rendering::Scope
|
161
|
+
#
|
162
|
+
# @api private
|
163
|
+
# @since 0.1.0
|
164
|
+
#
|
165
|
+
# @example
|
166
|
+
# require 'lotus/view'
|
167
|
+
#
|
168
|
+
# class IndexView
|
169
|
+
# include Lotus::View
|
170
|
+
# end
|
171
|
+
#
|
172
|
+
# template = Lotus::View::Template.new('index.html.erb')
|
173
|
+
# view = IndexView.new(template, {article: article})
|
174
|
+
#
|
175
|
+
# view.article # => #<Article:0x007fb0bbd3b6e8>
|
176
|
+
def method_missing(m)
|
177
|
+
@scope.__send__ m
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
# Render the given context and locals with the appropriate template.
|
182
|
+
# If there are registered subclasses, it choose the right class, according
|
183
|
+
# to the requested format.
|
184
|
+
#
|
185
|
+
# @param context [Hash] the context for the rendering process
|
186
|
+
# @option context [Symbol] :format the requested format
|
187
|
+
#
|
188
|
+
# @return [String] the output of the rendering process
|
189
|
+
#
|
190
|
+
# @raise [Lotus::View::MissingTemplateError] if it can't find a template
|
191
|
+
# for the given context
|
192
|
+
#
|
193
|
+
# @raise [Lotus::View::MissingFormatError] if the given context doesn't
|
194
|
+
# have the :format key
|
195
|
+
#
|
196
|
+
# @since 0.1.0
|
197
|
+
#
|
198
|
+
# @see Lotus::View#initialize
|
199
|
+
# @see Lotus::View#render
|
200
|
+
#
|
201
|
+
# @example
|
202
|
+
# require 'lotus/view'
|
203
|
+
#
|
204
|
+
# article = OpenStruct.new(title: 'Hello')
|
205
|
+
#
|
206
|
+
# module Articles
|
207
|
+
# class Show
|
208
|
+
# include Lotus::View
|
209
|
+
#
|
210
|
+
# def title
|
211
|
+
# @title ||= article.title.upcase
|
212
|
+
# end
|
213
|
+
# end
|
214
|
+
#
|
215
|
+
# class JsonShow < Show
|
216
|
+
# format :json
|
217
|
+
#
|
218
|
+
# def title
|
219
|
+
# super.downcase
|
220
|
+
# end
|
221
|
+
# end
|
222
|
+
# end
|
223
|
+
#
|
224
|
+
# Lotus::View.root = '/path/to/templates'
|
225
|
+
# Lotus::View.load!
|
226
|
+
#
|
227
|
+
# Articles::Show.render(format: :html, article: article)
|
228
|
+
# # => renders `articles/show.html.erb`
|
229
|
+
#
|
230
|
+
# Articles::Show.render(format: :json, article: article)
|
231
|
+
# # => renders `articles/show.json.erb`
|
232
|
+
#
|
233
|
+
# Articles::Show.render(format: :xml, article: article)
|
234
|
+
# # => raises Lotus::View::MissingTemplateError
|
235
|
+
def render(context)
|
236
|
+
registry.resolve(context).render
|
237
|
+
end
|
238
|
+
|
239
|
+
protected
|
240
|
+
|
241
|
+
# Loading mechanism hook.
|
242
|
+
#
|
243
|
+
# @api private
|
244
|
+
# @since 0.1.0
|
245
|
+
#
|
246
|
+
# @see Lotus::View.load!
|
247
|
+
def load!
|
248
|
+
super
|
249
|
+
registry.freeze
|
250
|
+
end
|
251
|
+
|
252
|
+
private
|
253
|
+
|
254
|
+
# The registry that holds all the registered subclasses.
|
255
|
+
#
|
256
|
+
# @api private
|
257
|
+
# @since 0.1.0
|
258
|
+
#
|
259
|
+
# @see Lotus::View::Rendering::Registry
|
260
|
+
def registry
|
261
|
+
@@registry ||= Registry.new(self)
|
262
|
+
end
|
263
|
+
end
|
264
|
+
end
|
265
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'tilt'
|
2
|
+
|
3
|
+
module Lotus
|
4
|
+
module View
|
5
|
+
# A logic-less template.
|
6
|
+
#
|
7
|
+
# @since 0.1.0
|
8
|
+
class Template
|
9
|
+
def initialize(template)
|
10
|
+
@_template = Tilt.new(template)
|
11
|
+
end
|
12
|
+
|
13
|
+
# Returns the format that the template handles.
|
14
|
+
#
|
15
|
+
# @return [String] the format name
|
16
|
+
#
|
17
|
+
# @since 0.1.0
|
18
|
+
#
|
19
|
+
# @example
|
20
|
+
# require 'lotus/view'
|
21
|
+
#
|
22
|
+
# template = Lotus::View::Template.new('index.html.erb')
|
23
|
+
# template.format # => 'html'
|
24
|
+
def format
|
25
|
+
@_template.basename.match(/(\.[^.]+)/).to_s.
|
26
|
+
gsub('.', ''). # TODO shame on me, this should be part of the regex above
|
27
|
+
to_sym
|
28
|
+
end
|
29
|
+
|
30
|
+
# Render the template within the context of the given scope.
|
31
|
+
#
|
32
|
+
# @param scope [Lotus::View::Scope] the rendering scope
|
33
|
+
#
|
34
|
+
# @return [String] the output of the rendering process
|
35
|
+
#
|
36
|
+
# @api private
|
37
|
+
# @since 0.1.0
|
38
|
+
#
|
39
|
+
# @see Lotus::View::Scope
|
40
|
+
def render(scope, &blk)
|
41
|
+
@_template.render(scope, {}, &blk)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/lib/lotus/view/version.rb
CHANGED
data/lib/lotus/view.rb
CHANGED
@@ -1,7 +1,185 @@
|
|
1
|
-
require
|
1
|
+
require 'set'
|
2
|
+
require 'pathname'
|
3
|
+
require 'lotus/view/version'
|
4
|
+
require 'lotus/view/inheritable'
|
5
|
+
require 'lotus/view/rendering'
|
6
|
+
require 'lotus/view/dsl'
|
7
|
+
require 'lotus/layout'
|
8
|
+
require 'lotus/presenter'
|
2
9
|
|
3
10
|
module Lotus
|
11
|
+
# View
|
12
|
+
#
|
13
|
+
# @since 0.1.0
|
4
14
|
module View
|
5
|
-
#
|
15
|
+
# Missing template error
|
16
|
+
#
|
17
|
+
# This is raised at the runtime when Lotus::View cannot find a template for
|
18
|
+
# the requested format.
|
19
|
+
#
|
20
|
+
# We can't raise this error during the loading phase, because at that time
|
21
|
+
# we don't know if a view implements its own rendering policy.
|
22
|
+
# A view is allowed to override `#render`, and this scenario can make the
|
23
|
+
# presence of a template useless. One typical example is the usage of a
|
24
|
+
# serializer that returns the output string, without rendering a template.
|
25
|
+
#
|
26
|
+
# @since 0.1.0
|
27
|
+
class MissingTemplateError < ::StandardError
|
28
|
+
def initialize(template, format)
|
29
|
+
super("Can't find template '#{ template }' for '#{ format }' format.")
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# Missing format error
|
34
|
+
#
|
35
|
+
# This is raised at the runtime when rendering context lacks of the :format
|
36
|
+
# key.
|
37
|
+
#
|
38
|
+
# @since 0.1.0
|
39
|
+
#
|
40
|
+
# @see Lotus::View::Rendering#render
|
41
|
+
class MissingFormatError < ::StandardError
|
42
|
+
end
|
43
|
+
|
44
|
+
# Register a view
|
45
|
+
#
|
46
|
+
# @api private
|
47
|
+
# @since 0.1.0
|
48
|
+
#
|
49
|
+
# @example
|
50
|
+
# require 'lotus/view'
|
51
|
+
#
|
52
|
+
# class IndexView
|
53
|
+
# include Lotus::View
|
54
|
+
# end
|
55
|
+
def self.included(base)
|
56
|
+
base.class_eval do
|
57
|
+
extend Inheritable.dup
|
58
|
+
extend Dsl.dup
|
59
|
+
extend Rendering.dup
|
60
|
+
end
|
61
|
+
|
62
|
+
views.add(base)
|
63
|
+
end
|
64
|
+
|
65
|
+
# Set the directory root where templates are located
|
66
|
+
#
|
67
|
+
# @param root [String] the root path
|
68
|
+
#
|
69
|
+
# @see Lotus::View.root
|
70
|
+
#
|
71
|
+
# @since 0.1.0
|
72
|
+
#
|
73
|
+
# @example
|
74
|
+
# require 'lotus/view'
|
75
|
+
#
|
76
|
+
# Lotus::View.root = '/path/to/templates'
|
77
|
+
def self.root=(root)
|
78
|
+
@root = Pathname.new(root) rescue nil
|
79
|
+
end
|
80
|
+
|
81
|
+
# Returns the directory root where templates are located.
|
82
|
+
# If not already set, it returns the current directory.
|
83
|
+
#
|
84
|
+
# @return [Pathname] the root path for templates
|
85
|
+
#
|
86
|
+
# @see Lotus::View.root=
|
87
|
+
#
|
88
|
+
# @since 0.1.0
|
89
|
+
#
|
90
|
+
# @example with already set value
|
91
|
+
# require 'lotus/view'
|
92
|
+
#
|
93
|
+
# Lotus::View.root = '/path/to/templates'
|
94
|
+
# Lotus::View.root # => #<Pathname:/path/to/templates>
|
95
|
+
#
|
96
|
+
# @example with missing set value
|
97
|
+
# require 'lotus/view'
|
98
|
+
#
|
99
|
+
# Lotus::View.root # => #<Pathname:.>
|
100
|
+
def self.root
|
101
|
+
@root ||= begin
|
102
|
+
self.root = '.'
|
103
|
+
@root
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
# Sets the default layout for all the registered views.
|
108
|
+
#
|
109
|
+
# @param layout [Symbol] the layout name
|
110
|
+
#
|
111
|
+
# @since 0.1.0
|
112
|
+
#
|
113
|
+
# @see Lotus::View::Dsl#layout
|
114
|
+
# @see Lotus::View.load!
|
115
|
+
#
|
116
|
+
# @example
|
117
|
+
# require 'lotus/view'
|
118
|
+
#
|
119
|
+
# Lotus::View.layout = :application
|
120
|
+
#
|
121
|
+
# class IndexView
|
122
|
+
# include Lotus::View
|
123
|
+
# end
|
124
|
+
#
|
125
|
+
# Lotus::View.load!
|
126
|
+
# IndexView.layout # => ApplicationLayout
|
127
|
+
def self.layout=(layout)
|
128
|
+
@layout = Rendering::LayoutFinder.find(layout)
|
129
|
+
end
|
130
|
+
|
131
|
+
# Returns the default layout to assign to the registered views.
|
132
|
+
# If not already set, it returns a <tt>Rendering::NullLayout</tt>.
|
133
|
+
#
|
134
|
+
# @return [Class,Rendering::NullLayout] depends if already set or not.
|
135
|
+
#
|
136
|
+
# @since 0.1.0
|
137
|
+
#
|
138
|
+
# @see Lotus::View.layout=
|
139
|
+
def self.layout
|
140
|
+
@layout ||= Rendering::NullLayout
|
141
|
+
end
|
142
|
+
|
143
|
+
# A set of registered views.
|
144
|
+
#
|
145
|
+
# @return [Set] all the registered views.
|
146
|
+
#
|
147
|
+
# @api private
|
148
|
+
# @since 0.1.0
|
149
|
+
def self.views
|
150
|
+
@views ||= Set.new
|
151
|
+
end
|
152
|
+
|
153
|
+
# A set of registered layouts.
|
154
|
+
#
|
155
|
+
# @return [Set] all the registered layout.
|
156
|
+
#
|
157
|
+
# @api private
|
158
|
+
# @since 0.1.0
|
159
|
+
def self.layouts
|
160
|
+
@layouts ||= Set.new
|
161
|
+
end
|
162
|
+
|
163
|
+
#FIXME extract a Loader class
|
164
|
+
def self.load!
|
165
|
+
root.freeze
|
166
|
+
layout.freeze
|
167
|
+
views.freeze
|
168
|
+
|
169
|
+
views.each do |view|
|
170
|
+
view.send(:load!)
|
171
|
+
end
|
172
|
+
|
173
|
+
layouts.each do |layout|
|
174
|
+
layout.send(:load!)
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
def self.unload!
|
179
|
+
instance_variable_set(:@root, nil)
|
180
|
+
instance_variable_set(:@layout, nil)
|
181
|
+
instance_variable_set(:@views, Set.new)
|
182
|
+
instance_variable_set(:@layouts, Set.new)
|
183
|
+
end
|
6
184
|
end
|
7
185
|
end
|
data/lib/lotus-view.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'lotus/view'
|
data/lotus-view.gemspec
CHANGED
@@ -4,20 +4,24 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
4
|
require 'lotus/view/version'
|
5
5
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name =
|
7
|
+
spec.name = 'lotus-view'
|
8
8
|
spec.version = Lotus::View::VERSION
|
9
|
-
spec.authors = [
|
10
|
-
spec.email = [
|
11
|
-
spec.summary = %q{View layer for Lotus}
|
9
|
+
spec.authors = ['Luca Guidi']
|
10
|
+
spec.email = ['me@lucaguidi.com']
|
12
11
|
spec.description = %q{View layer for Lotus}
|
13
|
-
spec.
|
14
|
-
spec.
|
12
|
+
spec.summary = %q{View layer for Lotus, with a separation between views and templates}
|
13
|
+
spec.homepage = 'http://lotusrb.org'
|
14
|
+
spec.license = 'MIT'
|
15
15
|
|
16
16
|
spec.files = `git ls-files`.split($/)
|
17
|
-
spec.executables =
|
18
|
-
spec.test_files = spec.files.grep(%r{^(test
|
19
|
-
spec.require_paths = [
|
17
|
+
spec.executables = []
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test)/})
|
19
|
+
spec.require_paths = ['lib']
|
20
20
|
|
21
|
-
spec.
|
22
|
-
spec.
|
21
|
+
spec.add_runtime_dependency 'tilt', '~> 2.0', '>= 2.0.1'
|
22
|
+
spec.add_runtime_dependency 'lotus-utils', '~> 0.1'
|
23
|
+
|
24
|
+
spec.add_development_dependency 'bundler', '~> 1.5'
|
25
|
+
spec.add_development_dependency 'minitest', '~> 5'
|
26
|
+
spec.add_development_dependency 'rake', '~> 10'
|
23
27
|
end
|
File without changes
|
File without changes
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= render template: 'articles/new', locals: { errors: {} } %>
|