actionview 6.0.0.beta1 → 6.0.0.beta2
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 +28 -3
- data/lib/action_view.rb +1 -1
- data/lib/action_view/base.rb +107 -10
- data/lib/action_view/context.rb +0 -5
- data/lib/action_view/digestor.rb +4 -8
- data/lib/action_view/file_template.rb +33 -0
- data/lib/action_view/gem_version.rb +1 -1
- data/lib/action_view/helpers/asset_tag_helper.rb +5 -5
- data/lib/action_view/helpers/cache_helper.rb +5 -5
- data/lib/action_view/helpers/csp_helper.rb +4 -2
- data/lib/action_view/helpers/rendering_helper.rb +6 -4
- data/lib/action_view/helpers/tags/base.rb +1 -1
- data/lib/action_view/helpers/translation_helper.rb +1 -1
- data/lib/action_view/layouts.rb +5 -5
- data/lib/action_view/lookup_context.rb +59 -24
- data/lib/action_view/railtie.rb +8 -3
- data/lib/action_view/renderer/abstract_renderer.rb +56 -3
- data/lib/action_view/renderer/partial_renderer.rb +66 -52
- data/lib/action_view/renderer/partial_renderer/collection_caching.rb +14 -14
- data/lib/action_view/renderer/renderer.rb +16 -4
- data/lib/action_view/renderer/streaming_template_renderer.rb +3 -3
- data/lib/action_view/renderer/template_renderer.rb +18 -18
- data/lib/action_view/rendering.rb +44 -26
- data/lib/action_view/template.rb +58 -36
- data/lib/action_view/template/handlers.rb +27 -1
- data/lib/action_view/template/handlers/builder.rb +2 -2
- data/lib/action_view/template/handlers/erb.rb +5 -5
- data/lib/action_view/template/handlers/erb/erubi.rb +7 -3
- 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/html.rb +14 -5
- data/lib/action_view/template/inline.rb +22 -0
- data/lib/action_view/template/resolver.rb +14 -7
- data/lib/action_view/template/text.rb +5 -3
- data/lib/action_view/testing/resolvers.rb +6 -4
- data/lib/action_view/view_paths.rb +25 -1
- metadata +12 -10
@@ -11,13 +11,13 @@ module ActionView
|
|
11
11
|
end
|
12
12
|
|
13
13
|
private
|
14
|
-
def cache_collection_render(instrumentation_payload)
|
14
|
+
def cache_collection_render(instrumentation_payload, view, template)
|
15
15
|
return yield unless @options[:cached]
|
16
16
|
|
17
17
|
# Result is a hash with the key represents the
|
18
18
|
# key used for cache lookup and the value is the item
|
19
19
|
# on which the partial is being rendered
|
20
|
-
keyed_collection = collection_by_cache_keys
|
20
|
+
keyed_collection = collection_by_cache_keys(view, template)
|
21
21
|
|
22
22
|
# Pull all partials from cache
|
23
23
|
# Result is a hash, key matches the entry in
|
@@ -40,7 +40,7 @@ module ActionView
|
|
40
40
|
rendered_partials = @collection.empty? ? [] : yield
|
41
41
|
|
42
42
|
index = 0
|
43
|
-
fetch_or_cache_partial(cached_partials, order_by: keyed_collection.each_key) do
|
43
|
+
fetch_or_cache_partial(cached_partials, template, order_by: keyed_collection.each_key) do
|
44
44
|
# This block is called once
|
45
45
|
# for every cache miss while preserving order.
|
46
46
|
rendered_partials[index].tap { index += 1 }
|
@@ -51,23 +51,21 @@ module ActionView
|
|
51
51
|
@options[:cached].respond_to?(:call)
|
52
52
|
end
|
53
53
|
|
54
|
-
def collection_by_cache_keys
|
54
|
+
def collection_by_cache_keys(view, template)
|
55
55
|
seed = callable_cache_key? ? @options[:cached] : ->(i) { i }
|
56
56
|
|
57
|
+
digest_path = view.digest_path_from_template(template)
|
58
|
+
|
57
59
|
@collection.each_with_object({}) do |item, hash|
|
58
|
-
hash[expanded_cache_key(seed.call(item))] = item
|
60
|
+
hash[expanded_cache_key(seed.call(item), view, template, digest_path)] = item
|
59
61
|
end
|
60
62
|
end
|
61
63
|
|
62
|
-
def expanded_cache_key(key)
|
63
|
-
key =
|
64
|
+
def expanded_cache_key(key, view, template, digest_path)
|
65
|
+
key = view.combined_fragment_cache_key(view.cache_fragment_name(key, virtual_path: template.virtual_path, digest_path: digest_path))
|
64
66
|
key.frozen? ? key.dup : key # #read_multi & #write may require mutability, Dalli 2.6.0.
|
65
67
|
end
|
66
68
|
|
67
|
-
def digest_path
|
68
|
-
@digest_path ||= @view.digest_path_from_virtual(@template.virtual_path)
|
69
|
-
end
|
70
|
-
|
71
69
|
# `order_by` is an enumerable object containing keys of the cache,
|
72
70
|
# all keys are passed in whether found already or not.
|
73
71
|
#
|
@@ -83,11 +81,13 @@ module ActionView
|
|
83
81
|
#
|
84
82
|
# If the partial is not already cached it will also be
|
85
83
|
# written back to the underlying cache store.
|
86
|
-
def fetch_or_cache_partial(cached_partials, order_by:)
|
84
|
+
def fetch_or_cache_partial(cached_partials, template, order_by:)
|
87
85
|
order_by.map do |cache_key|
|
88
|
-
cached_partials
|
86
|
+
if content = cached_partials[cache_key]
|
87
|
+
build_rendered_template(content, template)
|
88
|
+
else
|
89
89
|
yield.tap do |rendered_partial|
|
90
|
-
collection_cache.write(cache_key, rendered_partial)
|
90
|
+
collection_cache.write(cache_key, rendered_partial.body)
|
91
91
|
end
|
92
92
|
end
|
93
93
|
end
|
@@ -19,10 +19,14 @@ module ActionView
|
|
19
19
|
|
20
20
|
# Main render entry point shared by Action View and Action Controller.
|
21
21
|
def render(context, options)
|
22
|
+
render_to_object(context, options).body
|
23
|
+
end
|
24
|
+
|
25
|
+
def render_to_object(context, options) # :nodoc:
|
22
26
|
if options.key?(:partial)
|
23
|
-
|
27
|
+
render_partial_to_object(context, options)
|
24
28
|
else
|
25
|
-
|
29
|
+
render_template_to_object(context, options)
|
26
30
|
end
|
27
31
|
end
|
28
32
|
|
@@ -41,16 +45,24 @@ module ActionView
|
|
41
45
|
|
42
46
|
# Direct access to template rendering.
|
43
47
|
def render_template(context, options) #:nodoc:
|
44
|
-
|
48
|
+
render_template_to_object(context, options).body
|
45
49
|
end
|
46
50
|
|
47
51
|
# Direct access to partial rendering.
|
48
52
|
def render_partial(context, options, &block) #:nodoc:
|
49
|
-
|
53
|
+
render_partial_to_object(context, options, &block).body
|
50
54
|
end
|
51
55
|
|
52
56
|
def cache_hits # :nodoc:
|
53
57
|
@cache_hits ||= {}
|
54
58
|
end
|
59
|
+
|
60
|
+
def render_template_to_object(context, options) #:nodoc:
|
61
|
+
TemplateRenderer.new(@lookup_context).render(context, options)
|
62
|
+
end
|
63
|
+
|
64
|
+
def render_partial_to_object(context, options, &block) #:nodoc:
|
65
|
+
PartialRenderer.new(@lookup_context).render(context, options, block)
|
66
|
+
end
|
55
67
|
end
|
56
68
|
end
|
@@ -43,14 +43,14 @@ module ActionView
|
|
43
43
|
# For streaming, instead of rendering a given a template, we return a Body
|
44
44
|
# object that responds to each. This object is initialized with a block
|
45
45
|
# that knows how to render the template.
|
46
|
-
def render_template(template, layout_name = nil, locals = {}) #:nodoc:
|
47
|
-
return [super] unless layout_name && template.supports_streaming?
|
46
|
+
def render_template(view, template, layout_name = nil, locals = {}) #:nodoc:
|
47
|
+
return [super.body] unless layout_name && template.supports_streaming?
|
48
48
|
|
49
49
|
locals ||= {}
|
50
50
|
layout = layout_name && find_layout(layout_name, locals.keys, [formats.first])
|
51
51
|
|
52
52
|
Body.new do |buffer|
|
53
|
-
delayed_render(buffer, template, layout,
|
53
|
+
delayed_render(buffer, template, layout, view, locals)
|
54
54
|
end
|
55
55
|
end
|
56
56
|
|
@@ -5,15 +5,12 @@ require "active_support/core_ext/object/try"
|
|
5
5
|
module ActionView
|
6
6
|
class TemplateRenderer < AbstractRenderer #:nodoc:
|
7
7
|
def render(context, options)
|
8
|
-
@view = context
|
9
8
|
@details = extract_details(options)
|
10
9
|
template = determine_template(options)
|
11
10
|
|
12
|
-
prepend_formats(template.
|
11
|
+
prepend_formats(template.format)
|
13
12
|
|
14
|
-
|
15
|
-
|
16
|
-
render_template(template, options[:layout], options[:locals])
|
13
|
+
render_template(context, template, options[:layout], options[:locals] || {})
|
17
14
|
end
|
18
15
|
|
19
16
|
private
|
@@ -29,15 +26,20 @@ module ActionView
|
|
29
26
|
elsif options.key?(:html)
|
30
27
|
Template::HTML.new(options[:html], formats.first)
|
31
28
|
elsif options.key?(:file)
|
32
|
-
with_fallbacks
|
29
|
+
@lookup_context.with_fallbacks.find_file(options[:file], nil, false, keys, @details)
|
33
30
|
elsif options.key?(:inline)
|
34
31
|
handler = Template.handler_for_extension(options[:type] || "erb")
|
35
|
-
|
32
|
+
format = if handler.respond_to?(:default_format)
|
33
|
+
handler.default_format
|
34
|
+
else
|
35
|
+
@lookup_context.formats.first
|
36
|
+
end
|
37
|
+
Template::Inline.new(options[:inline], "inline template", handler, locals: keys, format: format)
|
36
38
|
elsif options.key?(:template)
|
37
39
|
if options[:template].respond_to?(:render)
|
38
40
|
options[:template]
|
39
41
|
else
|
40
|
-
find_template(options[:template], options[:prefixes], false, keys, @details)
|
42
|
+
@lookup_context.find_template(options[:template], options[:prefixes], false, keys, @details)
|
41
43
|
end
|
42
44
|
else
|
43
45
|
raise ArgumentError, "You invoked render but did not give any of :partial, :template, :inline, :file, :plain, :html or :body option."
|
@@ -46,27 +48,25 @@ module ActionView
|
|
46
48
|
|
47
49
|
# Renders the given template. A string representing the layout can be
|
48
50
|
# supplied as well.
|
49
|
-
def render_template(template, layout_name
|
50
|
-
view,
|
51
|
-
|
52
|
-
render_with_layout(layout_name, locals) do |layout|
|
51
|
+
def render_template(view, template, layout_name, locals)
|
52
|
+
render_with_layout(view, layout_name, template, locals) do |layout|
|
53
53
|
instrument(:template, identifier: template.identifier, layout: layout.try(:virtual_path)) do
|
54
54
|
template.render(view, locals) { |*name| view._layout_for(*name) }
|
55
55
|
end
|
56
56
|
end
|
57
57
|
end
|
58
58
|
|
59
|
-
def render_with_layout(path, locals)
|
59
|
+
def render_with_layout(view, path, template, locals)
|
60
60
|
layout = path && find_layout(path, locals.keys, [formats.first])
|
61
61
|
content = yield(layout)
|
62
62
|
|
63
|
-
if layout
|
64
|
-
view = @view
|
63
|
+
body = if layout
|
65
64
|
view.view_flow.set(:layout, content)
|
66
65
|
layout.render(view, locals) { |*name| view._layout_for(*name) }
|
67
66
|
else
|
68
67
|
content
|
69
68
|
end
|
69
|
+
build_rendered_template(body, template, layout)
|
70
70
|
end
|
71
71
|
|
72
72
|
# This is the method which actually finds the layout using details in the lookup
|
@@ -84,16 +84,16 @@ module ActionView
|
|
84
84
|
when String
|
85
85
|
begin
|
86
86
|
if layout.start_with?("/")
|
87
|
-
with_fallbacks
|
87
|
+
@lookup_context.with_fallbacks.find_template(layout, nil, false, [], details)
|
88
88
|
else
|
89
|
-
find_template(layout, nil, false, [], details)
|
89
|
+
@lookup_context.find_template(layout, nil, false, [], details)
|
90
90
|
end
|
91
91
|
rescue ActionView::MissingTemplate
|
92
92
|
all_details = @details.merge(formats: @lookup_context.default_formats)
|
93
93
|
raise unless template_exists?(layout, nil, false, [], all_details)
|
94
94
|
end
|
95
95
|
when Proc
|
96
|
-
resolve_layout(layout.call(formats), keys, formats)
|
96
|
+
resolve_layout(layout.call(@lookup_context, formats), keys, formats)
|
97
97
|
else
|
98
98
|
layout
|
99
99
|
end
|
@@ -26,6 +26,13 @@ module ActionView
|
|
26
26
|
extend ActiveSupport::Concern
|
27
27
|
include ActionView::ViewPaths
|
28
28
|
|
29
|
+
attr_reader :rendered_format
|
30
|
+
|
31
|
+
def initialize
|
32
|
+
@rendered_format = nil
|
33
|
+
super
|
34
|
+
end
|
35
|
+
|
29
36
|
# Overwrite process to setup I18n proxy.
|
30
37
|
def process(*) #:nodoc:
|
31
38
|
old_config, I18n.config = I18n.config, I18nProxy.new(I18n.config, lookup_context)
|
@@ -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,10 +103,6 @@ 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
107
|
|
94
108
|
# Find and render a template based on the options given.
|
@@ -98,17 +112,21 @@ module ActionView
|
|
98
112
|
context = view_context
|
99
113
|
|
100
114
|
context.assign assigns if assigns
|
101
|
-
lookup_context.rendered_format = nil if options[:formats]
|
102
115
|
lookup_context.variants = variant if variant
|
103
116
|
|
104
|
-
|
117
|
+
rendered_template = context.in_rendering_context(options) do |renderer|
|
118
|
+
renderer.render_to_object(context, options)
|
119
|
+
end
|
120
|
+
|
121
|
+
@rendered_format = Template::Types[rendered_template.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
129
|
lookup_context.formats = [format.to_sym]
|
111
|
-
lookup_context.rendered_format = lookup_context.formats.first
|
112
130
|
end
|
113
131
|
|
114
132
|
# Normalize args by converting render "foo" to render :action => "foo" and
|
data/lib/action_view/template.rb
CHANGED
@@ -2,14 +2,22 @@
|
|
2
2
|
|
3
3
|
require "active_support/core_ext/object/try"
|
4
4
|
require "active_support/core_ext/kernel/singleton_class"
|
5
|
+
require "active_support/deprecation"
|
5
6
|
require "thread"
|
7
|
+
require "delegate"
|
6
8
|
|
7
9
|
module ActionView
|
8
10
|
# = Action View Template
|
9
11
|
class Template
|
10
12
|
extend ActiveSupport::Autoload
|
11
13
|
|
12
|
-
|
14
|
+
def self.finalize_compiled_template_methods
|
15
|
+
ActiveSupport::Deprecation.warn "ActionView::Template.finalize_compiled_template_methods is deprecated and has no effect"
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.finalize_compiled_template_methods=(_)
|
19
|
+
ActiveSupport::Deprecation.warn "ActionView::Template.finalize_compiled_template_methods= is deprecated and has no effect"
|
20
|
+
end
|
13
21
|
|
14
22
|
# === Encodings in ActionView::Template
|
15
23
|
#
|
@@ -107,28 +115,23 @@ module ActionView
|
|
107
115
|
autoload :Error
|
108
116
|
autoload :Handlers
|
109
117
|
autoload :HTML
|
118
|
+
autoload :Inline
|
110
119
|
autoload :Text
|
111
120
|
autoload :Types
|
112
121
|
end
|
113
122
|
|
114
123
|
extend Template::Handlers
|
115
124
|
|
116
|
-
attr_accessor :locals, :
|
125
|
+
attr_accessor :locals, :variants, :virtual_path
|
117
126
|
|
118
127
|
attr_reader :source, :identifier, :handler, :original_encoding, :updated_at
|
128
|
+
attr_reader :variable, :format
|
119
129
|
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
mod.module_eval do
|
125
|
-
remove_possible_method method_name
|
126
|
-
end
|
130
|
+
def initialize(source, identifier, handler, format: nil, **details)
|
131
|
+
unless format
|
132
|
+
ActiveSupport::Deprecation.warn "ActionView::Template#initialize requires a format parameter"
|
133
|
+
format = :html
|
127
134
|
end
|
128
|
-
end
|
129
|
-
|
130
|
-
def initialize(source, identifier, handler, details)
|
131
|
-
format = details[:format] || (handler.default_format if handler.respond_to?(:default_format))
|
132
135
|
|
133
136
|
@source = source
|
134
137
|
@identifier = identifier
|
@@ -137,12 +140,25 @@ module ActionView
|
|
137
140
|
@original_encoding = nil
|
138
141
|
@locals = details[:locals] || []
|
139
142
|
@virtual_path = details[:virtual_path]
|
143
|
+
|
144
|
+
@variable = if @virtual_path
|
145
|
+
base = @virtual_path[-1] == "/" ? "" : File.basename(@virtual_path)
|
146
|
+
base =~ /\A_?(.*?)(?:\.\w+)*\z/
|
147
|
+
$1.to_sym
|
148
|
+
end
|
149
|
+
|
140
150
|
@updated_at = details[:updated_at] || Time.now
|
141
|
-
@
|
151
|
+
@format = format
|
142
152
|
@variants = [details[:variant]]
|
143
153
|
@compile_mutex = Mutex.new
|
144
154
|
end
|
145
155
|
|
156
|
+
def formats=(_)
|
157
|
+
end
|
158
|
+
deprecate :formats=
|
159
|
+
|
160
|
+
deprecate def formats; Array(format); end
|
161
|
+
|
146
162
|
# Returns whether the underlying handler supports streaming. If so,
|
147
163
|
# a streaming buffer *may* be passed when it starts rendering.
|
148
164
|
def supports_streaming?
|
@@ -155,17 +171,17 @@ module ActionView
|
|
155
171
|
# This method is instrumented as "!render_template.action_view". Notice that
|
156
172
|
# we use a bang in this instrumentation because you don't want to
|
157
173
|
# consume this in production. This is only slow if it's being listened to.
|
158
|
-
def render(view, locals, buffer =
|
174
|
+
def render(view, locals, buffer = ActionView::OutputBuffer.new, &block)
|
159
175
|
instrument_render_template do
|
160
176
|
compile!(view)
|
161
|
-
view.
|
177
|
+
view.run(method_name, self, locals, buffer, &block)
|
162
178
|
end
|
163
179
|
rescue => e
|
164
180
|
handle_render_error(view, e)
|
165
181
|
end
|
166
182
|
|
167
183
|
def type
|
168
|
-
@type ||= Types[
|
184
|
+
@type ||= Types[format]
|
169
185
|
end
|
170
186
|
|
171
187
|
# Receives a view object and return a template similar to self by using @virtual_path.
|
@@ -187,8 +203,12 @@ module ActionView
|
|
187
203
|
end
|
188
204
|
end
|
189
205
|
|
206
|
+
def short_identifier
|
207
|
+
@short_identifier ||= defined?(Rails.root) ? identifier.sub("#{Rails.root}/", "") : identifier
|
208
|
+
end
|
209
|
+
|
190
210
|
def inspect
|
191
|
-
|
211
|
+
"#<#{self.class.name} #{short_identifier} locals=#{@locals.inspect}>"
|
192
212
|
end
|
193
213
|
|
194
214
|
# This method is responsible for properly setting the encoding of the
|
@@ -202,7 +222,9 @@ module ActionView
|
|
202
222
|
# before passing the source on to the template engine, leaving a
|
203
223
|
# blank line in its stead.
|
204
224
|
def encode!
|
205
|
-
|
225
|
+
source = self.source
|
226
|
+
|
227
|
+
return source unless source.encoding == Encoding::BINARY
|
206
228
|
|
207
229
|
# Look for # encoding: *. If we find one, we'll encode the
|
208
230
|
# String in that encoding, otherwise, we'll use the
|
@@ -240,11 +262,11 @@ module ActionView
|
|
240
262
|
# to ensure that references to the template object can be marshalled as well. This means forgoing
|
241
263
|
# the marshalling of the compiler mutex and instantiating that again on unmarshalling.
|
242
264
|
def marshal_dump # :nodoc:
|
243
|
-
[ @source, @identifier, @handler, @compiled, @original_encoding, @locals, @virtual_path, @updated_at, @
|
265
|
+
[ @source, @identifier, @handler, @compiled, @original_encoding, @locals, @virtual_path, @updated_at, @format, @variants ]
|
244
266
|
end
|
245
267
|
|
246
268
|
def marshal_load(array) # :nodoc:
|
247
|
-
@source, @identifier, @handler, @compiled, @original_encoding, @locals, @virtual_path, @updated_at, @
|
269
|
+
@source, @identifier, @handler, @compiled, @original_encoding, @locals, @virtual_path, @updated_at, @format, @variants = *array
|
248
270
|
@compile_mutex = Mutex.new
|
249
271
|
end
|
250
272
|
|
@@ -264,11 +286,7 @@ module ActionView
|
|
264
286
|
# re-compilation
|
265
287
|
return if @compiled
|
266
288
|
|
267
|
-
|
268
|
-
mod = ActionView::CompiledTemplates
|
269
|
-
else
|
270
|
-
mod = view.singleton_class
|
271
|
-
end
|
289
|
+
mod = view.compiled_method_container
|
272
290
|
|
273
291
|
instrument("!compile_template") do
|
274
292
|
compile(mod)
|
@@ -281,6 +299,15 @@ module ActionView
|
|
281
299
|
end
|
282
300
|
end
|
283
301
|
|
302
|
+
class LegacyTemplate < DelegateClass(Template) # :nodoc:
|
303
|
+
attr_reader :source
|
304
|
+
|
305
|
+
def initialize(template, source)
|
306
|
+
super(template)
|
307
|
+
@source = source
|
308
|
+
end
|
309
|
+
end
|
310
|
+
|
284
311
|
# Among other things, this method is responsible for properly setting
|
285
312
|
# the encoding of the compiled template.
|
286
313
|
#
|
@@ -294,16 +321,14 @@ module ActionView
|
|
294
321
|
# In general, this means that templates will be UTF-8 inside of Rails,
|
295
322
|
# regardless of the original source encoding.
|
296
323
|
def compile(mod)
|
297
|
-
encode!
|
298
|
-
code = @handler.call(self)
|
324
|
+
source = encode!
|
325
|
+
code = @handler.call(self, source)
|
299
326
|
|
300
327
|
# Make sure that the resulting String to be eval'd is in the
|
301
328
|
# encoding of the code
|
302
329
|
source = +<<-end_src
|
303
330
|
def #{method_name}(local_assigns, output_buffer)
|
304
|
-
|
305
|
-
ensure
|
306
|
-
@virtual_path, @output_buffer = _old_virtual_path, _old_output_buffer
|
331
|
+
@virtual_path = #{@virtual_path.inspect};#{locals_code};#{code}
|
307
332
|
end
|
308
333
|
end_src
|
309
334
|
|
@@ -318,13 +343,10 @@ module ActionView
|
|
318
343
|
# handler is valid in the default_internal. This is for handlers
|
319
344
|
# that handle encoding but screw up
|
320
345
|
unless source.valid_encoding?
|
321
|
-
raise WrongEncodingError.new(
|
346
|
+
raise WrongEncodingError.new(source, Encoding.default_internal)
|
322
347
|
end
|
323
348
|
|
324
349
|
mod.module_eval(source, identifier, 0)
|
325
|
-
if finalize_compiled_template_methods
|
326
|
-
ObjectSpace.define_finalizer(self, Finalizer[method_name, mod])
|
327
|
-
end
|
328
350
|
end
|
329
351
|
|
330
352
|
def handle_render_error(view, e)
|
@@ -360,7 +382,7 @@ module ActionView
|
|
360
382
|
end
|
361
383
|
|
362
384
|
def identifier_method_name
|
363
|
-
|
385
|
+
short_identifier.tr("^a-z_", "_")
|
364
386
|
end
|
365
387
|
|
366
388
|
def instrument(action, &block) # :doc:
|