lotus-view 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +55 -105
- data/README.md +20 -10
- data/lib/lotus/layout.rb +2 -1
- data/lib/lotus/presenter.rb +12 -0
- data/lib/lotus/view.rb +9 -11
- data/lib/lotus/view/configuration.rb +114 -6
- data/lib/lotus/view/dsl.rb +13 -13
- data/lib/lotus/view/rendering/layout_finder.rb +1 -1
- data/lib/lotus/view/rendering/layout_registry.rb +11 -0
- data/lib/lotus/view/rendering/layout_scope.rb +50 -5
- data/lib/lotus/view/rendering/null_template.rb +6 -2
- data/lib/lotus/view/rendering/scope.rb +27 -2
- data/lib/lotus/view/template.rb +3 -5
- data/lib/lotus/view/version.rb +1 -1
- data/lotus-view.gemspec +2 -1
- metadata +11 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e8fa1effeef34385f8e2500ab74842e8d196f9bf
|
4
|
+
data.tar.gz: 203e83425ed18d487d19cc825443fed66c53c86e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6b1317306b81d7579d3a3894ba2f22584f69f28039a0161a706c3d3cb7f89cc5a2b591c09e7c57b684d53870a9b96010a8db882717cd8a6ce0d9574f59be4b81
|
7
|
+
data.tar.gz: bee5b8b82b89c9e561bc89bffb53ba3a01028393934fb8bfa350e7fb13c240a305061a3c9b8196abadb710c13d3654b932a4986a609b06280c49c7abc24c6af0
|
data/CHANGELOG.md
CHANGED
@@ -1,105 +1,55 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
426eaf7 2014-03-21 **Luca Guidi** Allow custom rendering policies. Views can override #render and decide how to return the output.
|
58
|
-
|
59
|
-
b2759f8 2014-03-18 **Luca Guidi** Lotus::View::Layout => Lotus::Layout
|
60
|
-
|
61
|
-
c0c04a8 2014-03-17 **Luca Guidi** Remove private method for Presenter: #object
|
62
|
-
|
63
|
-
74ca485 2014-03-13 **Luca Guidi** Introduced Lotus::Presenter
|
64
|
-
|
65
|
-
0ee9c10 2014-03-13 **Luca Guidi** Render partial from a layout
|
66
|
-
|
67
|
-
dc4a74f 2014-03-12 **Luca Guidi** Support for Tilt 2.0
|
68
|
-
|
69
|
-
728fe70 2014-02-20 **Luca Guidi** Added Lotus::View#locals
|
70
|
-
|
71
|
-
11c7e5a 2013-08-08 **Luca Guidi** Don't use global class vars.
|
72
|
-
|
73
|
-
570a20c 2013-08-07 **Luca Guidi** Scope templates discovery to registered engines
|
74
|
-
|
75
|
-
4b45b11 2013-08-06 **Luca Guidi** Added support for layouts.
|
76
|
-
|
77
|
-
96a2c66 2013-08-02 **Luca Guidi** Allow templates to be rendered from templates.
|
78
|
-
|
79
|
-
ba5acdc 2013-08-01 **Luca Guidi** Allow partials to be rendered from templates.
|
80
|
-
|
81
|
-
04474d4 2013-08-01 **Luca Guidi** Render template in the Lotus::View::Rendering::Scope context
|
82
|
-
|
83
|
-
d108767 2013-08-01 **Luca Guidi** Freeze at subclasses level too
|
84
|
-
|
85
|
-
04a3093 2013-08-01 **Luca Guidi** Let views to specify relative template filename
|
86
|
-
|
87
|
-
e7c832d 2013-08-01 **Luca Guidi** Lotus::View::Rendering::Template => Lotus::View::Template
|
88
|
-
|
89
|
-
f603ea9 2013-08-01 **Luca Guidi** Rework
|
90
|
-
|
91
|
-
5df49f1 2013-07-23 **Luca Guidi** Removed unnecessary indirection
|
92
|
-
|
93
|
-
683741c 2013-07-22 **Luca Guidi** Views can now transparently inheriths variables from locals, in order to reuse them.
|
94
|
-
|
95
|
-
3a31f63 2013-07-19 **Luca Guidi** Removed templates as class variable for views: introduced a registry for runtime resolution
|
96
|
-
|
97
|
-
f27e19f 2013-07-18 **Luca Guidi** WIP rendering resolver
|
98
|
-
|
99
|
-
05e1d8c 2013-07-18 **Luca Guidi** Allow views inheritance.
|
100
|
-
|
101
|
-
8236523 2013-07-18 **Luca Guidi** Refactoring: Engine is not relevant, let Tilt to deal with it. View has multiple templates. Intoduced DSL for format. Introduced resolver for runtime rendering. Dependency injection. :tophat:
|
102
|
-
|
103
|
-
f7f3d25 2013-07-17 **Luca Guidi** Extracted Lotus::View::Template::Finder
|
104
|
-
|
105
|
-
11d3c47 2013-07-15 **Luca Guidi** Initial mess
|
1
|
+
# Lotus::View
|
2
|
+
View layer for Lotus
|
3
|
+
|
4
|
+
## v0.3.0 - 2014-12-23
|
5
|
+
### Added
|
6
|
+
- [Trung Lê] When duplicate the framework, also duplicate `Presenter`
|
7
|
+
- [Benny Klotz] Introduced `Scope#class`, `#inspect`, `LayoutScope#class` and `#inspect`
|
8
|
+
- [Alfonso Uceda Pompa & Trung Lê] Introduced `Configuration#prepare`
|
9
|
+
- [Luca Guidi] Implemented "respond to" logic for `Lotus::View::Scope` (`respond_to?` and `respond_to_missing?`)
|
10
|
+
- [Luca Guidi] Implemented "respond to" logic for `Lotus::Layout` (`respond_to?` and `respond_to_missing?`)
|
11
|
+
- [Jeremy Stephens] Allow view concrete methods that accept a block to be invoked from templates
|
12
|
+
- [Peter Suschlik] Implemented "respond to" logic for `Lotus::Presenter` (`respond_to?` and `respond_to_missing?`)
|
13
|
+
- [Luca Guidi] Official support for Ruby 2.2
|
14
|
+
|
15
|
+
### Changed
|
16
|
+
- [Alfonso Uceda Pompa] Raise an exception when a layout doesn't have an associated template
|
17
|
+
|
18
|
+
### Fixed
|
19
|
+
- [Luca Guidi] Ensure that concrete methods in layouts are available in templates
|
20
|
+
- [Luca Guidi] Ensure to associate the right layout to a view in case fo duplicated framework
|
21
|
+
- [Luca Guidi] Safe override of Ruby's top level methods in Scope. (Eg. use `select` from a view, not from `::Kernel`)
|
22
|
+
|
23
|
+
## v0.2.0 - 2014-06-23
|
24
|
+
### Added
|
25
|
+
- [Luca Guidi] Introduced `Configuration#duplicate`
|
26
|
+
- [Luca Guidi] Introduced `Configuration#layout` to define the layout that all the views will use
|
27
|
+
- [Luca Guidi] Introduced `Configuration#load_paths` to define several sources where to lookup for templates
|
28
|
+
- [Luca Guidi] Introduced `Configuration#root` to define the root path where to find templates
|
29
|
+
- [Luca Guidi] Introduced `Lotus::View::Configuration`
|
30
|
+
- [Grant Ammons] Allow view concrete methods with arity > 0 to be invoked from templates
|
31
|
+
- [Luca Guidi] Official support for Ruby 2.1
|
32
|
+
|
33
|
+
### Changed
|
34
|
+
- [Luca Guidi] `Rendering::TemplatesFinder` now look recursively for templates, starting from the root.
|
35
|
+
- [Luca Guidi] Removed `View.layout=`
|
36
|
+
- [Luca Guidi] Removed `View.root=`
|
37
|
+
|
38
|
+
### Fixed
|
39
|
+
- [Luca Guidi] Ensure outermost locals to not shadow innermost inside templates/partials
|
40
|
+
|
41
|
+
## v0.1.0 - 2014-03-23
|
42
|
+
### Added
|
43
|
+
- [Luca Guidi] Allow custom rendering policy via `Action#render` override. This bypasses the template lookup and rendering.
|
44
|
+
- [Luca Guidi] Introduced `Lotus::Presenter`
|
45
|
+
- [Luca Guidi] Introduced templates rendering from templates and layouts
|
46
|
+
- [Luca Guidi] Introduced partials rendering from templates and layouts
|
47
|
+
- [Luca Guidi] Introduced layouts support
|
48
|
+
- [Luca Guidi] Introduced `Lotus::View.load!` as entry point to load views and templates
|
49
|
+
- [Luca Guidi] Allow to setup template name via `View.template`
|
50
|
+
- [Luca Guidi] Rendering context also considers locals passed to the constructor
|
51
|
+
- [Luca Guidi] Introduced `View.format` as DSL to declare which format to handle
|
52
|
+
- [Luca Guidi] Introduced view subclasses as way to handle different formats (mime types)
|
53
|
+
- [Luca Guidi] Introduced multiple templates per each View
|
54
|
+
- [Luca Guidi] Implemented basic rendering with templates
|
55
|
+
- [Luca Guidi] Official support for Ruby 2.0
|
data/README.md
CHANGED
@@ -6,13 +6,13 @@ It's based on a **separation between views and templates**.
|
|
6
6
|
|
7
7
|
A _view_ is an object that encapsulates the presentation logic of a page.
|
8
8
|
A _template_ is a file that defines the semantic and visual elements of a page.
|
9
|
-
In order to show a result to
|
9
|
+
In order to show a result to a user, a template must be _rendered_ by a view.
|
10
10
|
|
11
11
|
Keeping things separated helps to declutter templates and models from presentation logic.
|
12
12
|
Also, since views are objects, they are easily testable.
|
13
13
|
If you ever used [Mustache](http://mustache.github.io/), you are already aware of the advantages.
|
14
14
|
|
15
|
-
Like all the other Lotus
|
15
|
+
Like all the other Lotus components, it can be used as a standalone framework or within a full Lotus application.
|
16
16
|
|
17
17
|
## Status
|
18
18
|
|
@@ -40,7 +40,9 @@ __Lotus::View__ supports Ruby (MRI) 2+
|
|
40
40
|
|
41
41
|
Add this line to your application's Gemfile:
|
42
42
|
|
43
|
-
|
43
|
+
```ruby
|
44
|
+
gem 'lotus-view'
|
45
|
+
```
|
44
46
|
|
45
47
|
And then execute:
|
46
48
|
|
@@ -56,7 +58,7 @@ Or install it yourself as:
|
|
56
58
|
|
57
59
|
* Templates are searched under `Lotus::View.configuration.root`, set this value according to your app structure (eg. `"app/templates"`).
|
58
60
|
* A view will look for a template with a file name that is composed by its full class name (eg. `"articles/index"`).
|
59
|
-
* A template must have two concatenated extensions: one for the format one for the engine (eg. `".html.erb"`).
|
61
|
+
* A template must have two concatenated extensions: one for the format and one for the engine (eg. `".html.erb"`).
|
60
62
|
* The framework must be loaded before rendering the first time: `Lotus::View.load!`.
|
61
63
|
|
62
64
|
### Views
|
@@ -145,7 +147,7 @@ module Articles
|
|
145
147
|
include Lotus::View
|
146
148
|
|
147
149
|
def authors
|
148
|
-
article.map(&:
|
150
|
+
article.authors.map(&:full_name).join ', '
|
149
151
|
end
|
150
152
|
end
|
151
153
|
end
|
@@ -406,7 +408,7 @@ module Articles
|
|
406
408
|
end
|
407
409
|
end
|
408
410
|
|
409
|
-
Articles::
|
411
|
+
Articles::Create.template # => "articles/new"
|
410
412
|
```
|
411
413
|
|
412
414
|
### Partials
|
@@ -515,7 +517,7 @@ puts presenter.inspect_object # => #<Map:0x007fdeada0b2f0 @locations=["Rome", "B
|
|
515
517
|
|
516
518
|
### Configuration
|
517
519
|
|
518
|
-
|
520
|
+
__Lotus::View__ can be configured with a DSL that determines its behavior.
|
519
521
|
It supports a few options:
|
520
522
|
|
521
523
|
```ruby
|
@@ -533,9 +535,17 @@ Lotus::View.configure do
|
|
533
535
|
namespace 'MyApp::Views'
|
534
536
|
|
535
537
|
# Set the global layout
|
536
|
-
# Argument: Symbol,
|
538
|
+
# Argument: Symbol, defaults to nil
|
537
539
|
#
|
538
540
|
layout :application
|
541
|
+
|
542
|
+
# Set modules that you want to include in all views
|
543
|
+
# Argument: Block
|
544
|
+
#
|
545
|
+
prepare do
|
546
|
+
include MyCustomModule
|
547
|
+
before { do_something }
|
548
|
+
end
|
539
549
|
end
|
540
550
|
```
|
541
551
|
|
@@ -562,7 +572,7 @@ Show.root # => #<Pathname:/another/root>
|
|
562
572
|
|
563
573
|
### Reusability
|
564
574
|
|
565
|
-
|
575
|
+
__Lotus::View__ can be used as a singleton framework as seen in this README.
|
566
576
|
The application code includes `Lotus::View` or `Lotus::Layout` directly
|
567
577
|
and the configuration is unique per Ruby process.
|
568
578
|
|
@@ -597,7 +607,7 @@ configuration.
|
|
597
607
|
|
598
608
|
### Thread safety
|
599
609
|
|
600
|
-
|
610
|
+
__Lotus::View__ is thread safe during the runtime, but it isn't during the loading process.
|
601
611
|
Please load the framework as the last thing before your application starts.
|
602
612
|
Also, be sure that your app provides a thread safe context while it's loaded.
|
603
613
|
|
data/lib/lotus/layout.rb
CHANGED
data/lib/lotus/presenter.rb
CHANGED
@@ -59,6 +59,10 @@ module Lotus
|
|
59
59
|
end
|
60
60
|
|
61
61
|
protected
|
62
|
+
# Override Ruby's method_missing
|
63
|
+
#
|
64
|
+
# @api private
|
65
|
+
# @since 0.1.0
|
62
66
|
def method_missing(m, *args, &blk)
|
63
67
|
if @object.respond_to?(m)
|
64
68
|
@object.__send__ m, *args, &blk
|
@@ -66,5 +70,13 @@ module Lotus
|
|
66
70
|
super
|
67
71
|
end
|
68
72
|
end
|
73
|
+
|
74
|
+
# Override Ruby's respond_to_missing? in order to support proper delegation
|
75
|
+
#
|
76
|
+
# @api private
|
77
|
+
# @since 0.3.0
|
78
|
+
def respond_to_missing?(m, include_private = false)
|
79
|
+
@object.respond_to?(m, include_private)
|
80
|
+
end
|
69
81
|
end
|
70
82
|
end
|
data/lib/lotus/view.rb
CHANGED
@@ -148,8 +148,9 @@ module Lotus
|
|
148
148
|
# #
|
149
149
|
# # 1. Generate MyApp::View
|
150
150
|
# # 2. Generate MyApp::Layout
|
151
|
-
# # 3. Generate MyApp::
|
152
|
-
# # 4.
|
151
|
+
# # 3. Generate MyApp::Presenter
|
152
|
+
# # 4. Generate MyApp::Views
|
153
|
+
# # 5. Configure MyApp::Views as the default namespace for views
|
153
154
|
#
|
154
155
|
# module MyApp::Views::Dashboard
|
155
156
|
# class Index
|
@@ -227,7 +228,10 @@ module Lotus
|
|
227
228
|
def self.duplicate(mod, views = 'Views', &blk)
|
228
229
|
dupe.tap do |duplicated|
|
229
230
|
mod.module_eval %{ module #{ views }; end } if views
|
230
|
-
mod.module_eval %{
|
231
|
+
mod.module_eval %{
|
232
|
+
Layout = Lotus::Layout.dup
|
233
|
+
Presenter = Lotus::Presenter.dup
|
234
|
+
}
|
231
235
|
|
232
236
|
duplicated.configure do
|
233
237
|
namespace [mod, views].compact.join '::'
|
@@ -272,6 +276,8 @@ module Lotus
|
|
272
276
|
|
273
277
|
self.configuration = conf.duplicate
|
274
278
|
end
|
279
|
+
|
280
|
+
conf.copy!(base)
|
275
281
|
end
|
276
282
|
|
277
283
|
# Load the framework
|
@@ -281,13 +287,5 @@ module Lotus
|
|
281
287
|
def self.load!
|
282
288
|
configuration.load!
|
283
289
|
end
|
284
|
-
|
285
|
-
# Unload the framework
|
286
|
-
#
|
287
|
-
# @since 0.1.0
|
288
|
-
# @api private
|
289
|
-
def self.unload!
|
290
|
-
configuration.unload!
|
291
|
-
end
|
292
290
|
end
|
293
291
|
end
|
@@ -32,6 +32,7 @@ module Lotus
|
|
32
32
|
attr_reader :load_paths
|
33
33
|
attr_reader :views
|
34
34
|
attr_reader :layouts
|
35
|
+
attr_reader :modules
|
35
36
|
|
36
37
|
# Return the original configuration of the framework instance associated
|
37
38
|
# with the given class.
|
@@ -83,7 +84,7 @@ module Lotus
|
|
83
84
|
def self.for(base)
|
84
85
|
# TODO this implementation is similar to Lotus::Controller::Configuration consider to extract it into Lotus::Utils
|
85
86
|
namespace = Utils::String.new(base).namespace
|
86
|
-
framework = Utils::Class.
|
87
|
+
framework = Utils::Class.load_from_pattern!("(#{namespace}|Lotus)::View")
|
87
88
|
framework.configuration
|
88
89
|
end
|
89
90
|
|
@@ -229,10 +230,96 @@ module Lotus
|
|
229
230
|
#
|
230
231
|
# MyApp::View.configuration.layout # => MyApp::ApplicationLayout
|
231
232
|
def layout(value = nil)
|
232
|
-
if value
|
233
|
+
if value.nil?
|
234
|
+
Rendering::LayoutFinder.find(@layout, @namespace)
|
235
|
+
else
|
233
236
|
@layout = value
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
# Prepare the views.
|
241
|
+
#
|
242
|
+
# The given block will be yielded when `Lotus::View` will be included by
|
243
|
+
# a view.
|
244
|
+
#
|
245
|
+
# This method can be called multiple times.
|
246
|
+
#
|
247
|
+
# @param blk [Proc] the code block
|
248
|
+
#
|
249
|
+
# @return [void]
|
250
|
+
#
|
251
|
+
# @raise [ArgumentError] if called without passing a block
|
252
|
+
#
|
253
|
+
# @since 0.3.0
|
254
|
+
#
|
255
|
+
# @see Lotus::View.configure
|
256
|
+
# @see Lotus::View.duplicate
|
257
|
+
#
|
258
|
+
# @example Including shared utilities
|
259
|
+
# require 'lotus/view'
|
260
|
+
#
|
261
|
+
# module UrlHelpers
|
262
|
+
# def comments_path
|
263
|
+
# '/'
|
264
|
+
# end
|
265
|
+
# end
|
266
|
+
#
|
267
|
+
# Lotus::View.configure do
|
268
|
+
# prepare do
|
269
|
+
# include UrlHelpers
|
270
|
+
# end
|
271
|
+
# end
|
272
|
+
#
|
273
|
+
# Lotus::View.load!
|
274
|
+
#
|
275
|
+
# module Comments
|
276
|
+
# class New
|
277
|
+
# # The following include will cause UrlHelpers to be included too.
|
278
|
+
# # This makes `comments_path` available in the view context
|
279
|
+
# include Lotus::View
|
280
|
+
#
|
281
|
+
# def form
|
282
|
+
# %(<form action="#{ comments_path }" method="POST"></form>)
|
283
|
+
# end
|
284
|
+
# end
|
285
|
+
# end
|
286
|
+
#
|
287
|
+
# @example Preparing multiple times
|
288
|
+
# require 'lotus/view'
|
289
|
+
#
|
290
|
+
# Lotus::View.configure do
|
291
|
+
# prepare do
|
292
|
+
# include UrlHelpers
|
293
|
+
# end
|
294
|
+
#
|
295
|
+
# prepare do
|
296
|
+
# format :json
|
297
|
+
# end
|
298
|
+
# end
|
299
|
+
#
|
300
|
+
# Lotus::View.configure do
|
301
|
+
# prepare do
|
302
|
+
# include FormattingHelpers
|
303
|
+
# end
|
304
|
+
# end
|
305
|
+
#
|
306
|
+
# Lotus::View.load!
|
307
|
+
#
|
308
|
+
# module Articles
|
309
|
+
# class Index
|
310
|
+
# # The following include will cause the inclusion of:
|
311
|
+
# # * UrlHelpers
|
312
|
+
# # * FormattingHelpers
|
313
|
+
# #
|
314
|
+
# # It also sets the view to render only JSON
|
315
|
+
# include Lotus::View
|
316
|
+
# end
|
317
|
+
# end
|
318
|
+
def prepare(&blk)
|
319
|
+
if block_given?
|
320
|
+
@modules.push(blk)
|
234
321
|
else
|
235
|
-
|
322
|
+
raise ArgumentError.new('Please provide a block')
|
236
323
|
end
|
237
324
|
end
|
238
325
|
|
@@ -264,6 +351,7 @@ module Lotus
|
|
264
351
|
c.root = root
|
265
352
|
c.layout = @layout # lazy loading of the class
|
266
353
|
c.load_paths = load_paths.dup
|
354
|
+
c.modules = modules.dup
|
267
355
|
end
|
268
356
|
end
|
269
357
|
|
@@ -272,8 +360,9 @@ module Lotus
|
|
272
360
|
# @since 0.2.0
|
273
361
|
# @api private
|
274
362
|
def load!
|
275
|
-
views.each {|v| v.__send__(:load!) }
|
276
|
-
layouts.each {|l| l.__send__(:load!) }
|
363
|
+
views.each { |v| v.__send__(:load!) }
|
364
|
+
layouts.each { |l| l.__send__(:load!) }
|
365
|
+
freeze
|
277
366
|
end
|
278
367
|
|
279
368
|
# Reset all the values to the defaults
|
@@ -287,12 +376,31 @@ module Lotus
|
|
287
376
|
@layouts = Set.new
|
288
377
|
@load_paths = Utils::LoadPaths.new(root)
|
289
378
|
@layout = nil
|
379
|
+
@modules = []
|
380
|
+
end
|
381
|
+
|
382
|
+
# Copy the configuration for the given action
|
383
|
+
#
|
384
|
+
# @param base [Class] the target action
|
385
|
+
#
|
386
|
+
# @return void
|
387
|
+
#
|
388
|
+
# @since 0.3.0
|
389
|
+
# @api private
|
390
|
+
def copy!(base)
|
391
|
+
modules.each do |mod|
|
392
|
+
base.class_eval(&mod)
|
393
|
+
end
|
290
394
|
end
|
291
395
|
|
292
396
|
alias_method :unload!, :reset!
|
293
397
|
|
294
398
|
protected
|
295
|
-
attr_writer :namespace
|
399
|
+
attr_writer :namespace
|
400
|
+
attr_writer :root
|
401
|
+
attr_writer :load_paths
|
402
|
+
attr_writer :layout
|
403
|
+
attr_writer :modules
|
296
404
|
end
|
297
405
|
end
|
298
406
|
end
|
data/lib/lotus/view/dsl.rb
CHANGED
@@ -43,10 +43,10 @@ module Lotus
|
|
43
43
|
# Lotus::View.configuration.root # => 'app/templates'
|
44
44
|
# Articles::Show.root # => 'path/to/articles/templates'
|
45
45
|
def root(value = nil)
|
46
|
-
if value
|
47
|
-
configuration.root(value)
|
48
|
-
else
|
46
|
+
if value.nil?
|
49
47
|
configuration.root
|
48
|
+
else
|
49
|
+
configuration.root(value)
|
50
50
|
end
|
51
51
|
end
|
52
52
|
|
@@ -75,10 +75,10 @@ module Lotus
|
|
75
75
|
# Articles::Show.format # => nil
|
76
76
|
# Articles::JsonShow.format # => :json
|
77
77
|
def format(value = nil)
|
78
|
-
if value
|
79
|
-
@format = value
|
80
|
-
else
|
78
|
+
if value.nil?
|
81
79
|
@format
|
80
|
+
else
|
81
|
+
@format = value
|
82
82
|
end
|
83
83
|
end
|
84
84
|
|
@@ -204,10 +204,10 @@ module Lotus
|
|
204
204
|
# Bookshelf::Web::Views::Books::Index.template # => 'books/index'
|
205
205
|
# Bookshelf::Api::Views::Books::Index.template # => 'books/index'
|
206
206
|
def template(value = nil)
|
207
|
-
if value
|
208
|
-
@@template = value
|
209
|
-
else
|
207
|
+
if value.nil?
|
210
208
|
@@template ||= Rendering::TemplateName.new(name, configuration.namespace).to_s
|
209
|
+
else
|
210
|
+
@@template = value
|
211
211
|
end
|
212
212
|
end
|
213
213
|
|
@@ -295,10 +295,10 @@ module Lotus
|
|
295
295
|
# Lotus::View.load!
|
296
296
|
# Articles::Show.layout # => :articles
|
297
297
|
def layout(value = nil)
|
298
|
-
if value
|
299
|
-
@layout
|
298
|
+
if value.nil?
|
299
|
+
@_layout ||= Rendering::LayoutFinder.find(@layout || configuration.layout, configuration.namespace)
|
300
300
|
else
|
301
|
-
@layout
|
301
|
+
@layout = value
|
302
302
|
end
|
303
303
|
end
|
304
304
|
|
@@ -317,8 +317,8 @@ module Lotus
|
|
317
317
|
v.root.freeze
|
318
318
|
v.format.freeze
|
319
319
|
v.template.freeze
|
320
|
-
v.layout(Rendering::LayoutFinder.new(v).find)
|
321
320
|
v.layout#.freeze
|
321
|
+
v.configuration.freeze
|
322
322
|
end
|
323
323
|
end
|
324
324
|
end
|
@@ -66,7 +66,7 @@ module Lotus
|
|
66
66
|
when Symbol, String
|
67
67
|
# TODO Move this low level logic into a Lotus::Utils solution
|
68
68
|
class_name = "#{ Utils::String.new(layout).classify }#{ SUFFIX }"
|
69
|
-
namespace = Utils::Class.
|
69
|
+
namespace = Utils::Class.load_from_pattern!(namespace)
|
70
70
|
namespace.const_get(class_name)
|
71
71
|
when Class
|
72
72
|
layout
|
@@ -4,6 +4,16 @@ require 'lotus/view/rendering/templates_finder'
|
|
4
4
|
module Lotus
|
5
5
|
module View
|
6
6
|
module Rendering
|
7
|
+
# Missing template layout error
|
8
|
+
#
|
9
|
+
# This is raised at the runtime when Lotus::Layout cannot find it's template.
|
10
|
+
#
|
11
|
+
# @since 0.3.0
|
12
|
+
class MissingTemplateLayoutError < ::StandardError
|
13
|
+
def initialize(template)
|
14
|
+
super("Can't find layout template '#{ template }'")
|
15
|
+
end
|
16
|
+
end
|
7
17
|
# Holds the references of all the registered layouts.
|
8
18
|
# As now the registry is unique at the level of the framework.
|
9
19
|
#
|
@@ -48,6 +58,7 @@ module Lotus
|
|
48
58
|
templates.each do |template|
|
49
59
|
merge! template.format => template
|
50
60
|
end
|
61
|
+
self.any? or raise MissingTemplateLayoutError.new(@view)
|
51
62
|
end
|
52
63
|
|
53
64
|
def templates
|
@@ -4,7 +4,7 @@ module Lotus
|
|
4
4
|
# Scope for layout rendering
|
5
5
|
#
|
6
6
|
# @since 0.1.0
|
7
|
-
class LayoutScope
|
7
|
+
class LayoutScope < BasicObject
|
8
8
|
# Initialize the scope
|
9
9
|
#
|
10
10
|
# @param layout [Lotus::Layout] the layout to render
|
@@ -17,6 +17,27 @@ module Lotus
|
|
17
17
|
@layout, @scope = layout, scope
|
18
18
|
end
|
19
19
|
|
20
|
+
# Returns the classname as string
|
21
|
+
#
|
22
|
+
# @return classname
|
23
|
+
#
|
24
|
+
# @since 0.3.0
|
25
|
+
def class
|
26
|
+
(class << self; self end).superclass
|
27
|
+
end
|
28
|
+
|
29
|
+
# Returns an inspect String
|
30
|
+
#
|
31
|
+
# @return [String] inspect String (contains classname, objectid in hex, available ivars)
|
32
|
+
#
|
33
|
+
# @since 0.3.0
|
34
|
+
def inspect
|
35
|
+
base = "#<#{ self.class }:#{'%x' % (self.object_id << 1)}"
|
36
|
+
base << " @layout=\"#{@layout}\"" if @layout
|
37
|
+
base << " @scope=\"#{@scope}\"" if @scope
|
38
|
+
base << ">"
|
39
|
+
end
|
40
|
+
|
20
41
|
# Render a partial or a template within a layout template.
|
21
42
|
#
|
22
43
|
# @param options [Hash]
|
@@ -90,6 +111,30 @@ module Lotus
|
|
90
111
|
@locals || @scope.locals
|
91
112
|
end
|
92
113
|
|
114
|
+
# Implements "respond to" logic
|
115
|
+
#
|
116
|
+
# @return [TrueClass,FalseClass]
|
117
|
+
#
|
118
|
+
# @since 0.3.0
|
119
|
+
#
|
120
|
+
# @see http://ruby-doc.org/core/Object.html#method-i-respond_to-3F
|
121
|
+
def respond_to?(m, include_all = false)
|
122
|
+
respond_to_missing?(m, include_all)
|
123
|
+
end
|
124
|
+
|
125
|
+
# Implements "respond to" logic
|
126
|
+
#
|
127
|
+
# @return [TrueClass,FalseClass]
|
128
|
+
#
|
129
|
+
# @since 0.3.0
|
130
|
+
# @api private
|
131
|
+
#
|
132
|
+
# @see http://ruby-doc.org/core/Object.html#method-i-respond_to_missing-3F
|
133
|
+
def respond_to_missing?(m, include_all)
|
134
|
+
@layout.respond_to?(m, include_all) ||
|
135
|
+
@scope.respond_to?(m, include_all)
|
136
|
+
end
|
137
|
+
|
93
138
|
protected
|
94
139
|
# Forward all the missing methods to the view scope or to the layout.
|
95
140
|
#
|
@@ -108,11 +153,11 @@ module Lotus
|
|
108
153
|
#
|
109
154
|
# # `article` will be looked up in the view scope first.
|
110
155
|
# # If not found, it will be searched within the layout.
|
111
|
-
def method_missing(m)
|
156
|
+
def method_missing(m, *args, &blk)
|
112
157
|
begin
|
113
|
-
@scope.__send__
|
158
|
+
@scope.__send__(m, *args, &blk)
|
114
159
|
rescue
|
115
|
-
@layout.__send__
|
160
|
+
@layout.__send__(m, *args, &blk)
|
116
161
|
end
|
117
162
|
end
|
118
163
|
|
@@ -129,7 +174,7 @@ module Lotus
|
|
129
174
|
options.dup.tap do |opts|
|
130
175
|
opts.merge!(format: format)
|
131
176
|
opts[:locals] = locals
|
132
|
-
opts[:locals].merge!(options.fetch(:locals){ Hash
|
177
|
+
opts[:locals].merge!(options.fetch(:locals){ ::Hash.new })
|
133
178
|
end
|
134
179
|
end
|
135
180
|
end
|
@@ -63,6 +63,10 @@ module Lotus
|
|
63
63
|
class NullTemplate
|
64
64
|
# Render the layout template
|
65
65
|
#
|
66
|
+
# @param scope [Lotus::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
|
+
#
|
66
70
|
# @return [String] the output of the rendering process
|
67
71
|
#
|
68
72
|
# @api private
|
@@ -70,8 +74,8 @@ module Lotus
|
|
70
74
|
#
|
71
75
|
# @see Lotus::Layout#render
|
72
76
|
# @see Lotus::View::Rendering#render
|
73
|
-
def render(scope, locals = {}
|
74
|
-
|
77
|
+
def render(scope, locals = {})
|
78
|
+
yield
|
75
79
|
end
|
76
80
|
end
|
77
81
|
end
|
@@ -23,6 +23,18 @@ module Lotus
|
|
23
23
|
@view, @locals = view, locals
|
24
24
|
end
|
25
25
|
|
26
|
+
# Returns an inspect String
|
27
|
+
#
|
28
|
+
# @return [String] inspect String (contains classname, objectid in hex, available ivars)
|
29
|
+
#
|
30
|
+
# @since 0.3.0
|
31
|
+
def inspect
|
32
|
+
base = "#<#{ self.class }: #{'%x' % (self.object_id << 1)}"
|
33
|
+
base << " @view=\"#{@view}\"" if @view
|
34
|
+
base << " @locals=\"#{@locals}\"" if @locals
|
35
|
+
base << ">"
|
36
|
+
end
|
37
|
+
|
26
38
|
# Returns the requested format.
|
27
39
|
#
|
28
40
|
# @return [Symbol] the requested format (eg. :html, :json, :xml, etc..)
|
@@ -32,10 +44,23 @@ module Lotus
|
|
32
44
|
locals[:format]
|
33
45
|
end
|
34
46
|
|
47
|
+
# Implements "respond to" logic
|
48
|
+
#
|
49
|
+
# @return [TrueClass,FalseClass]
|
50
|
+
#
|
51
|
+
# @since 0.3.0
|
52
|
+
# @api private
|
53
|
+
#
|
54
|
+
# @see http://ruby-doc.org/core/Object.html#method-i-respond_to_missing-3F
|
55
|
+
def respond_to_missing?(m, include_all)
|
56
|
+
@view.respond_to?(m) ||
|
57
|
+
@locals.key?(m)
|
58
|
+
end
|
59
|
+
|
35
60
|
protected
|
36
|
-
def method_missing(m, *args)
|
61
|
+
def method_missing(m, *args, &block)
|
37
62
|
if @view.respond_to?(m)
|
38
|
-
@view.__send__ m, *args
|
63
|
+
@view.__send__ m, *args, &block
|
39
64
|
elsif @locals.key?(m)
|
40
65
|
@locals[m]
|
41
66
|
else
|
data/lib/lotus/view/template.rb
CHANGED
@@ -12,7 +12,7 @@ module Lotus
|
|
12
12
|
|
13
13
|
# Returns the format that the template handles.
|
14
14
|
#
|
15
|
-
# @return [
|
15
|
+
# @return [Symbol] the format name
|
16
16
|
#
|
17
17
|
# @since 0.1.0
|
18
18
|
#
|
@@ -20,11 +20,9 @@ module Lotus
|
|
20
20
|
# require 'lotus/view'
|
21
21
|
#
|
22
22
|
# template = Lotus::View::Template.new('index.html.erb')
|
23
|
-
# template.format # =>
|
23
|
+
# template.format # => :html
|
24
24
|
def format
|
25
|
-
@_template.basename.match(
|
26
|
-
gsub('.', ''). # TODO shame on me, this should be part of the regex above
|
27
|
-
to_sym
|
25
|
+
@_template.basename.match(/\.([^.]+)/).captures.first.to_sym
|
28
26
|
end
|
29
27
|
|
30
28
|
# Render the template within the context of the given scope.
|
data/lib/lotus/view/version.rb
CHANGED
data/lotus-view.gemspec
CHANGED
@@ -17,9 +17,10 @@ Gem::Specification.new do |spec|
|
|
17
17
|
spec.executables = []
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test)/})
|
19
19
|
spec.require_paths = ['lib']
|
20
|
+
spec.required_ruby_version = '>= 2.0.0'
|
20
21
|
|
21
22
|
spec.add_runtime_dependency 'tilt', '~> 2.0', '>= 2.0.1'
|
22
|
-
spec.add_runtime_dependency 'lotus-utils', '~> 0.2'
|
23
|
+
spec.add_runtime_dependency 'lotus-utils', '~> 0.3', '>= 0.3.2'
|
23
24
|
|
24
25
|
spec.add_development_dependency 'bundler', '~> 1.5'
|
25
26
|
spec.add_development_dependency 'minitest', '~> 5'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lotus-view
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Luca Guidi
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-12-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: tilt
|
@@ -36,14 +36,20 @@ dependencies:
|
|
36
36
|
requirements:
|
37
37
|
- - "~>"
|
38
38
|
- !ruby/object:Gem::Version
|
39
|
-
version: '0.
|
39
|
+
version: '0.3'
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: 0.3.2
|
40
43
|
type: :runtime
|
41
44
|
prerelease: false
|
42
45
|
version_requirements: !ruby/object:Gem::Requirement
|
43
46
|
requirements:
|
44
47
|
- - "~>"
|
45
48
|
- !ruby/object:Gem::Version
|
46
|
-
version: '0.
|
49
|
+
version: '0.3'
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: 0.3.2
|
47
53
|
- !ruby/object:Gem::Dependency
|
48
54
|
name: bundler
|
49
55
|
requirement: !ruby/object:Gem::Requirement
|
@@ -133,7 +139,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
133
139
|
requirements:
|
134
140
|
- - ">="
|
135
141
|
- !ruby/object:Gem::Version
|
136
|
-
version:
|
142
|
+
version: 2.0.0
|
137
143
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
138
144
|
requirements:
|
139
145
|
- - ">="
|