hanami-view 2.0.0.alpha8 → 2.1.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +30 -0
- data/README.md +15 -3
- data/hanami-view.gemspec +5 -3
- data/lib/hanami/view/cache.rb +16 -0
- data/lib/hanami/view/context.rb +15 -55
- data/lib/hanami/view/context_helpers/content_helpers.rb +5 -5
- data/lib/hanami/view/decorated_attributes.rb +2 -2
- data/lib/hanami/view/erb/engine.rb +27 -0
- data/lib/hanami/view/erb/filters/block.rb +44 -0
- data/lib/hanami/view/erb/filters/trimming.rb +42 -0
- data/lib/hanami/view/erb/parser.rb +161 -0
- data/lib/hanami/view/erb/template.rb +30 -0
- data/lib/hanami/view/errors.rb +8 -2
- data/lib/hanami/view/exposure.rb +23 -17
- data/lib/hanami/view/exposures.rb +22 -13
- data/lib/hanami/view/helpers/escape_helper.rb +221 -0
- data/lib/hanami/view/helpers/number_formatting_helper.rb +182 -0
- data/lib/hanami/view/helpers/tag_helper/tag_builder.rb +230 -0
- data/lib/hanami/view/helpers/tag_helper.rb +210 -0
- data/lib/hanami/view/html.rb +104 -0
- data/lib/hanami/view/html_safe_string_buffer.rb +46 -0
- data/lib/hanami/view/part.rb +13 -15
- data/lib/hanami/view/part_builder.rb +68 -108
- data/lib/hanami/view/path.rb +4 -31
- data/lib/hanami/view/renderer.rb +36 -44
- data/lib/hanami/view/rendering.rb +42 -0
- data/lib/hanami/view/{render_environment_missing.rb → rendering_missing.rb} +8 -13
- data/lib/hanami/view/scope.rb +14 -15
- data/lib/hanami/view/scope_builder.rb +42 -78
- data/lib/hanami/view/tilt/haml_adapter.rb +40 -0
- data/lib/hanami/view/tilt/slim_adapter.rb +40 -0
- data/lib/hanami/view/tilt.rb +22 -46
- data/lib/hanami/view/version.rb +1 -1
- data/lib/hanami/view.rb +53 -91
- metadata +64 -26
- data/LICENSE +0 -20
- data/lib/hanami/view/render_environment.rb +0 -62
- data/lib/hanami/view/tilt/erb.rb +0 -26
- data/lib/hanami/view/tilt/erbse.rb +0 -21
- data/lib/hanami/view/tilt/haml.rb +0 -26
data/lib/hanami/view/path.rb
CHANGED
@@ -1,13 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "pathname"
|
4
|
-
require "dry/core/cache"
|
5
4
|
|
6
5
|
module Hanami
|
7
6
|
class View
|
8
7
|
# @api private
|
9
8
|
class Path
|
10
|
-
extend Dry::Core::Cache
|
11
9
|
include Dry::Equalizer(:dir, :root)
|
12
10
|
|
13
11
|
attr_reader :dir, :root
|
@@ -25,12 +23,10 @@ module Hanami
|
|
25
23
|
@root = Pathname(root)
|
26
24
|
end
|
27
25
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
parent_dir && lookup_in_parent_dir(name, format, child_dirs: child_dirs)
|
33
|
-
end
|
26
|
+
# Searches for a template using a wildcard for the engine extension
|
27
|
+
def lookup(prefix, name, format)
|
28
|
+
glob = dir.join(prefix, "#{name}.#{format}.*")
|
29
|
+
Dir[glob].first
|
34
30
|
end
|
35
31
|
|
36
32
|
def chdir(dirname)
|
@@ -40,29 +36,6 @@ module Hanami
|
|
40
36
|
def to_s
|
41
37
|
dir.to_s
|
42
38
|
end
|
43
|
-
|
44
|
-
private
|
45
|
-
|
46
|
-
def root?
|
47
|
-
dir == root
|
48
|
-
end
|
49
|
-
|
50
|
-
# Search for a template using a wildcard for the engine extension
|
51
|
-
def lookup_template(name, format)
|
52
|
-
glob = dir.join("#{name}.#{format}.*")
|
53
|
-
Dir[glob].first
|
54
|
-
end
|
55
|
-
|
56
|
-
def lookup_in_child_dirs(name, format, child_dirs:)
|
57
|
-
child_dirs.reduce(nil) { |_, dir|
|
58
|
-
template = chdir(dir).lookup(name, format)
|
59
|
-
break template if template
|
60
|
-
}
|
61
|
-
end
|
62
|
-
|
63
|
-
def lookup_in_parent_dir(name, format, child_dirs:)
|
64
|
-
!root? && chdir("..").lookup(name, format, child_dirs: child_dirs, parent_dir: true)
|
65
|
-
end
|
66
39
|
end
|
67
40
|
end
|
68
41
|
end
|
data/lib/hanami/view/renderer.rb
CHANGED
@@ -1,9 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "dry/core/cache"
|
4
|
-
require "dry/core/equalizer"
|
5
3
|
require_relative "errors"
|
6
|
-
require_relative "tilt"
|
7
4
|
|
8
5
|
module Hanami
|
9
6
|
class View
|
@@ -11,67 +8,62 @@ module Hanami
|
|
11
8
|
class Renderer
|
12
9
|
PARTIAL_PREFIX = "_"
|
13
10
|
PATH_DELIMITER = "/"
|
11
|
+
CURRENT_PATH_PREFIX = "."
|
14
12
|
|
15
|
-
|
13
|
+
attr_reader :config, :prefixes
|
16
14
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
def initialize(paths, format:, engine_mapping: nil, **options)
|
22
|
-
@paths = paths
|
23
|
-
@format = format
|
24
|
-
@engine_mapping = engine_mapping || {}
|
25
|
-
@options = options
|
15
|
+
def initialize(config)
|
16
|
+
@config = config
|
17
|
+
@prefixes = [CURRENT_PATH_PREFIX]
|
26
18
|
end
|
27
19
|
|
28
|
-
def template(name,
|
29
|
-
|
20
|
+
def template(name, format, scope, &block)
|
21
|
+
old_prefixes = @prefixes.dup
|
30
22
|
|
31
|
-
|
32
|
-
render(path, scope, &block)
|
33
|
-
else
|
34
|
-
raise TemplateNotFoundError.new(name, paths)
|
35
|
-
end
|
36
|
-
end
|
23
|
+
template_path = lookup(name, format)
|
37
24
|
|
38
|
-
|
39
|
-
template(
|
40
|
-
name_for_partial(name),
|
41
|
-
scope,
|
42
|
-
child_dirs: %w[shared],
|
43
|
-
parent_dir: true,
|
44
|
-
&block
|
45
|
-
)
|
46
|
-
end
|
25
|
+
raise TemplateNotFoundError.new(name, format, config.paths) unless template_path
|
47
26
|
|
48
|
-
|
49
|
-
|
50
|
-
end
|
27
|
+
new_prefix = File.dirname(name)
|
28
|
+
@prefixes << new_prefix unless @prefixes.include?(new_prefix)
|
51
29
|
|
52
|
-
|
53
|
-
|
30
|
+
render(template_path, scope, &block)
|
31
|
+
ensure
|
32
|
+
@prefixes = old_prefixes
|
33
|
+
end
|
54
34
|
|
55
|
-
|
35
|
+
def partial(name, format, scope, &block)
|
36
|
+
template(name_for_partial(name), format, scope, &block)
|
56
37
|
end
|
57
38
|
|
58
39
|
private
|
59
40
|
|
60
|
-
def lookup(name,
|
61
|
-
|
62
|
-
|
63
|
-
|
41
|
+
def lookup(name, format)
|
42
|
+
View.cache.fetch_or_store(:lookup, name, format, config, prefixes) {
|
43
|
+
catch :found do
|
44
|
+
config.paths.reduce(nil) do |_, path|
|
45
|
+
prefixes.reduce(nil) do |_, prefix|
|
46
|
+
result = path.lookup(prefix, name, format)
|
47
|
+
throw :found, result if result
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
64
51
|
}
|
65
52
|
end
|
66
53
|
|
67
54
|
def name_for_partial(name)
|
68
|
-
|
69
|
-
|
55
|
+
segments = name.to_s.split(PATH_DELIMITER)
|
56
|
+
segments[-1] = "#{PARTIAL_PREFIX}#{segments[-1]}"
|
57
|
+
segments.join(PATH_DELIMITER)
|
58
|
+
end
|
59
|
+
|
60
|
+
def render(path, scope, &block)
|
61
|
+
tilt(path).render(scope, {locals: scope._locals}, &block).html_safe
|
70
62
|
end
|
71
63
|
|
72
64
|
def tilt(path)
|
73
|
-
fetch_or_store(:
|
74
|
-
Tilt[path,
|
65
|
+
View.cache.fetch_or_store(:tilt, path, config) {
|
66
|
+
Hanami::View::Tilt[path, config.renderer_engine_mapping, config.renderer_options]
|
75
67
|
}
|
76
68
|
end
|
77
69
|
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Hanami
|
4
|
+
class View
|
5
|
+
# @api private
|
6
|
+
class Rendering
|
7
|
+
attr_reader :config, :format
|
8
|
+
|
9
|
+
attr_reader :inflector, :part_builder, :scope_builder
|
10
|
+
|
11
|
+
attr_reader :context, :renderer
|
12
|
+
|
13
|
+
def initialize(config:, format:, context:)
|
14
|
+
@config = config
|
15
|
+
@format = format
|
16
|
+
|
17
|
+
@inflector = config.inflector
|
18
|
+
@part_builder = config.part_builder
|
19
|
+
@scope_builder = config.scope_builder
|
20
|
+
|
21
|
+
@context = context.dup_for_rendering(self)
|
22
|
+
@renderer = Renderer.new(config)
|
23
|
+
end
|
24
|
+
|
25
|
+
def template(name, scope, &block)
|
26
|
+
renderer.template(name, format, scope, &block)
|
27
|
+
end
|
28
|
+
|
29
|
+
def partial(name, scope, &block)
|
30
|
+
renderer.partial(name, format, scope, &block)
|
31
|
+
end
|
32
|
+
|
33
|
+
def part(name, value, as: nil)
|
34
|
+
part_builder.(name, value, as: as, rendering: self)
|
35
|
+
end
|
36
|
+
|
37
|
+
def scope(name = nil, locals) # rubocop:disable Style/OptionalArguments
|
38
|
+
scope_builder.(name, locals: locals, rendering: self)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -1,39 +1,34 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "dry/inflector"
|
4
|
+
require_relative "errors"
|
4
5
|
|
5
6
|
module Hanami
|
6
7
|
class View
|
7
8
|
# @api private
|
8
|
-
class
|
9
|
-
class MissingEnvironmentError < StandardError
|
10
|
-
def message
|
11
|
-
"a +render_env+ must be provided"
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
9
|
+
class RenderingMissing
|
15
10
|
def format
|
16
|
-
raise
|
11
|
+
raise RenderingMissingError
|
17
12
|
end
|
18
13
|
|
19
14
|
def context
|
20
|
-
raise
|
15
|
+
raise RenderingMissingError
|
21
16
|
end
|
22
17
|
|
23
18
|
def part(_name, _value, **_options)
|
24
|
-
raise
|
19
|
+
raise RenderingMissingError
|
25
20
|
end
|
26
21
|
|
27
22
|
def scope(_name = nil, _locals) # rubocop:disable Style/OptionalArguments
|
28
|
-
raise
|
23
|
+
raise RenderingMissingError
|
29
24
|
end
|
30
25
|
|
31
26
|
def template(_name, _scope)
|
32
|
-
raise
|
27
|
+
raise RenderingMissingError
|
33
28
|
end
|
34
29
|
|
35
30
|
def partial(_name, _scope)
|
36
|
-
raise
|
31
|
+
raise RenderingMissingError
|
37
32
|
end
|
38
33
|
|
39
34
|
def inflector
|
data/lib/hanami/view/scope.rb
CHANGED
@@ -2,7 +2,6 @@
|
|
2
2
|
|
3
3
|
require "dry/core/equalizer"
|
4
4
|
require "dry/core/constants"
|
5
|
-
require_relative "render_environment_missing"
|
6
5
|
|
7
6
|
module Hanami
|
8
7
|
class View
|
@@ -21,7 +20,7 @@ module Hanami
|
|
21
20
|
# @api private
|
22
21
|
CONVENIENCE_METHODS = %i[format context locals].freeze
|
23
22
|
|
24
|
-
include Dry::Equalizer(:_name, :_locals, :
|
23
|
+
include Dry::Equalizer(:_name, :_locals, :_rendering)
|
25
24
|
|
26
25
|
# The scope's name
|
27
26
|
#
|
@@ -43,18 +42,18 @@ module Hanami
|
|
43
42
|
# @api public
|
44
43
|
attr_reader :_locals
|
45
44
|
|
46
|
-
# The current
|
45
|
+
# The current rendering
|
47
46
|
#
|
48
|
-
# @return [
|
47
|
+
# @return [Rendering]
|
49
48
|
#
|
50
49
|
# @api private
|
51
|
-
attr_reader :
|
50
|
+
attr_reader :_rendering
|
52
51
|
|
53
52
|
# Returns a new Scope instance
|
54
53
|
#
|
55
54
|
# @param name [Symbol, nil] scope name
|
56
55
|
# @param locals [Hash<Symbol, Object>] template locals
|
57
|
-
# @param
|
56
|
+
# @param rendering [Rendering] the current rendering
|
58
57
|
#
|
59
58
|
# @return [Scope]
|
60
59
|
#
|
@@ -62,11 +61,11 @@ module Hanami
|
|
62
61
|
def initialize(
|
63
62
|
name: nil,
|
64
63
|
locals: Dry::Core::Constants::EMPTY_HASH,
|
65
|
-
|
64
|
+
rendering: RenderingMissing.new
|
66
65
|
)
|
67
66
|
@_name = name
|
68
67
|
@_locals = locals
|
69
|
-
@
|
68
|
+
@_rendering = rendering
|
70
69
|
end
|
71
70
|
|
72
71
|
# @overload render(partial_name, **locals, &block)
|
@@ -96,7 +95,7 @@ module Hanami
|
|
96
95
|
partial_name = _inflector.underscore(_inflector.demodulize(partial_name.to_s))
|
97
96
|
end
|
98
97
|
|
99
|
-
|
98
|
+
_rendering.partial(partial_name, _render_scope(**locals), &block)
|
100
99
|
end
|
101
100
|
|
102
101
|
# Build a new scope using a scope class matching the provided name
|
@@ -108,7 +107,7 @@ module Hanami
|
|
108
107
|
#
|
109
108
|
# @api public
|
110
109
|
def scope(name = nil, **locals)
|
111
|
-
|
110
|
+
_rendering.scope(name, locals)
|
112
111
|
end
|
113
112
|
|
114
113
|
# The template format for the current render environment.
|
@@ -123,7 +122,7 @@ module Hanami
|
|
123
122
|
#
|
124
123
|
# @api public
|
125
124
|
def _format
|
126
|
-
|
125
|
+
_rendering.format
|
127
126
|
end
|
128
127
|
|
129
128
|
# The context object for the current render environment
|
@@ -138,7 +137,7 @@ module Hanami
|
|
138
137
|
#
|
139
138
|
# @api public
|
140
139
|
def _context
|
141
|
-
|
140
|
+
_rendering.context
|
142
141
|
end
|
143
142
|
|
144
143
|
private
|
@@ -164,7 +163,7 @@ module Hanami
|
|
164
163
|
|
165
164
|
def respond_to_missing?(name, include_private = false)
|
166
165
|
_locals.key?(name) ||
|
167
|
-
|
166
|
+
_rendering.context.respond_to?(name) ||
|
168
167
|
CONVENIENCE_METHODS.include?(name) ||
|
169
168
|
super
|
170
169
|
end
|
@@ -176,13 +175,13 @@ module Hanami
|
|
176
175
|
self.class.new(
|
177
176
|
# FIXME: what about `name`?
|
178
177
|
locals: locals,
|
179
|
-
|
178
|
+
rendering: _rendering
|
180
179
|
)
|
181
180
|
end
|
182
181
|
end
|
183
182
|
|
184
183
|
def _inflector
|
185
|
-
|
184
|
+
_rendering.inflector
|
186
185
|
end
|
187
186
|
end
|
188
187
|
end
|
@@ -1,97 +1,61 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "dry/core/cache"
|
4
|
-
require "dry/core/equalizer"
|
5
|
-
require_relative "scope"
|
6
|
-
|
7
3
|
module Hanami
|
8
4
|
class View
|
9
5
|
# Builds scope objects via matching classes
|
10
6
|
#
|
11
7
|
# @api private
|
12
8
|
class ScopeBuilder
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
#
|
28
|
-
# @api private
|
29
|
-
def initialize(namespace: nil, render_env: nil)
|
30
|
-
@namespace = namespace
|
31
|
-
@render_env = render_env
|
32
|
-
end
|
33
|
-
|
34
|
-
# @api private
|
35
|
-
def for_render_env(render_env)
|
36
|
-
return self if render_env == self.render_env
|
37
|
-
|
38
|
-
self.class.new(namespace: namespace, render_env: render_env)
|
39
|
-
end
|
40
|
-
|
41
|
-
# Returns a new scope using a class matching the name
|
42
|
-
#
|
43
|
-
# @param name [Symbol, Class] scope name
|
44
|
-
# @param locals [Hash<Symbol, Object>] locals hash
|
45
|
-
#
|
46
|
-
# @return [Hanami::View::Scope]
|
47
|
-
#
|
48
|
-
# @api private
|
49
|
-
def call(name = nil, locals) # rubocop:disable Style/OptionalArguments
|
50
|
-
scope_class(name).new(
|
51
|
-
name: name,
|
52
|
-
locals: locals,
|
53
|
-
render_env: render_env
|
54
|
-
)
|
55
|
-
end
|
56
|
-
|
57
|
-
private
|
58
|
-
|
59
|
-
DEFAULT_SCOPE_CLASS = Scope
|
9
|
+
class << self
|
10
|
+
# Returns a new scope using a class matching the name
|
11
|
+
#
|
12
|
+
# @param name [Symbol, Class] scope name
|
13
|
+
# @param locals [Hash<Symbol, Object>] locals hash
|
14
|
+
#
|
15
|
+
# @return [Hanami::View::Scope]
|
16
|
+
#
|
17
|
+
# @api private
|
18
|
+
def call(name = nil, locals:, rendering:) # rubocop:disable Style/OptionalArguments
|
19
|
+
klass = scope_class(name, rendering: rendering)
|
20
|
+
|
21
|
+
klass.new(name: name, locals: locals, rendering: rendering)
|
22
|
+
end
|
60
23
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
24
|
+
private
|
25
|
+
|
26
|
+
def scope_class(name = nil, rendering:)
|
27
|
+
if name.nil?
|
28
|
+
rendering.config.scope_class
|
29
|
+
elsif name.is_a?(Class)
|
30
|
+
name
|
31
|
+
else
|
32
|
+
View.cache.fetch_or_store(:scope_class, rendering.config) do
|
33
|
+
resolve_scope_class(name: name, rendering: rendering)
|
34
|
+
end
|
69
35
|
end
|
70
36
|
end
|
71
|
-
end
|
72
37
|
|
73
|
-
|
74
|
-
|
38
|
+
def resolve_scope_class(name:, rendering:)
|
39
|
+
name = rendering.inflector.camelize(name.to_s)
|
75
40
|
|
76
|
-
|
77
|
-
begin
|
78
|
-
klass = namespace.const_get(name)
|
79
|
-
rescue NameError # rubocop:disable Lint/HandleExceptions
|
80
|
-
end
|
41
|
+
namespace = rendering.config.scope_namespace
|
81
42
|
|
82
|
-
|
83
|
-
|
84
|
-
|
43
|
+
# Give autoloaders a chance to act
|
44
|
+
begin
|
45
|
+
klass = namespace.const_get(name)
|
46
|
+
rescue NameError # rubocop:disable Lint/HandleExceptions
|
47
|
+
end
|
85
48
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
DEFAULT_SCOPE_CLASS
|
90
|
-
end
|
91
|
-
end
|
49
|
+
if !klass && namespace.const_defined?(name, false)
|
50
|
+
klass = namespace.const_get(name)
|
51
|
+
end
|
92
52
|
|
93
|
-
|
94
|
-
|
53
|
+
if klass && klass < Scope
|
54
|
+
klass
|
55
|
+
else
|
56
|
+
rendering.config.scope_class
|
57
|
+
end
|
58
|
+
end
|
95
59
|
end
|
96
60
|
end
|
97
61
|
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "haml"
|
4
|
+
|
5
|
+
module Hanami
|
6
|
+
class View
|
7
|
+
module Tilt
|
8
|
+
# @api private
|
9
|
+
module HamlAdapter
|
10
|
+
# Add options to Haml::Engine to match the options from its default generator.
|
11
|
+
#
|
12
|
+
# The default generator for Haml::Engine is configurable via an engine option, like so:
|
13
|
+
#
|
14
|
+
# use :Generator, -> { options[:generator] }
|
15
|
+
#
|
16
|
+
# Because this Temple filter is set as a proc, the resulting effect within Temple's EngineDSL
|
17
|
+
# is that the generator's valid options are not merged into the full set of options available
|
18
|
+
# on Haml::Engine itself. This means we receive a "Option :capture_generator is invalid"
|
19
|
+
# warning when we set our `capture_generator:` below.
|
20
|
+
#
|
21
|
+
# However, this option is perfectly valid, so here we merge all the options for Haml's default
|
22
|
+
# generator into the top-level engine's options, avoiding the warning.
|
23
|
+
::Haml::Engine.define_options(::Haml::Engine.options[:generator].options.valid_keys)
|
24
|
+
|
25
|
+
# Haml template renderer for Hanami::View.
|
26
|
+
#
|
27
|
+
# This differs from the standard Haml::Template by automatically escaping HTML based on a
|
28
|
+
# given string's `#html_safe?`, regardless of when "hanami/view/html" is required.
|
29
|
+
#
|
30
|
+
# @see Hanami::View::Tilt
|
31
|
+
# @api private
|
32
|
+
Template = Temple::Templates::Tilt(
|
33
|
+
::Haml::Engine,
|
34
|
+
use_html_safe: true,
|
35
|
+
capture_generator: HTMLSafeStringBuffer,
|
36
|
+
)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "slim"
|
4
|
+
|
5
|
+
module Hanami
|
6
|
+
class View
|
7
|
+
module Tilt
|
8
|
+
# @api private
|
9
|
+
module SlimAdapter
|
10
|
+
# Add options to Slim::Engine to match the options from its default generator.
|
11
|
+
#
|
12
|
+
# The default generator for Slim::Engine is configurable via an engine option, like so:
|
13
|
+
#
|
14
|
+
# use(:Generator) { options[:generator] }
|
15
|
+
#
|
16
|
+
# Because this Temple filter is set as a proc, the resulting effect within Temple's EngineDSL
|
17
|
+
# is that the generator's valid options are not merged into the full set of options available
|
18
|
+
# on Slim::Engine itself. This means we receive a "Option :capture_generator is invalid"
|
19
|
+
# warning when we set our `capture_generator:` below.
|
20
|
+
#
|
21
|
+
# However, this option is perfectly valid, so here we merge all the options for Slim's default
|
22
|
+
# generator into the top-level engine's options, avoiding the warning.
|
23
|
+
::Slim::Engine.define_options(::Slim::Engine.options[:generator].options.valid_keys)
|
24
|
+
|
25
|
+
# Slim template renderer for Hanami::View.
|
26
|
+
#
|
27
|
+
# This differs from the standard Slim::Template by automatically escaping HTML based on a
|
28
|
+
# given string's `#html_safe?`, regardless of when "hanami/view/html" is required.
|
29
|
+
#
|
30
|
+
# @see Hanami::View::Tilt
|
31
|
+
# @api private
|
32
|
+
Template = Temple::Templates::Tilt(
|
33
|
+
::Slim::Engine,
|
34
|
+
use_html_safe: true,
|
35
|
+
capture_generator: HTMLSafeStringBuffer,
|
36
|
+
)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|