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,138 @@
|
|
1
|
+
module Lotus
|
2
|
+
module View
|
3
|
+
module Rendering
|
4
|
+
# Scope for layout rendering
|
5
|
+
#
|
6
|
+
# @since 0.1.0
|
7
|
+
class LayoutScope
|
8
|
+
# Initialize the scope
|
9
|
+
#
|
10
|
+
# @param layout [Lotus::Layout] the layout to render
|
11
|
+
# @param scope [Lotus::View::Rendering::Scope] the scope of the current
|
12
|
+
# view
|
13
|
+
#
|
14
|
+
# @api private
|
15
|
+
# @since 0.1.0
|
16
|
+
def initialize(layout, scope)
|
17
|
+
@layout, @scope = layout, scope
|
18
|
+
end
|
19
|
+
|
20
|
+
# Render a partial or a template within a layout template.
|
21
|
+
#
|
22
|
+
# @param options [Hash]
|
23
|
+
# @option options [String] :partial the partial template to render
|
24
|
+
# @option options [String] :template the template to render
|
25
|
+
#
|
26
|
+
# @return [String] the output of the rendering process
|
27
|
+
#
|
28
|
+
# @since 0.1.0
|
29
|
+
#
|
30
|
+
# @example Rendering partial
|
31
|
+
# # Given a partial under:
|
32
|
+
# # templates/shared/_sidebar.html.erb
|
33
|
+
# #
|
34
|
+
# # In the layout template:
|
35
|
+
# # templates/application.html.erb
|
36
|
+
# #
|
37
|
+
# # Use like this:
|
38
|
+
# <%= render partial: 'shared/sidebar' %>
|
39
|
+
#
|
40
|
+
# @example Rendering template
|
41
|
+
# # Given a template under:
|
42
|
+
# # templates/articles/index.html.erb
|
43
|
+
# #
|
44
|
+
# # In the layout template:
|
45
|
+
# # templates/application.html.erb
|
46
|
+
# #
|
47
|
+
# # Use like this:
|
48
|
+
# <%= render template: 'articles/index' %>
|
49
|
+
#
|
50
|
+
# @example Rendering partial, using optional :locals
|
51
|
+
# # Given a partial under:
|
52
|
+
# # templates/shared/_sidebar.html.erb
|
53
|
+
# #
|
54
|
+
# # In the layout template:
|
55
|
+
# # templates/application.html.erb
|
56
|
+
# #
|
57
|
+
# # Use like this:
|
58
|
+
# <%= render partial: 'shared/sidebar', { user: current_user } %>
|
59
|
+
#
|
60
|
+
# #
|
61
|
+
# # `user` will be available in the scope of the sidebar rendering
|
62
|
+
def render(options)
|
63
|
+
renderer(options).render
|
64
|
+
end
|
65
|
+
|
66
|
+
# Returns the requested format.
|
67
|
+
#
|
68
|
+
# @return [Symbol] the requested format (eg. :html, :json, :xml, etc..)
|
69
|
+
#
|
70
|
+
# @since 0.1.0
|
71
|
+
def format
|
72
|
+
@scope.format
|
73
|
+
end
|
74
|
+
|
75
|
+
# The current view.
|
76
|
+
#
|
77
|
+
# @return [Lotus::View] the current view
|
78
|
+
#
|
79
|
+
# @since 0.1.0
|
80
|
+
def view
|
81
|
+
@view || @scope.view
|
82
|
+
end
|
83
|
+
|
84
|
+
# The current locals.
|
85
|
+
#
|
86
|
+
# @return [Hash] the current locals
|
87
|
+
#
|
88
|
+
# @since 0.1.0
|
89
|
+
def locals
|
90
|
+
@locals || @scope.locals
|
91
|
+
end
|
92
|
+
|
93
|
+
protected
|
94
|
+
# Forward all the missing methods to the view scope or to the layout.
|
95
|
+
#
|
96
|
+
# @api private
|
97
|
+
# @since 0.1.0
|
98
|
+
#
|
99
|
+
# @see Lotus::View::Rendering::Scope
|
100
|
+
# @see Lotus::Layout
|
101
|
+
#
|
102
|
+
# @example
|
103
|
+
# # In the layout template:
|
104
|
+
# # templates/application.html.erb
|
105
|
+
# #
|
106
|
+
# # Use like this:
|
107
|
+
# <title><%= article.title %></title>
|
108
|
+
#
|
109
|
+
# # `article` will be looked up in the view scope first.
|
110
|
+
# # If not found, it will be searched within the layout.
|
111
|
+
def method_missing(m)
|
112
|
+
begin
|
113
|
+
@scope.__send__ m
|
114
|
+
rescue
|
115
|
+
@layout.__send__ m
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def renderer(options)
|
120
|
+
if options[:partial]
|
121
|
+
Rendering::Partial
|
122
|
+
elsif options[:template]
|
123
|
+
Rendering::Template
|
124
|
+
end.new(view, _options(options))
|
125
|
+
end
|
126
|
+
|
127
|
+
private
|
128
|
+
def _options(options)
|
129
|
+
options.dup.tap do |opts|
|
130
|
+
opts.merge!(format: format)
|
131
|
+
opts[:locals] ||= {}
|
132
|
+
opts[:locals].merge!(locals)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Lotus
|
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 'lotus/view'
|
12
|
+
#
|
13
|
+
# module Articles
|
14
|
+
# class Show
|
15
|
+
# include Lotus::View
|
16
|
+
# layout nil
|
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 [Lotus::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 Lotus::Layout#initialize
|
32
|
+
# @see Lotus::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 Lotus::Layout#render
|
45
|
+
# @see Lotus::View::Rendering#render
|
46
|
+
def render
|
47
|
+
@rendered
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
module Lotus
|
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 a
|
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 'lotus/view'
|
19
|
+
#
|
20
|
+
# # We have an ApplicationLayout (views/application_layout.rb):
|
21
|
+
# class ApplicationLayout
|
22
|
+
# include Lotus::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
|
+
# Lotus::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 Lotus::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
|
+
# Lotus::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
|
+
# @return [String] the output of the rendering process
|
67
|
+
#
|
68
|
+
# @api private
|
69
|
+
# @since 0.1.0
|
70
|
+
#
|
71
|
+
# @see Lotus::Layout#render
|
72
|
+
# @see Lotus::View::Rendering#render
|
73
|
+
def render(scope, locals = {}, &blk)
|
74
|
+
blk.call
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'lotus/view/rendering/partial_finder'
|
2
|
+
|
3
|
+
module Lotus
|
4
|
+
module View
|
5
|
+
module Rendering
|
6
|
+
# Rendering partial
|
7
|
+
#
|
8
|
+
# It's used when a template wants to render a partial.
|
9
|
+
#
|
10
|
+
# @api private
|
11
|
+
# @since 0.1.0
|
12
|
+
#
|
13
|
+
# @see Lotus::View::Rendering::Template
|
14
|
+
# @see Lotus::View::Rendering::LayoutScope#render
|
15
|
+
#
|
16
|
+
# @example
|
17
|
+
# # We have an application template (templates/application.html.erb)
|
18
|
+
# # that uses the following line:
|
19
|
+
#
|
20
|
+
# <%= render partial: 'shared/sidebar' %>
|
21
|
+
class Partial < Template
|
22
|
+
protected
|
23
|
+
def template
|
24
|
+
PartialFinder.new(@view.class, @options).find
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'lotus/view/rendering/template_finder'
|
2
|
+
|
3
|
+
module Lotus
|
4
|
+
module View
|
5
|
+
module Rendering
|
6
|
+
# Find a partial for the current view context.
|
7
|
+
# It's used when a template wants to render a partial.
|
8
|
+
#
|
9
|
+
# @see Lotus::View::Rendering::Partial
|
10
|
+
# @see Lotus::View::Rendering::TemplateFinder
|
11
|
+
#
|
12
|
+
# @api private
|
13
|
+
# @since 0.1.0
|
14
|
+
class PartialFinder < TemplateFinder
|
15
|
+
# Template file name prefix.
|
16
|
+
# By convention a partial file name starts with this prefix.
|
17
|
+
#
|
18
|
+
# @api private
|
19
|
+
# @since 0.1.0
|
20
|
+
#
|
21
|
+
# @example
|
22
|
+
# "_sidebar.html.erb"
|
23
|
+
PREFIX = '_'.freeze
|
24
|
+
|
25
|
+
protected
|
26
|
+
def template_name
|
27
|
+
*all, last = partial_name.split(separator)
|
28
|
+
all.push( last.prepend(prefix) ).join(separator)
|
29
|
+
end
|
30
|
+
|
31
|
+
def partial_name
|
32
|
+
@options[:partial]
|
33
|
+
end
|
34
|
+
|
35
|
+
def prefix
|
36
|
+
PREFIX
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,129 @@
|
|
1
|
+
require 'lotus/view/rendering/layout_registry'
|
2
|
+
require 'lotus/view/rendering/view_finder'
|
3
|
+
|
4
|
+
module Lotus
|
5
|
+
module View
|
6
|
+
module Rendering
|
7
|
+
# Holds all the references of all the registered subclasses of a view.
|
8
|
+
# We have one registry for each superclass view.
|
9
|
+
#
|
10
|
+
# @api private
|
11
|
+
# @since 0.1.0
|
12
|
+
#
|
13
|
+
# @see Lotus::View::Rendering::LayoutRegistry
|
14
|
+
# @see Lotus::View::Rendering#registry
|
15
|
+
#
|
16
|
+
# @example
|
17
|
+
# require 'lotus/view'
|
18
|
+
#
|
19
|
+
# module Articles
|
20
|
+
# class Index
|
21
|
+
# include Lotus::View
|
22
|
+
# end
|
23
|
+
#
|
24
|
+
# class Show
|
25
|
+
# include Lotus::View
|
26
|
+
# end
|
27
|
+
#
|
28
|
+
# class JsonShow < Show
|
29
|
+
# format :json
|
30
|
+
# end
|
31
|
+
#
|
32
|
+
# class XmlShow < Show
|
33
|
+
# format :xml
|
34
|
+
#
|
35
|
+
# def render
|
36
|
+
# ArticleSerializer.new(article).to_xml
|
37
|
+
# end
|
38
|
+
# end
|
39
|
+
# end
|
40
|
+
#
|
41
|
+
# # We have the following templates:
|
42
|
+
# #
|
43
|
+
# # * articles/index.html.erb
|
44
|
+
# # * articles/index.atom.erb
|
45
|
+
# # * articles/show.html.erb
|
46
|
+
# # * articles/show.json.erb
|
47
|
+
#
|
48
|
+
# # One registry per superclass view
|
49
|
+
# Articles::Index.send(:registry).object_id # => 70135342862240
|
50
|
+
#
|
51
|
+
# Articles::Show.send(:registry).object_id # => 70135342110540
|
52
|
+
# Articles::XmlShow.send(:registry).object_id # => 70135342110540
|
53
|
+
# Articles::JsonShow.send(:registry).object_id # => 70135342110540
|
54
|
+
#
|
55
|
+
#
|
56
|
+
#
|
57
|
+
# # It holds the references for all the templates and the views
|
58
|
+
# Articles::Index.send(:registry).inspect
|
59
|
+
# # => { :all => [Articles::Index, nil],
|
60
|
+
# # :atom => [Articles::Index, #<Lotus::View::Template ... @file="/path/to/templates/articles/index.atom.erb"],
|
61
|
+
# # :html => [Articles::Index, #<Lotus::View::Template ... @file="/path/to/templates/articles/index.html.erb"] }
|
62
|
+
#
|
63
|
+
# Articles::Show.send(:registry).inspect
|
64
|
+
# # => { :all => [Articles::Show, nil],
|
65
|
+
# # :html => [Articles::Show, #<Lotus::View::Template ... @file="/path/to/templates/articles/show.html.erb"],
|
66
|
+
# # :json => [Articles::JsonShow, #<Lotus::View::Template ... @file="/path/to/templates/articles/show.json.erb"],
|
67
|
+
# # :xml => [Articles::XmlShow, nil] }
|
68
|
+
class Registry < LayoutRegistry
|
69
|
+
# Default format for views without an explicit format.
|
70
|
+
#
|
71
|
+
# @api private
|
72
|
+
# @since 0.1.0
|
73
|
+
#
|
74
|
+
# @see Lotus::View::Dsl#format
|
75
|
+
DEFAULT_FORMAT = :all
|
76
|
+
|
77
|
+
# Returns the view for the given context.
|
78
|
+
#
|
79
|
+
# @param context [Hash] the rendering context
|
80
|
+
# @option context [Symbol] :format the requested format
|
81
|
+
# @param locals [Hash] the set of available objects
|
82
|
+
#
|
83
|
+
# @return [Lotus::View] the view associated with the given context
|
84
|
+
#
|
85
|
+
# @raise [Lotus::View::MissingFormatError] if the given context doesn't
|
86
|
+
# have the :format key
|
87
|
+
#
|
88
|
+
# @api private
|
89
|
+
# @since 0.1.0
|
90
|
+
#
|
91
|
+
# @see Lotus::View::Rendering#render
|
92
|
+
def resolve(context)
|
93
|
+
view, template = fetch(format(context)) { self[DEFAULT_FORMAT] }
|
94
|
+
view.new(template, context)
|
95
|
+
end
|
96
|
+
|
97
|
+
private
|
98
|
+
def prepare!
|
99
|
+
prepare_views!
|
100
|
+
prepare_templates!
|
101
|
+
end
|
102
|
+
|
103
|
+
def prepare_views!
|
104
|
+
views.each do |view|
|
105
|
+
merge! view.format || DEFAULT_FORMAT => [ view, template_for(view) ]
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def prepare_templates!
|
110
|
+
templates.each do |template|
|
111
|
+
merge! template.format => [ view_for(template), template ]
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def views
|
116
|
+
@view.subclasses + [ @view ]
|
117
|
+
end
|
118
|
+
|
119
|
+
def view_for(template)
|
120
|
+
ViewFinder.new(@view).find(template)
|
121
|
+
end
|
122
|
+
|
123
|
+
def template_for(view)
|
124
|
+
templates.find {|template| template.format == view.format }
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'lotus/view/rendering/layout_scope'
|
2
|
+
require 'lotus/view/rendering/template'
|
3
|
+
require 'lotus/view/rendering/partial'
|
4
|
+
|
5
|
+
module Lotus
|
6
|
+
module View
|
7
|
+
module Rendering
|
8
|
+
# Rendering scope
|
9
|
+
#
|
10
|
+
# @since 0.1.0
|
11
|
+
#
|
12
|
+
# @see Lotus::View::Rendering::LayoutScope
|
13
|
+
class Scope < LayoutScope
|
14
|
+
# Initialize the scope
|
15
|
+
#
|
16
|
+
# @param view [Class] the view
|
17
|
+
# @param locals [Hash] a set of objects available during the rendering
|
18
|
+
# @option locals [Symbol] :format the requested format
|
19
|
+
#
|
20
|
+
# @api private
|
21
|
+
# @since 0.1.0
|
22
|
+
def initialize(view, locals = {})
|
23
|
+
@view, @locals = view, locals
|
24
|
+
end
|
25
|
+
|
26
|
+
# Returns the requested format.
|
27
|
+
#
|
28
|
+
# @return [Symbol] the requested format (eg. :html, :json, :xml, etc..)
|
29
|
+
#
|
30
|
+
# @since 0.1.0
|
31
|
+
def format
|
32
|
+
locals[:format]
|
33
|
+
end
|
34
|
+
|
35
|
+
protected
|
36
|
+
def method_missing(m)
|
37
|
+
if @view.respond_to?(m)
|
38
|
+
@view.__send__ m
|
39
|
+
elsif @locals.key?(m)
|
40
|
+
@locals[m]
|
41
|
+
else
|
42
|
+
super
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'lotus/view/rendering/template_finder'
|
2
|
+
|
3
|
+
module Lotus
|
4
|
+
module View
|
5
|
+
module Rendering
|
6
|
+
# Rendering template
|
7
|
+
#
|
8
|
+
# It's used when a template wants to render another template.
|
9
|
+
#
|
10
|
+
# @api private
|
11
|
+
# @since 0.1.0
|
12
|
+
#
|
13
|
+
# @see Lotus::View::Rendering::LayoutScope#render
|
14
|
+
#
|
15
|
+
# @example
|
16
|
+
# # We have an application template (templates/application.html.erb)
|
17
|
+
# # that uses the following line:
|
18
|
+
#
|
19
|
+
# <%= render template: 'articles/show' %>
|
20
|
+
class Template
|
21
|
+
# Initialize a template
|
22
|
+
#
|
23
|
+
# @param view [Lotus::View] the current view
|
24
|
+
# @param options [Hash] the rendering informations
|
25
|
+
# @option options [Symbol] :format the current format
|
26
|
+
# @option options [Hash] :locals the set of objects available within
|
27
|
+
# the rendering context
|
28
|
+
#
|
29
|
+
# @api private
|
30
|
+
# @since 0.1.0
|
31
|
+
def initialize(view, options)
|
32
|
+
@view, @options = view, options
|
33
|
+
end
|
34
|
+
|
35
|
+
# Render the template.
|
36
|
+
#
|
37
|
+
# @return [String] the output of the rendering process.
|
38
|
+
#
|
39
|
+
# @api private
|
40
|
+
# @since 0.1.0
|
41
|
+
def render
|
42
|
+
template.render(scope)
|
43
|
+
end
|
44
|
+
|
45
|
+
protected
|
46
|
+
def template
|
47
|
+
TemplateFinder.new(@view.class, @options).find
|
48
|
+
end
|
49
|
+
|
50
|
+
def scope
|
51
|
+
Scope.new(@view, @options[:locals])
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'lotus/view/rendering/templates_finder'
|
2
|
+
|
3
|
+
module Lotus
|
4
|
+
module View
|
5
|
+
module Rendering
|
6
|
+
# Find a template for the current view context.
|
7
|
+
# It's used when a template wants to render another template.
|
8
|
+
#
|
9
|
+
# @see Lotus::View::Rendering::Template
|
10
|
+
# @see Lotus::View::Rendering::TemplatesFinder
|
11
|
+
#
|
12
|
+
# @api private
|
13
|
+
# @since 0.1.0
|
14
|
+
class TemplateFinder < TemplatesFinder
|
15
|
+
# Initialize a finder
|
16
|
+
#
|
17
|
+
# @param view [Class] a view
|
18
|
+
# @param options [Hash] the informations about the context
|
19
|
+
# @option options [String] :template the template file name
|
20
|
+
# @option options [Symbol] :format the requested format
|
21
|
+
#
|
22
|
+
# @api private
|
23
|
+
# @since 0.1.0
|
24
|
+
def initialize(view, options)
|
25
|
+
super(view)
|
26
|
+
@options = options
|
27
|
+
end
|
28
|
+
|
29
|
+
# Find a template for the current view context
|
30
|
+
#
|
31
|
+
# @return [Lotus::View::Template] the requested template
|
32
|
+
#
|
33
|
+
# @api private
|
34
|
+
# @since 0.1.0
|
35
|
+
#
|
36
|
+
# @see Lotus::View::Rendering::TemplatesFinder#find
|
37
|
+
# @see Lotus::View::Rendering::Template#render
|
38
|
+
def find
|
39
|
+
super.first
|
40
|
+
end
|
41
|
+
|
42
|
+
protected
|
43
|
+
def template_name
|
44
|
+
@options[:template]
|
45
|
+
end
|
46
|
+
|
47
|
+
def format
|
48
|
+
@options[:format]
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|