actionview 6.0.0.beta1 → 6.1.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of actionview might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +206 -119
- data/MIT-LICENSE +1 -1
- data/README.rdoc +4 -2
- data/lib/action_view/base.rb +81 -15
- data/lib/action_view/cache_expiry.rb +52 -0
- data/lib/action_view/context.rb +0 -6
- data/lib/action_view/dependency_tracker.rb +10 -4
- data/lib/action_view/digestor.rb +11 -19
- data/lib/action_view/flows.rb +0 -1
- data/lib/action_view/gem_version.rb +2 -2
- data/lib/action_view/helpers/active_model_helper.rb +0 -1
- data/lib/action_view/helpers/asset_tag_helper.rb +46 -21
- data/lib/action_view/helpers/asset_url_helper.rb +6 -4
- data/lib/action_view/helpers/atom_feed_helper.rb +2 -1
- data/lib/action_view/helpers/cache_helper.rb +16 -23
- data/lib/action_view/helpers/csp_helper.rb +4 -2
- data/lib/action_view/helpers/date_helper.rb +5 -6
- data/lib/action_view/helpers/form_helper.rb +63 -21
- data/lib/action_view/helpers/form_options_helper.rb +10 -18
- data/lib/action_view/helpers/form_tag_helper.rb +12 -9
- data/lib/action_view/helpers/javascript_helper.rb +7 -5
- data/lib/action_view/helpers/number_helper.rb +9 -8
- data/lib/action_view/helpers/output_safety_helper.rb +1 -1
- data/lib/action_view/helpers/rendering_helper.rb +17 -7
- data/lib/action_view/helpers/sanitize_helper.rb +10 -16
- data/lib/action_view/helpers/tag_helper.rb +94 -19
- data/lib/action_view/helpers/tags/base.rb +10 -7
- data/lib/action_view/helpers/tags/check_box.rb +0 -1
- data/lib/action_view/helpers/tags/collection_check_boxes.rb +0 -1
- data/lib/action_view/helpers/tags/collection_helpers.rb +0 -1
- data/lib/action_view/helpers/tags/collection_radio_buttons.rb +0 -1
- data/lib/action_view/helpers/tags/color_field.rb +0 -1
- data/lib/action_view/helpers/tags/date_field.rb +1 -2
- data/lib/action_view/helpers/tags/date_select.rb +2 -3
- data/lib/action_view/helpers/tags/datetime_field.rb +0 -1
- data/lib/action_view/helpers/tags/datetime_local_field.rb +1 -2
- data/lib/action_view/helpers/tags/label.rb +4 -1
- data/lib/action_view/helpers/tags/month_field.rb +1 -2
- data/lib/action_view/helpers/tags/radio_button.rb +0 -1
- data/lib/action_view/helpers/tags/select.rb +1 -2
- data/lib/action_view/helpers/tags/text_field.rb +0 -1
- data/lib/action_view/helpers/tags/time_field.rb +1 -2
- data/lib/action_view/helpers/tags/week_field.rb +1 -2
- data/lib/action_view/helpers/text_helper.rb +1 -2
- data/lib/action_view/helpers/translation_helper.rb +99 -54
- data/lib/action_view/helpers/url_helper.rb +109 -15
- data/lib/action_view/layouts.rb +8 -10
- data/lib/action_view/log_subscriber.rb +26 -11
- data/lib/action_view/lookup_context.rb +59 -31
- data/lib/action_view/path_set.rb +3 -12
- data/lib/action_view/railtie.rb +36 -42
- data/lib/action_view/record_identifier.rb +0 -1
- data/lib/action_view/renderer/abstract_renderer.rb +142 -11
- data/lib/action_view/renderer/collection_renderer.rb +192 -0
- data/lib/action_view/renderer/object_renderer.rb +34 -0
- data/lib/action_view/renderer/partial_renderer/collection_caching.rb +35 -29
- data/lib/action_view/renderer/partial_renderer.rb +21 -273
- data/lib/action_view/renderer/renderer.rb +59 -4
- data/lib/action_view/renderer/streaming_template_renderer.rb +9 -7
- data/lib/action_view/renderer/template_renderer.rb +35 -27
- data/lib/action_view/rendering.rb +49 -29
- data/lib/action_view/routing_url_for.rb +1 -1
- data/lib/action_view/template/error.rb +30 -15
- data/lib/action_view/template/handlers/builder.rb +2 -2
- data/lib/action_view/template/handlers/erb/erubi.rb +15 -9
- data/lib/action_view/template/handlers/erb.rb +14 -19
- data/lib/action_view/template/handlers/html.rb +1 -1
- data/lib/action_view/template/handlers/raw.rb +2 -2
- data/lib/action_view/template/handlers.rb +1 -1
- data/lib/action_view/template/html.rb +5 -6
- data/lib/action_view/template/inline.rb +22 -0
- data/lib/action_view/template/raw_file.rb +25 -0
- data/lib/action_view/template/renderable.rb +24 -0
- data/lib/action_view/template/resolver.rb +141 -140
- data/lib/action_view/template/sources/file.rb +17 -0
- data/lib/action_view/template/sources.rb +13 -0
- data/lib/action_view/template/text.rb +2 -3
- data/lib/action_view/template.rb +49 -75
- data/lib/action_view/test_case.rb +20 -28
- data/lib/action_view/testing/resolvers.rb +18 -27
- data/lib/action_view/unbound_template.rb +31 -0
- data/lib/action_view/view_paths.rb +59 -38
- data/lib/action_view.rb +7 -2
- data/lib/assets/compiled/rails-ujs.js +22 -13
- metadata +30 -18
@@ -26,7 +26,14 @@ module ActionView
|
|
26
26
|
extend ActiveSupport::Concern
|
27
27
|
include ActionView::ViewPaths
|
28
28
|
|
29
|
-
|
29
|
+
attr_reader :rendered_format
|
30
|
+
|
31
|
+
def initialize
|
32
|
+
@rendered_format = nil
|
33
|
+
super
|
34
|
+
end
|
35
|
+
|
36
|
+
# Overwrite process to set up I18n proxy.
|
30
37
|
def process(*) #:nodoc:
|
31
38
|
old_config, I18n.config = I18n.config, I18nProxy.new(I18n.config, lookup_context)
|
32
39
|
super
|
@@ -35,30 +42,40 @@ module ActionView
|
|
35
42
|
end
|
36
43
|
|
37
44
|
module ClassMethods
|
38
|
-
def
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
45
|
+
def _routes
|
46
|
+
end
|
47
|
+
|
48
|
+
def _helpers
|
49
|
+
end
|
50
|
+
|
51
|
+
def build_view_context_class(klass, supports_path, routes, helpers)
|
52
|
+
Class.new(klass) do
|
53
|
+
if routes
|
54
|
+
include routes.url_helpers(supports_path)
|
55
|
+
include routes.mounted_helpers
|
56
|
+
end
|
57
|
+
|
58
|
+
if helpers
|
59
|
+
include helpers
|
53
60
|
end
|
54
61
|
end
|
55
62
|
end
|
56
|
-
end
|
57
63
|
|
58
|
-
|
64
|
+
def view_context_class
|
65
|
+
klass = ActionView::LookupContext::DetailsKey.view_context_class(ActionView::Base)
|
66
|
+
|
67
|
+
@view_context_class ||= build_view_context_class(klass, supports_path?, _routes, _helpers)
|
68
|
+
|
69
|
+
if klass.changed?(@view_context_class)
|
70
|
+
@view_context_class = build_view_context_class(klass, supports_path?, _routes, _helpers)
|
71
|
+
end
|
72
|
+
|
73
|
+
@view_context_class
|
74
|
+
end
|
75
|
+
end
|
59
76
|
|
60
77
|
def view_context_class
|
61
|
-
|
78
|
+
self.class.view_context_class
|
62
79
|
end
|
63
80
|
|
64
81
|
# An instance of a view class. The default view class is ActionView::Base.
|
@@ -72,11 +89,12 @@ module ActionView
|
|
72
89
|
#
|
73
90
|
# Override this method in a module to change the default behavior.
|
74
91
|
def view_context
|
75
|
-
view_context_class.new(
|
92
|
+
view_context_class.new(lookup_context, view_assigns, self)
|
76
93
|
end
|
77
94
|
|
78
95
|
# Returns an object that is able to render templates.
|
79
96
|
def view_renderer # :nodoc:
|
97
|
+
# Lifespan: Per controller
|
80
98
|
@_view_renderer ||= ActionView::Renderer.new(lookup_context)
|
81
99
|
end
|
82
100
|
|
@@ -85,12 +103,7 @@ module ActionView
|
|
85
103
|
_render_template(options)
|
86
104
|
end
|
87
105
|
|
88
|
-
def rendered_format
|
89
|
-
Template::Types[lookup_context.rendered_format]
|
90
|
-
end
|
91
|
-
|
92
106
|
private
|
93
|
-
|
94
107
|
# Find and render a template based on the options given.
|
95
108
|
def _render_template(options)
|
96
109
|
variant = options.delete(:variant)
|
@@ -98,17 +111,22 @@ module ActionView
|
|
98
111
|
context = view_context
|
99
112
|
|
100
113
|
context.assign assigns if assigns
|
101
|
-
lookup_context.rendered_format = nil if options[:formats]
|
102
114
|
lookup_context.variants = variant if variant
|
103
115
|
|
104
|
-
|
116
|
+
rendered_template = context.in_rendering_context(options) do |renderer|
|
117
|
+
renderer.render_to_object(context, options)
|
118
|
+
end
|
119
|
+
|
120
|
+
rendered_format = rendered_template.format || lookup_context.formats.first
|
121
|
+
@rendered_format = Template::Types[rendered_format]
|
122
|
+
|
123
|
+
rendered_template.body
|
105
124
|
end
|
106
125
|
|
107
126
|
# Assign the rendered format to look up context.
|
108
127
|
def _process_format(format)
|
109
128
|
super
|
110
|
-
lookup_context.formats = [format.to_sym]
|
111
|
-
lookup_context.rendered_format = lookup_context.formats.first
|
129
|
+
lookup_context.formats = [format.to_sym] if format.to_sym
|
112
130
|
end
|
113
131
|
|
114
132
|
# Normalize args by converting render "foo" to render :action => "foo" and
|
@@ -126,6 +144,8 @@ module ActionView
|
|
126
144
|
else
|
127
145
|
if action.respond_to?(:permitted?) && action.permitted?
|
128
146
|
options = action
|
147
|
+
elsif action.respond_to?(:render_in)
|
148
|
+
options[:renderable] = action
|
129
149
|
else
|
130
150
|
options[:partial] = action
|
131
151
|
end
|
@@ -105,7 +105,7 @@ module ActionView
|
|
105
105
|
end
|
106
106
|
else
|
107
107
|
method = _generate_paths_by_default ? :path : :url
|
108
|
-
builder = ActionDispatch::Routing::PolymorphicRoutes::HelperMethodBuilder.
|
108
|
+
builder = ActionDispatch::Routing::PolymorphicRoutes::HelperMethodBuilder.public_send(method)
|
109
109
|
|
110
110
|
case options
|
111
111
|
when Symbol
|
@@ -81,19 +81,19 @@ module ActionView
|
|
81
81
|
end
|
82
82
|
end
|
83
83
|
|
84
|
-
def source_extract(indentation = 0
|
85
|
-
return unless num = line_number
|
84
|
+
def source_extract(indentation = 0)
|
85
|
+
return [] unless num = line_number
|
86
86
|
num = num.to_i
|
87
87
|
|
88
|
-
source_code = @template.
|
88
|
+
source_code = @template.encode!.split("\n")
|
89
89
|
|
90
90
|
start_on_line = [ num - SOURCE_CODE_RADIUS - 1, 0 ].max
|
91
91
|
end_on_line = [ num + SOURCE_CODE_RADIUS - 1, source_code.length].min
|
92
92
|
|
93
93
|
indent = end_on_line.to_s.size + indentation
|
94
|
-
return unless source_code = source_code[start_on_line..end_on_line]
|
94
|
+
return [] unless source_code = source_code[start_on_line..end_on_line]
|
95
95
|
|
96
|
-
formatted_code_for(source_code, start_on_line, indent
|
96
|
+
formatted_code_for(source_code, start_on_line, indent)
|
97
97
|
end
|
98
98
|
|
99
99
|
def sub_template_of(template_path)
|
@@ -109,12 +109,11 @@ module ActionView
|
|
109
109
|
end
|
110
110
|
end
|
111
111
|
|
112
|
-
def
|
112
|
+
def annotated_source_code
|
113
113
|
source_extract(4)
|
114
114
|
end
|
115
115
|
|
116
116
|
private
|
117
|
-
|
118
117
|
def source_location
|
119
118
|
if line_number
|
120
119
|
"on line ##{line_number} of "
|
@@ -123,19 +122,35 @@ module ActionView
|
|
123
122
|
end + file_name
|
124
123
|
end
|
125
124
|
|
126
|
-
def formatted_code_for(source_code, line_counter, indent
|
127
|
-
|
128
|
-
source_code.
|
125
|
+
def formatted_code_for(source_code, line_counter, indent)
|
126
|
+
indent_template = "%#{indent}s: %s"
|
127
|
+
source_code.map do |line|
|
129
128
|
line_counter += 1
|
130
|
-
|
131
|
-
result.update(line_counter.to_s => "%#{indent}s %s\n" % ["", line])
|
132
|
-
else
|
133
|
-
result << "%#{indent}s: %s" % [line_counter, line]
|
134
|
-
end
|
129
|
+
indent_template % [line_counter, line]
|
135
130
|
end
|
136
131
|
end
|
137
132
|
end
|
138
133
|
end
|
139
134
|
|
140
135
|
TemplateError = Template::Error
|
136
|
+
|
137
|
+
class SyntaxErrorInTemplate < TemplateError #:nodoc
|
138
|
+
def initialize(template, offending_code_string)
|
139
|
+
@offending_code_string = offending_code_string
|
140
|
+
super(template)
|
141
|
+
end
|
142
|
+
|
143
|
+
def message
|
144
|
+
<<~MESSAGE
|
145
|
+
Encountered a syntax error while rendering template: check #{@offending_code_string}
|
146
|
+
MESSAGE
|
147
|
+
end
|
148
|
+
|
149
|
+
def annotated_source_code
|
150
|
+
@offending_code_string.split("\n").map.with_index(1) { |line, index|
|
151
|
+
indentation = " " * 4
|
152
|
+
"#{index}:#{indentation}#{line}"
|
153
|
+
}
|
154
|
+
end
|
155
|
+
end
|
141
156
|
end
|
@@ -5,11 +5,11 @@ module ActionView
|
|
5
5
|
class Builder
|
6
6
|
class_attribute :default_format, default: :xml
|
7
7
|
|
8
|
-
def call(template)
|
8
|
+
def call(template, source)
|
9
9
|
require_engine
|
10
10
|
"xml = ::Builder::XmlMarkup.new(:indent => 2);" \
|
11
11
|
"self.output_buffer = xml.target!;" +
|
12
|
-
|
12
|
+
source +
|
13
13
|
";xml.target!;"
|
14
14
|
end
|
15
15
|
|
@@ -13,17 +13,23 @@ module ActionView
|
|
13
13
|
|
14
14
|
# Dup properties so that we don't modify argument
|
15
15
|
properties = Hash[properties]
|
16
|
-
|
17
|
-
properties[:
|
18
|
-
properties[:
|
16
|
+
|
17
|
+
properties[:bufvar] ||= "@output_buffer"
|
18
|
+
properties[:preamble] ||= ""
|
19
|
+
properties[:postamble] ||= "#{properties[:bufvar]}.to_s"
|
20
|
+
|
19
21
|
properties[:escapefunc] = ""
|
20
22
|
|
21
23
|
super
|
22
24
|
end
|
23
25
|
|
24
26
|
def evaluate(action_view_erb_handler_context)
|
25
|
-
|
26
|
-
|
27
|
+
src = @src
|
28
|
+
view = Class.new(ActionView::Base) {
|
29
|
+
include action_view_erb_handler_context._routes.url_helpers
|
30
|
+
class_eval("define_method(:_template) { |local_assigns, output_buffer| #{src} }", defined?(@filename) ? @filename : "(erubi)", 0)
|
31
|
+
}.empty
|
32
|
+
view._run(:_template, nil, {}, ActionView::OutputBuffer.new)
|
27
33
|
end
|
28
34
|
|
29
35
|
private
|
@@ -33,7 +39,7 @@ module ActionView
|
|
33
39
|
if text == "\n"
|
34
40
|
@newline_pending += 1
|
35
41
|
else
|
36
|
-
src << "
|
42
|
+
src << bufvar << ".safe_append='"
|
37
43
|
src << "\n" * @newline_pending if @newline_pending > 0
|
38
44
|
src << text.gsub(/['\\]/, '\\\\\&')
|
39
45
|
src << "'.freeze;"
|
@@ -48,9 +54,9 @@ module ActionView
|
|
48
54
|
flush_newline_if_pending(src)
|
49
55
|
|
50
56
|
if (indicator == "==") || @escape
|
51
|
-
src << "
|
57
|
+
src << bufvar << ".safe_expr_append="
|
52
58
|
else
|
53
|
-
src << "
|
59
|
+
src << bufvar << ".append="
|
54
60
|
end
|
55
61
|
|
56
62
|
if BLOCK_EXPR.match?(code)
|
@@ -72,7 +78,7 @@ module ActionView
|
|
72
78
|
|
73
79
|
def flush_newline_if_pending(src)
|
74
80
|
if @newline_pending > 0
|
75
|
-
src << "
|
81
|
+
src << bufvar << ".safe_append='#{"\n" * @newline_pending}'.freeze;"
|
76
82
|
@newline_pending = 0
|
77
83
|
end
|
78
84
|
end
|
@@ -16,20 +16,10 @@ module ActionView
|
|
16
16
|
# Do not escape templates of these mime types.
|
17
17
|
class_attribute :escape_ignore_list, default: ["text/plain"]
|
18
18
|
|
19
|
-
[self, singleton_class].each do |base|
|
20
|
-
base.alias_method :escape_whitelist, :escape_ignore_list
|
21
|
-
base.alias_method :escape_whitelist=, :escape_ignore_list=
|
22
|
-
|
23
|
-
base.deprecate(
|
24
|
-
escape_whitelist: "use #escape_ignore_list instead",
|
25
|
-
:escape_whitelist= => "use #escape_ignore_list= instead"
|
26
|
-
)
|
27
|
-
end
|
28
|
-
|
29
19
|
ENCODING_TAG = Regexp.new("\\A(<%#{ENCODING_FLAG}-?%>)[ \\t]*")
|
30
20
|
|
31
|
-
def self.call(template)
|
32
|
-
new.call(template)
|
21
|
+
def self.call(template, source)
|
22
|
+
new.call(template, source)
|
33
23
|
end
|
34
24
|
|
35
25
|
def supports_streaming?
|
@@ -40,30 +30,35 @@ module ActionView
|
|
40
30
|
true
|
41
31
|
end
|
42
32
|
|
43
|
-
def call(template)
|
33
|
+
def call(template, source)
|
44
34
|
# First, convert to BINARY, so in case the encoding is
|
45
35
|
# wrong, we can still find an encoding tag
|
46
36
|
# (<%# encoding %>) inside the String using a regular
|
47
37
|
# expression
|
48
|
-
template_source =
|
38
|
+
template_source = source.b
|
49
39
|
|
50
40
|
erb = template_source.gsub(ENCODING_TAG, "")
|
51
41
|
encoding = $2
|
52
42
|
|
53
|
-
erb.force_encoding valid_encoding(
|
43
|
+
erb.force_encoding valid_encoding(source.dup, encoding)
|
54
44
|
|
55
45
|
# Always make sure we return a String in the default_internal
|
56
46
|
erb.encode!
|
57
47
|
|
58
|
-
|
59
|
-
erb,
|
48
|
+
options = {
|
60
49
|
escape: (self.class.escape_ignore_list.include? template.type),
|
61
50
|
trim: (self.class.erb_trim_mode == "-")
|
62
|
-
|
51
|
+
}
|
52
|
+
|
53
|
+
if ActionView::Base.annotate_rendered_view_with_filenames && template.format == :html
|
54
|
+
options[:preamble] = "@output_buffer.safe_append='<!-- BEGIN #{template.short_identifier} -->';"
|
55
|
+
options[:postamble] = "@output_buffer.safe_append='<!-- END #{template.short_identifier} -->';@output_buffer.to_s"
|
56
|
+
end
|
57
|
+
|
58
|
+
self.class.erb_implementation.new(erb, options).src
|
63
59
|
end
|
64
60
|
|
65
61
|
private
|
66
|
-
|
67
62
|
def valid_encoding(string, encoding)
|
68
63
|
# If a magic encoding comment was found, tag the
|
69
64
|
# String with this encoding. This is for a case
|
@@ -14,7 +14,7 @@ module ActionView #:nodoc:
|
|
14
14
|
base.register_template_handler :erb, ERB.new
|
15
15
|
base.register_template_handler :html, Html.new
|
16
16
|
base.register_template_handler :builder, Builder.new
|
17
|
-
base.register_template_handler :ruby,
|
17
|
+
base.register_template_handler :ruby, lambda { |_, source| source }
|
18
18
|
end
|
19
19
|
|
20
20
|
@@template_handlers = {}
|
@@ -4,12 +4,11 @@ module ActionView #:nodoc:
|
|
4
4
|
# = Action View HTML Template
|
5
5
|
class Template #:nodoc:
|
6
6
|
class HTML #:nodoc:
|
7
|
-
|
7
|
+
attr_reader :type
|
8
8
|
|
9
|
-
def initialize(string, type
|
9
|
+
def initialize(string, type)
|
10
10
|
@string = string.to_s
|
11
|
-
@type =
|
12
|
-
@type ||= Types[:html]
|
11
|
+
@type = type
|
13
12
|
end
|
14
13
|
|
15
14
|
def identifier
|
@@ -26,8 +25,8 @@ module ActionView #:nodoc:
|
|
26
25
|
to_str
|
27
26
|
end
|
28
27
|
|
29
|
-
def
|
30
|
-
|
28
|
+
def format
|
29
|
+
@type
|
31
30
|
end
|
32
31
|
end
|
33
32
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActionView #:nodoc:
|
4
|
+
class Template #:nodoc:
|
5
|
+
class Inline < Template #:nodoc:
|
6
|
+
# This finalizer is needed (and exactly with a proc inside another proc)
|
7
|
+
# otherwise templates leak in development.
|
8
|
+
Finalizer = proc do |method_name, mod| # :nodoc:
|
9
|
+
proc do
|
10
|
+
mod.module_eval do
|
11
|
+
remove_possible_method method_name
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def compile(mod)
|
17
|
+
super
|
18
|
+
ObjectSpace.define_finalizer(self, Finalizer[method_name, mod])
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActionView #:nodoc:
|
4
|
+
# = Action View RawFile Template
|
5
|
+
class Template #:nodoc:
|
6
|
+
class RawFile #:nodoc:
|
7
|
+
attr_accessor :type, :format
|
8
|
+
|
9
|
+
def initialize(filename)
|
10
|
+
@filename = filename.to_s
|
11
|
+
extname = ::File.extname(filename).delete(".")
|
12
|
+
@type = Template::Types[extname] || Template::Types[:text]
|
13
|
+
@format = @type.symbol
|
14
|
+
end
|
15
|
+
|
16
|
+
def identifier
|
17
|
+
@filename
|
18
|
+
end
|
19
|
+
|
20
|
+
def render(*args)
|
21
|
+
::File.read(@filename)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActionView
|
4
|
+
# = Action View Renderable Template for objects that respond to #render_in
|
5
|
+
class Template
|
6
|
+
class Renderable # :nodoc:
|
7
|
+
def initialize(renderable)
|
8
|
+
@renderable = renderable
|
9
|
+
end
|
10
|
+
|
11
|
+
def identifier
|
12
|
+
@renderable.class.name
|
13
|
+
end
|
14
|
+
|
15
|
+
def render(context, *args)
|
16
|
+
@renderable.render_in(context)
|
17
|
+
end
|
18
|
+
|
19
|
+
def format
|
20
|
+
@renderable.format
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|