hanami-view 1.3.0.beta1 → 2.0.0.alpha2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +21 -0
- data/LICENSE +20 -0
- data/README.md +20 -862
- data/hanami-view.gemspec +26 -16
- data/lib/hanami-view.rb +3 -1
- data/lib/hanami/view.rb +208 -223
- data/lib/hanami/view/application_configuration.rb +77 -0
- data/lib/hanami/view/application_context.rb +35 -0
- data/lib/hanami/view/application_view.rb +89 -0
- data/lib/hanami/view/context.rb +97 -0
- data/lib/hanami/view/context_helpers/content_helpers.rb +26 -0
- data/lib/hanami/view/decorated_attributes.rb +82 -0
- data/lib/hanami/view/errors.rb +19 -56
- data/lib/hanami/view/exposure.rb +126 -0
- data/lib/hanami/view/exposures.rb +74 -0
- data/lib/hanami/view/part.rb +217 -0
- data/lib/hanami/view/part_builder.rb +140 -0
- data/lib/hanami/view/path.rb +68 -0
- data/lib/hanami/view/render_environment.rb +62 -0
- data/lib/hanami/view/render_environment_missing.rb +44 -0
- data/lib/hanami/view/rendered.rb +55 -0
- data/lib/hanami/view/renderer.rb +79 -0
- data/lib/hanami/view/scope.rb +189 -0
- data/lib/hanami/view/scope_builder.rb +98 -0
- data/lib/hanami/view/standalone_view.rb +396 -0
- data/lib/hanami/view/tilt.rb +78 -0
- data/lib/hanami/view/tilt/erb.rb +26 -0
- data/lib/hanami/view/tilt/erbse.rb +21 -0
- data/lib/hanami/view/tilt/haml.rb +26 -0
- data/lib/hanami/view/version.rb +5 -5
- metadata +113 -63
- data/LICENSE.md +0 -22
- data/lib/hanami/layout.rb +0 -172
- data/lib/hanami/presenter.rb +0 -98
- data/lib/hanami/view/configuration.rb +0 -504
- data/lib/hanami/view/dsl.rb +0 -347
- data/lib/hanami/view/escape.rb +0 -225
- data/lib/hanami/view/inheritable.rb +0 -54
- data/lib/hanami/view/rendering.rb +0 -294
- data/lib/hanami/view/rendering/layout_finder.rb +0 -128
- data/lib/hanami/view/rendering/layout_registry.rb +0 -69
- data/lib/hanami/view/rendering/layout_scope.rb +0 -274
- data/lib/hanami/view/rendering/null_layout.rb +0 -52
- data/lib/hanami/view/rendering/null_local.rb +0 -82
- data/lib/hanami/view/rendering/null_template.rb +0 -83
- data/lib/hanami/view/rendering/options.rb +0 -24
- data/lib/hanami/view/rendering/partial.rb +0 -31
- data/lib/hanami/view/rendering/partial_file.rb +0 -29
- data/lib/hanami/view/rendering/partial_finder.rb +0 -75
- data/lib/hanami/view/rendering/partial_templates_finder.rb +0 -73
- data/lib/hanami/view/rendering/registry.rb +0 -134
- data/lib/hanami/view/rendering/scope.rb +0 -108
- data/lib/hanami/view/rendering/subscope.rb +0 -56
- data/lib/hanami/view/rendering/template.rb +0 -69
- data/lib/hanami/view/rendering/template_finder.rb +0 -55
- data/lib/hanami/view/rendering/template_name.rb +0 -50
- data/lib/hanami/view/rendering/templates_finder.rb +0 -144
- data/lib/hanami/view/rendering/view_finder.rb +0 -37
- data/lib/hanami/view/template.rb +0 -57
@@ -1,108 +0,0 @@
|
|
1
|
-
require 'hanami/utils/escape'
|
2
|
-
require 'hanami/view/rendering/layout_scope'
|
3
|
-
require 'hanami/view/rendering/template'
|
4
|
-
require 'hanami/view/rendering/partial'
|
5
|
-
|
6
|
-
module Hanami
|
7
|
-
module View
|
8
|
-
module Rendering
|
9
|
-
# Rendering view scope
|
10
|
-
#
|
11
|
-
# @since 0.1.0
|
12
|
-
#
|
13
|
-
# @see Hanami::View::Rendering::LayoutScope
|
14
|
-
class Scope < LayoutScope
|
15
|
-
# Initialize the scope
|
16
|
-
#
|
17
|
-
# @param view [Class] the view
|
18
|
-
# @param locals [Hash] a set of objects available during the rendering
|
19
|
-
# @option locals [Symbol] :format the requested format
|
20
|
-
#
|
21
|
-
# @api private
|
22
|
-
# @since 0.1.0
|
23
|
-
def initialize(view, locals = {})
|
24
|
-
@view = view
|
25
|
-
@locals = locals
|
26
|
-
@layout = layout
|
27
|
-
@scope = nil
|
28
|
-
end
|
29
|
-
|
30
|
-
# Returns an inspect String
|
31
|
-
#
|
32
|
-
# @return [String] inspect String (contains classname, objectid in hex, available ivars)
|
33
|
-
#
|
34
|
-
# @since 0.3.0
|
35
|
-
def inspect
|
36
|
-
base = "#<#{ self.class }: #{'%x' % (self.object_id << 1)}"
|
37
|
-
base << " @view=\"#{@view}\"" if @view
|
38
|
-
base << " @locals=\"#{@locals}\"" if @locals
|
39
|
-
base << ">"
|
40
|
-
end
|
41
|
-
|
42
|
-
# Returns the requested format.
|
43
|
-
#
|
44
|
-
# @return [Symbol] the requested format (eg. :html, :json, :xml, etc..)
|
45
|
-
#
|
46
|
-
# @since 0.1.0
|
47
|
-
def format
|
48
|
-
locals[:format]
|
49
|
-
end
|
50
|
-
|
51
|
-
# Implements "respond to" logic
|
52
|
-
#
|
53
|
-
# @return [TrueClass,FalseClass]
|
54
|
-
#
|
55
|
-
# @since 0.3.0
|
56
|
-
# @api private
|
57
|
-
#
|
58
|
-
# @see http://ruby-doc.org/core/Object.html#method-i-respond_to_missing-3F
|
59
|
-
def respond_to_missing?(m, include_all)
|
60
|
-
# FIXME: this isn't compatible with Hanami 2.0, as it extends a view
|
61
|
-
# that we want to be frozen in the future
|
62
|
-
#
|
63
|
-
# See https://github.com/hanami/view/issues/130#issuecomment-319326236
|
64
|
-
@view.respond_to?(m, include_all) ||
|
65
|
-
@locals.key?(m)
|
66
|
-
end
|
67
|
-
|
68
|
-
protected
|
69
|
-
|
70
|
-
# @api private
|
71
|
-
def method_missing(m, *args, &block)
|
72
|
-
::Hanami::View::Escape.html(
|
73
|
-
# FIXME: this isn't compatible with Hanami 2.0, as it extends a view
|
74
|
-
# that we want to be frozen in the future
|
75
|
-
#
|
76
|
-
# See https://github.com/hanami/view/issues/130#issuecomment-319326236
|
77
|
-
if @view.respond_to?(m, true)
|
78
|
-
@view.__send__ m, *args, &block
|
79
|
-
elsif @locals.key?(m)
|
80
|
-
@locals[m]
|
81
|
-
else
|
82
|
-
super
|
83
|
-
end
|
84
|
-
)
|
85
|
-
end
|
86
|
-
|
87
|
-
private
|
88
|
-
|
89
|
-
# @since 1.1.1
|
90
|
-
# @api private
|
91
|
-
def _options(options)
|
92
|
-
current_locals = locals.reject { |key, _| @view.respond_to?(key) }
|
93
|
-
Options.build(options, current_locals, format)
|
94
|
-
end
|
95
|
-
|
96
|
-
# @since 0.4.2
|
97
|
-
# @api private
|
98
|
-
def layout
|
99
|
-
if @view.class.respond_to?(:layout)
|
100
|
-
@view.class.layout.new(self, "")
|
101
|
-
else
|
102
|
-
nil
|
103
|
-
end
|
104
|
-
end
|
105
|
-
end
|
106
|
-
end
|
107
|
-
end
|
108
|
-
end
|
@@ -1,56 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "hanami/view/rendering/scope"
|
4
|
-
require "hanami/view/rendering/options"
|
5
|
-
|
6
|
-
module Hanami
|
7
|
-
module View
|
8
|
-
module Rendering
|
9
|
-
# Rendering subscope
|
10
|
-
#
|
11
|
-
# @since 1.1.1
|
12
|
-
# @api private
|
13
|
-
#
|
14
|
-
# @see Hanami::View::Rendering::Scope
|
15
|
-
class Subscope < Scope
|
16
|
-
# Implements "respond to" logic
|
17
|
-
#
|
18
|
-
# @return [TrueClass,FalseClass]
|
19
|
-
#
|
20
|
-
# @since 1.1.1
|
21
|
-
# @api private
|
22
|
-
#
|
23
|
-
# @see http://ruby-doc.org/core/Object.html#method-i-respond_to_missing-3F
|
24
|
-
def respond_to_missing?(m, _include_all)
|
25
|
-
@locals.key?(m)
|
26
|
-
end
|
27
|
-
|
28
|
-
protected
|
29
|
-
|
30
|
-
# @since 1.1.1
|
31
|
-
# @api private
|
32
|
-
def method_missing(m, *args, &block)
|
33
|
-
::Hanami::View::Escape.html(
|
34
|
-
# FIXME: this isn't compatible with Hanami 2.0, as it extends a view
|
35
|
-
# that we want to be frozen in the future
|
36
|
-
#
|
37
|
-
# See https://github.com/hanami/view/issues/130#issuecomment-319326236
|
38
|
-
if @locals.key?(m)
|
39
|
-
@locals[m]
|
40
|
-
else
|
41
|
-
super
|
42
|
-
end
|
43
|
-
)
|
44
|
-
end
|
45
|
-
|
46
|
-
private
|
47
|
-
|
48
|
-
# @since 1.1.1
|
49
|
-
# @api private
|
50
|
-
def _options(options)
|
51
|
-
Options.build(options, locals, format)
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
@@ -1,69 +0,0 @@
|
|
1
|
-
require 'hanami/view/rendering/template_finder'
|
2
|
-
|
3
|
-
module Hanami
|
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 Hanami::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 [Hanami::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
|
-
# @raise [Hanami::View::MissingTemplateError] if template can't be found
|
40
|
-
#
|
41
|
-
# @api private
|
42
|
-
# @since 0.1.0
|
43
|
-
def render
|
44
|
-
(template or raise_missing_template_error).render(scope)
|
45
|
-
end
|
46
|
-
|
47
|
-
protected
|
48
|
-
# @api private
|
49
|
-
def template
|
50
|
-
TemplateFinder.new(@view.class, @options).find
|
51
|
-
end
|
52
|
-
|
53
|
-
# @api private
|
54
|
-
def scope
|
55
|
-
Subscope.new(@view, @options[:locals])
|
56
|
-
end
|
57
|
-
|
58
|
-
# @since 0.5.0
|
59
|
-
# @api private
|
60
|
-
def raise_missing_template_error
|
61
|
-
raise MissingTemplateError.new(
|
62
|
-
@options.fetch(:template) { @options.fetch(:partial, nil) },
|
63
|
-
@options[:format]
|
64
|
-
)
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
@@ -1,55 +0,0 @@
|
|
1
|
-
require 'hanami/view/rendering/templates_finder'
|
2
|
-
|
3
|
-
module Hanami
|
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 Hanami::View::Rendering::Template
|
10
|
-
# @see Hanami::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 [Hanami::View::Template] the requested template
|
32
|
-
#
|
33
|
-
# @api private
|
34
|
-
# @since 0.1.0
|
35
|
-
#
|
36
|
-
# @see Hanami::View::Rendering::TemplatesFinder#find
|
37
|
-
# @see Hanami::View::Rendering::Template#render
|
38
|
-
def find
|
39
|
-
super.first
|
40
|
-
end
|
41
|
-
|
42
|
-
protected
|
43
|
-
# @api private
|
44
|
-
def template_name
|
45
|
-
@options[:template]
|
46
|
-
end
|
47
|
-
|
48
|
-
# @api private
|
49
|
-
def format
|
50
|
-
@options[:format]
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
@@ -1,50 +0,0 @@
|
|
1
|
-
require 'hanami/utils/string'
|
2
|
-
|
3
|
-
module Hanami
|
4
|
-
module View
|
5
|
-
module Rendering
|
6
|
-
# @since 0.2.0
|
7
|
-
# @api private
|
8
|
-
class TemplateName
|
9
|
-
# @since 0.2.0
|
10
|
-
# @api private
|
11
|
-
NAMESPACE_SEPARATOR = '::'.freeze
|
12
|
-
|
13
|
-
# @since 0.2.0
|
14
|
-
# @api private
|
15
|
-
def initialize(name, namespace)
|
16
|
-
@name = name
|
17
|
-
compile!(namespace)
|
18
|
-
end
|
19
|
-
|
20
|
-
# @since 0.2.0
|
21
|
-
# @api private
|
22
|
-
def to_s
|
23
|
-
@name
|
24
|
-
end
|
25
|
-
|
26
|
-
private
|
27
|
-
# @since 0.2.0
|
28
|
-
# @api private
|
29
|
-
def compile!(namespace)
|
30
|
-
tokens(namespace) {|token| replace!(token) }
|
31
|
-
@name = Utils::String.underscore(@name)
|
32
|
-
end
|
33
|
-
|
34
|
-
# @since 0.2.0
|
35
|
-
# @api private
|
36
|
-
def tokens(namespace)
|
37
|
-
namespace.to_s.split(NAMESPACE_SEPARATOR).each do |token|
|
38
|
-
yield token
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
# @since 0.2.0
|
43
|
-
# @api private
|
44
|
-
def replace!(token)
|
45
|
-
@name.gsub!(%r{\A#{ token }#{ NAMESPACE_SEPARATOR }}, '')
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
@@ -1,144 +0,0 @@
|
|
1
|
-
require 'hanami/view/template'
|
2
|
-
|
3
|
-
module Hanami
|
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
|
-
# Default format
|
14
|
-
#
|
15
|
-
# @api private
|
16
|
-
# @since 0.1.0
|
17
|
-
FORMAT = '*'.freeze
|
18
|
-
|
19
|
-
# Default template engines
|
20
|
-
#
|
21
|
-
# @api private
|
22
|
-
# @since 0.1.0
|
23
|
-
ENGINES = '*'.freeze
|
24
|
-
|
25
|
-
# Recursive pattern
|
26
|
-
#
|
27
|
-
# @api private
|
28
|
-
# @since 0.2.0
|
29
|
-
RECURSIVE = '**'.freeze
|
30
|
-
|
31
|
-
# Initialize a finder
|
32
|
-
#
|
33
|
-
# @param view [Class] the view
|
34
|
-
#
|
35
|
-
# @api private
|
36
|
-
# @since 0.1.0
|
37
|
-
def initialize(view)
|
38
|
-
@view = view
|
39
|
-
end
|
40
|
-
|
41
|
-
# Find all the associated templates to the view.
|
42
|
-
# It recursively looks for templates under the root path of the view,
|
43
|
-
# that are matching the template name
|
44
|
-
#
|
45
|
-
# @return [Array<Hanami::View::Template>] the templates
|
46
|
-
#
|
47
|
-
# @api private
|
48
|
-
# @since 0.1.0
|
49
|
-
#
|
50
|
-
# @see Hanami::View::Dsl#root
|
51
|
-
# @see Hanami::View::Dsl#template
|
52
|
-
#
|
53
|
-
# @example
|
54
|
-
# require 'hanami/view'
|
55
|
-
#
|
56
|
-
# module Articles
|
57
|
-
# class Show
|
58
|
-
# include Hanami::View
|
59
|
-
# end
|
60
|
-
# end
|
61
|
-
#
|
62
|
-
# Articles::Show.root # => "/path/to/templates"
|
63
|
-
# Articles::Show.template # => "articles/show"
|
64
|
-
#
|
65
|
-
# # This view has a template:
|
66
|
-
# #
|
67
|
-
# # "/path/to/templates/articles/show.html.erb"
|
68
|
-
#
|
69
|
-
# Hanami::View::Rendering::TemplatesFinder.new(Articles::Show).find
|
70
|
-
# # => [#<Hanami::View::Template:0x007f8a0a86a970 ... @file="/path/to/templates/articles/show.html.erb">]
|
71
|
-
def find
|
72
|
-
_find.map do |template|
|
73
|
-
View::Template.new(template, @view.configuration.default_encoding)
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
protected
|
78
|
-
|
79
|
-
# @api private
|
80
|
-
# @since 0.4.3
|
81
|
-
#
|
82
|
-
# Searches first for files at `../templates/articles/index.*.*`
|
83
|
-
# If none are found, falls back to recursive search in `../templates/**/articles/index.*.*`
|
84
|
-
#
|
85
|
-
def _find(lookup = search_path)
|
86
|
-
base_path = templates_path(root, template_name)
|
87
|
-
if base_path.none?
|
88
|
-
templates_path(root, lookup, template_name)
|
89
|
-
else
|
90
|
-
base_path
|
91
|
-
end
|
92
|
-
end
|
93
|
-
|
94
|
-
# @api private
|
95
|
-
# @since 0.7.0
|
96
|
-
def templates_path(*parts)
|
97
|
-
Dir.glob("#{ parts.join(separator) }.#{ format }.#{ engines }")
|
98
|
-
end
|
99
|
-
|
100
|
-
# @api private
|
101
|
-
# @since 0.1.0
|
102
|
-
def template_name
|
103
|
-
@view.template
|
104
|
-
end
|
105
|
-
|
106
|
-
# @api private
|
107
|
-
# @since 0.1.0
|
108
|
-
def root
|
109
|
-
@view.root
|
110
|
-
end
|
111
|
-
|
112
|
-
# @api private
|
113
|
-
# @since 0.4.3
|
114
|
-
def search_path
|
115
|
-
recursive
|
116
|
-
end
|
117
|
-
|
118
|
-
# @api private
|
119
|
-
# @since 0.2.0
|
120
|
-
def recursive
|
121
|
-
RECURSIVE
|
122
|
-
end
|
123
|
-
|
124
|
-
# @api private
|
125
|
-
# @since 0.1.0
|
126
|
-
def separator
|
127
|
-
::File::SEPARATOR
|
128
|
-
end
|
129
|
-
|
130
|
-
# @api private
|
131
|
-
# @since 0.1.0
|
132
|
-
def format
|
133
|
-
FORMAT
|
134
|
-
end
|
135
|
-
|
136
|
-
# @api private
|
137
|
-
# @since 0.1.0
|
138
|
-
def engines
|
139
|
-
ENGINES
|
140
|
-
end
|
141
|
-
end
|
142
|
-
end
|
143
|
-
end
|
144
|
-
end
|