actionview 4.2.11 → 5.0.7
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 +5 -5
- data/CHANGELOG.md +304 -184
- data/MIT-LICENSE +1 -1
- data/README.rdoc +2 -3
- data/lib/action_view.rb +1 -1
- data/lib/action_view/base.rb +14 -2
- data/lib/action_view/dependency_tracker.rb +51 -18
- data/lib/action_view/digestor.rb +83 -81
- data/lib/action_view/flows.rb +4 -5
- data/lib/action_view/gem_version.rb +3 -3
- data/lib/action_view/helpers/asset_tag_helper.rb +15 -5
- data/lib/action_view/helpers/asset_url_helper.rb +51 -12
- data/lib/action_view/helpers/atom_feed_helper.rb +6 -5
- data/lib/action_view/helpers/cache_helper.rb +62 -21
- data/lib/action_view/helpers/capture_helper.rb +5 -4
- data/lib/action_view/helpers/controller_helper.rb +11 -2
- data/lib/action_view/helpers/date_helper.rb +59 -13
- data/lib/action_view/helpers/debug_helper.rb +1 -1
- data/lib/action_view/helpers/form_helper.rb +74 -72
- data/lib/action_view/helpers/form_options_helper.rb +79 -39
- data/lib/action_view/helpers/form_tag_helper.rb +74 -44
- data/lib/action_view/helpers/javascript_helper.rb +4 -4
- data/lib/action_view/helpers/number_helper.rb +28 -13
- data/lib/action_view/helpers/output_safety_helper.rb +32 -2
- data/lib/action_view/helpers/record_tag_helper.rb +12 -99
- data/lib/action_view/helpers/rendering_helper.rb +2 -2
- data/lib/action_view/helpers/sanitize_helper.rb +1 -2
- data/lib/action_view/helpers/tag_helper.rb +19 -11
- data/lib/action_view/helpers/tags/base.rb +45 -29
- data/lib/action_view/helpers/tags/collection_check_boxes.rb +4 -28
- data/lib/action_view/helpers/tags/collection_helpers.rb +32 -0
- data/lib/action_view/helpers/tags/collection_radio_buttons.rb +1 -9
- data/lib/action_view/helpers/tags/datetime_field.rb +1 -1
- data/lib/action_view/helpers/tags/label.rb +1 -1
- data/lib/action_view/helpers/tags/placeholderable.rb +1 -1
- data/lib/action_view/helpers/tags/search_field.rb +12 -9
- data/lib/action_view/helpers/tags/text_field.rb +0 -1
- data/lib/action_view/helpers/tags/translator.rb +1 -1
- data/lib/action_view/helpers/text_helper.rb +27 -11
- data/lib/action_view/helpers/translation_helper.rb +56 -26
- data/lib/action_view/helpers/url_helper.rb +108 -79
- data/lib/action_view/layouts.rb +11 -10
- data/lib/action_view/log_subscriber.rb +35 -1
- data/lib/action_view/lookup_context.rb +69 -48
- data/lib/action_view/model_naming.rb +1 -1
- data/lib/action_view/path_set.rb +9 -0
- data/lib/action_view/railtie.rb +18 -3
- data/lib/action_view/record_identifier.rb +45 -19
- data/lib/action_view/renderer/abstract_renderer.rb +7 -3
- data/lib/action_view/renderer/partial_renderer.rb +38 -37
- data/lib/action_view/renderer/partial_renderer/collection_caching.rb +49 -0
- data/lib/action_view/renderer/renderer.rb +2 -6
- data/lib/action_view/renderer/streaming_template_renderer.rb +1 -1
- data/lib/action_view/renderer/template_renderer.rb +11 -10
- data/lib/action_view/rendering.rb +15 -7
- data/lib/action_view/routing_url_for.rb +18 -6
- data/lib/action_view/tasks/{dependencies.rake → cache_digests.rake} +2 -2
- data/lib/action_view/template.rb +36 -12
- data/lib/action_view/template/error.rb +20 -9
- data/lib/action_view/template/handlers.rb +6 -4
- data/lib/action_view/template/handlers/html.rb +9 -0
- data/lib/action_view/template/handlers/raw.rb +1 -3
- data/lib/action_view/template/resolver.rb +49 -42
- data/lib/action_view/template/types.rb +14 -16
- data/lib/action_view/test_case.rb +15 -9
- data/lib/action_view/testing/resolvers.rb +1 -2
- data/lib/action_view/view_paths.rb +6 -24
- metadata +16 -20
@@ -15,7 +15,7 @@ module ActionView
|
|
15
15
|
# that new object is called in turn. This abstracts the setup and rendering
|
16
16
|
# into a separate classes for partials and templates.
|
17
17
|
class AbstractRenderer #:nodoc:
|
18
|
-
delegate :find_template, :find_file, :template_exists?, :with_fallbacks, :with_layout_format, :formats, :to => :@lookup_context
|
18
|
+
delegate :find_template, :find_file, :template_exists?, :any_templates?, :with_fallbacks, :with_layout_format, :formats, :to => :@lookup_context
|
19
19
|
|
20
20
|
def initialize(lookup_context)
|
21
21
|
@lookup_context = lookup_context
|
@@ -35,8 +35,12 @@ module ActionView
|
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
38
|
-
def instrument(name, options
|
39
|
-
|
38
|
+
def instrument(name, **options)
|
39
|
+
options[:identifier] ||= (@template && @template.identifier) || @path
|
40
|
+
|
41
|
+
ActiveSupport::Notifications.instrument("render_#{name}.action_view", options) do |payload|
|
42
|
+
yield payload
|
43
|
+
end
|
40
44
|
end
|
41
45
|
|
42
46
|
def prepend_formats(formats)
|
@@ -1,4 +1,5 @@
|
|
1
|
-
require '
|
1
|
+
require 'action_view/renderer/partial_renderer/collection_caching'
|
2
|
+
require 'concurrent/map'
|
2
3
|
|
3
4
|
module ActionView
|
4
5
|
class PartialIteration
|
@@ -73,7 +74,7 @@ module ActionView
|
|
73
74
|
#
|
74
75
|
# <%= render partial: "account", locals: { user: @buyer } %>
|
75
76
|
#
|
76
|
-
# == Rendering a collection of partials
|
77
|
+
# == \Rendering a collection of partials
|
77
78
|
#
|
78
79
|
# The example of partial use describes a familiar pattern where a template needs to iterate over an array and
|
79
80
|
# render a sub template for each of the elements. This pattern has been implemented as a single method that
|
@@ -105,7 +106,7 @@ module ActionView
|
|
105
106
|
# NOTE: Due to backwards compatibility concerns, the collection can't be one of hashes. Normally you'd also
|
106
107
|
# just keep domain objects, like Active Records, in there.
|
107
108
|
#
|
108
|
-
# == Rendering shared partials
|
109
|
+
# == \Rendering shared partials
|
109
110
|
#
|
110
111
|
# Two controllers can share a set of partials and render them like this:
|
111
112
|
#
|
@@ -113,7 +114,7 @@ module ActionView
|
|
113
114
|
#
|
114
115
|
# This will render the partial "advertisement/_ad.html.erb" regardless of which controller this is being called from.
|
115
116
|
#
|
116
|
-
# == Rendering objects that respond to `to_partial_path`
|
117
|
+
# == \Rendering objects that respond to `to_partial_path`
|
117
118
|
#
|
118
119
|
# Instead of explicitly naming the location of a partial, you can also let PartialRenderer do the work
|
119
120
|
# and pick the proper path by checking `to_partial_path` method.
|
@@ -127,7 +128,7 @@ module ActionView
|
|
127
128
|
# # <%= render partial: "posts/post", collection: @posts %>
|
128
129
|
# <%= render partial: @posts %>
|
129
130
|
#
|
130
|
-
# == Rendering the default case
|
131
|
+
# == \Rendering the default case
|
131
132
|
#
|
132
133
|
# If you're not going to be using any of the options like collections or layouts, you can also use the short-hand
|
133
134
|
# defaults of render to render partials. Examples:
|
@@ -147,29 +148,29 @@ module ActionView
|
|
147
148
|
# # <%= render partial: "posts/post", collection: @posts %>
|
148
149
|
# <%= render @posts %>
|
149
150
|
#
|
150
|
-
# == Rendering partials with layouts
|
151
|
+
# == \Rendering partials with layouts
|
151
152
|
#
|
152
153
|
# Partials can have their own layouts applied to them. These layouts are different than the ones that are
|
153
154
|
# specified globally for the entire action, but they work in a similar fashion. Imagine a list with two types
|
154
155
|
# of users:
|
155
156
|
#
|
156
|
-
# <%# app/views/users/index.html.erb
|
157
|
+
# <%# app/views/users/index.html.erb %>
|
157
158
|
# Here's the administrator:
|
158
159
|
# <%= render partial: "user", layout: "administrator", locals: { user: administrator } %>
|
159
160
|
#
|
160
161
|
# Here's the editor:
|
161
162
|
# <%= render partial: "user", layout: "editor", locals: { user: editor } %>
|
162
163
|
#
|
163
|
-
# <%# app/views/users/_user.html.erb
|
164
|
+
# <%# app/views/users/_user.html.erb %>
|
164
165
|
# Name: <%= user.name %>
|
165
166
|
#
|
166
|
-
# <%# app/views/users/_administrator.html.erb
|
167
|
+
# <%# app/views/users/_administrator.html.erb %>
|
167
168
|
# <div id="administrator">
|
168
169
|
# Budget: $<%= user.budget %>
|
169
170
|
# <%= yield %>
|
170
171
|
# </div>
|
171
172
|
#
|
172
|
-
# <%# app/views/users/_editor.html.erb
|
173
|
+
# <%# app/views/users/_editor.html.erb %>
|
173
174
|
# <div id="editor">
|
174
175
|
# Deadline: <%= user.deadline %>
|
175
176
|
# <%= yield %>
|
@@ -232,7 +233,7 @@ module ActionView
|
|
232
233
|
#
|
233
234
|
# You can also apply a layout to a block within any template:
|
234
235
|
#
|
235
|
-
# <%# app/views/users/_chief.html.erb
|
236
|
+
# <%# app/views/users/_chief.html.erb %>
|
236
237
|
# <%= render(layout: "administrator", locals: { user: chief }) do %>
|
237
238
|
# Title: <%= chief.title %>
|
238
239
|
# <% end %>
|
@@ -249,13 +250,13 @@ module ActionView
|
|
249
250
|
# If you pass arguments to "yield" then this will be passed to the block. One way to use this is to pass
|
250
251
|
# an array to layout and treat it as an enumerable.
|
251
252
|
#
|
252
|
-
# <%# app/views/users/_user.html.erb
|
253
|
+
# <%# app/views/users/_user.html.erb %>
|
253
254
|
# <div class="user">
|
254
255
|
# Budget: $<%= user.budget %>
|
255
256
|
# <%= yield user %>
|
256
257
|
# </div>
|
257
258
|
#
|
258
|
-
# <%# app/views/users/index.html.erb
|
259
|
+
# <%# app/views/users/index.html.erb %>
|
259
260
|
# <%= render layout: @users do |user| %>
|
260
261
|
# Title: <%= user.title %>
|
261
262
|
# <% end %>
|
@@ -264,14 +265,14 @@ module ActionView
|
|
264
265
|
#
|
265
266
|
# You can also yield multiple times in one layout and use block arguments to differentiate the sections.
|
266
267
|
#
|
267
|
-
# <%# app/views/users/_user.html.erb
|
268
|
+
# <%# app/views/users/_user.html.erb %>
|
268
269
|
# <div class="user">
|
269
270
|
# <%= yield user, :header %>
|
270
271
|
# Budget: $<%= user.budget %>
|
271
272
|
# <%= yield user, :footer %>
|
272
273
|
# </div>
|
273
274
|
#
|
274
|
-
# <%# app/views/users/index.html.erb
|
275
|
+
# <%# app/views/users/index.html.erb %>
|
275
276
|
# <%= render layout: @users do |user, section| %>
|
276
277
|
# <%- case section when :header -%>
|
277
278
|
# Title: <%= user.title %>
|
@@ -280,8 +281,10 @@ module ActionView
|
|
280
281
|
# <%- end -%>
|
281
282
|
# <% end %>
|
282
283
|
class PartialRenderer < AbstractRenderer
|
283
|
-
|
284
|
-
|
284
|
+
include CollectionCaching
|
285
|
+
|
286
|
+
PREFIXED_PARTIAL_NAMES = Concurrent::Map.new do |h, k|
|
287
|
+
h[k] = Concurrent::Map.new
|
285
288
|
end
|
286
289
|
|
287
290
|
def initialize(*)
|
@@ -291,7 +294,7 @@ module ActionView
|
|
291
294
|
|
292
295
|
def render(context, options, block)
|
293
296
|
setup(context, options, block)
|
294
|
-
|
297
|
+
@template = find_partial
|
295
298
|
|
296
299
|
@lookup_context.rendered_format ||= begin
|
297
300
|
if @template && @template.formats.present?
|
@@ -302,11 +305,9 @@ module ActionView
|
|
302
305
|
end
|
303
306
|
|
304
307
|
if @collection
|
305
|
-
|
306
|
-
render_collection
|
307
|
-
end
|
308
|
+
render_collection
|
308
309
|
else
|
309
|
-
instrument(:partial
|
310
|
+
instrument(:partial) do
|
310
311
|
render_partial
|
311
312
|
end
|
312
313
|
end
|
@@ -315,14 +316,17 @@ module ActionView
|
|
315
316
|
private
|
316
317
|
|
317
318
|
def render_collection
|
318
|
-
|
319
|
+
instrument(:collection, count: @collection.size) do |payload|
|
320
|
+
return nil if @collection.blank?
|
319
321
|
|
320
|
-
|
321
|
-
|
322
|
-
|
322
|
+
if @options.key?(:spacer_template)
|
323
|
+
spacer = find_template(@options[:spacer_template], @locals.keys).render(@view, @locals)
|
324
|
+
end
|
323
325
|
|
324
|
-
|
325
|
-
|
326
|
+
cache_collection_render(payload) do
|
327
|
+
@template ? collection_with_template : collection_without_template
|
328
|
+
end.join(spacer).html_safe
|
329
|
+
end
|
326
330
|
end
|
327
331
|
|
328
332
|
def render_partial
|
@@ -334,7 +338,7 @@ module ActionView
|
|
334
338
|
end
|
335
339
|
|
336
340
|
object = locals[as] if object.nil? # Respect object when object is false
|
337
|
-
locals[as] = object
|
341
|
+
locals[as] = object if @has_object
|
338
342
|
|
339
343
|
content = @template.render(view, locals) do |*name|
|
340
344
|
view._layout_for(*name, &block)
|
@@ -344,8 +348,6 @@ module ActionView
|
|
344
348
|
content
|
345
349
|
end
|
346
350
|
|
347
|
-
private
|
348
|
-
|
349
351
|
# Sets up instance variables needed for rendering a partial. This method
|
350
352
|
# finds the options and details and extracts them. The method also contains
|
351
353
|
# logic that handles the type of object passed in as the partial.
|
@@ -401,7 +403,7 @@ module ActionView
|
|
401
403
|
def collection_from_options
|
402
404
|
if @options.key?(:collection)
|
403
405
|
collection = @options[:collection]
|
404
|
-
collection
|
406
|
+
collection ? collection.to_a : []
|
405
407
|
end
|
406
408
|
end
|
407
409
|
|
@@ -455,7 +457,7 @@ module ActionView
|
|
455
457
|
locals[counter] = index
|
456
458
|
locals[iteration] = partial_iteration
|
457
459
|
|
458
|
-
template = (cache[path] ||= find_template(path, keys + [as, counter]))
|
460
|
+
template = (cache[path] ||= find_template(path, keys + [as, counter, iteration]))
|
459
461
|
content = template.render(view, locals)
|
460
462
|
partial_iteration.iterate!
|
461
463
|
content
|
@@ -518,8 +520,8 @@ module ActionView
|
|
518
520
|
|
519
521
|
def retrieve_variable(path, as)
|
520
522
|
variable = as || begin
|
521
|
-
base = path[-1] == "/" ? "" : File.basename(path)
|
522
|
-
raise_invalid_identifier(path) unless base =~ /\A_?(
|
523
|
+
base = path[-1] == "/".freeze ? "".freeze : File.basename(path)
|
524
|
+
raise_invalid_identifier(path) unless base =~ /\A_?(.*?)(?:\.\w+)*\z/
|
523
525
|
$1.to_sym
|
524
526
|
end
|
525
527
|
if @collection
|
@@ -530,8 +532,7 @@ module ActionView
|
|
530
532
|
end
|
531
533
|
|
532
534
|
IDENTIFIER_ERROR_MESSAGE = "The partial name (%s) is not a valid Ruby identifier; " +
|
533
|
-
"make sure your partial name starts with underscore
|
534
|
-
"and is followed by any combination of letters, numbers and underscores."
|
535
|
+
"make sure your partial name starts with underscore."
|
535
536
|
|
536
537
|
OPTION_AS_ERROR_MESSAGE = "The value (%s) of the option `as` is not a valid Ruby identifier; " +
|
537
538
|
"make sure it starts with lowercase letter, " +
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module ActionView
|
2
|
+
module CollectionCaching # :nodoc:
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
# Fallback cache store if Action View is used without Rails.
|
7
|
+
# Otherwise overridden in Railtie to use Rails.cache.
|
8
|
+
mattr_accessor(:collection_cache) { ActiveSupport::Cache::MemoryStore.new }
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
def cache_collection_render(instrumentation_payload)
|
13
|
+
return yield unless @options[:cached]
|
14
|
+
|
15
|
+
keyed_collection = collection_by_cache_keys
|
16
|
+
cached_partials = collection_cache.read_multi(*keyed_collection.keys)
|
17
|
+
instrumentation_payload[:cache_hits] = cached_partials.size
|
18
|
+
|
19
|
+
@collection = keyed_collection.reject { |key, _| cached_partials.key?(key) }.values
|
20
|
+
rendered_partials = @collection.empty? ? [] : yield
|
21
|
+
|
22
|
+
index = 0
|
23
|
+
fetch_or_cache_partial(cached_partials, order_by: keyed_collection.each_key) do
|
24
|
+
rendered_partials[index].tap { index += 1 }
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def collection_by_cache_keys
|
29
|
+
@collection.each_with_object({}) do |item, hash|
|
30
|
+
hash[expanded_cache_key(item)] = item
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def expanded_cache_key(key)
|
35
|
+
key = @view.fragment_cache_key(@view.cache_fragment_name(key, virtual_path: @template.virtual_path))
|
36
|
+
key.frozen? ? key.dup : key # #read_multi & #write may require mutability, Dalli 2.6.0.
|
37
|
+
end
|
38
|
+
|
39
|
+
def fetch_or_cache_partial(cached_partials, order_by:)
|
40
|
+
order_by.map do |cache_key|
|
41
|
+
cached_partials.fetch(cache_key) do
|
42
|
+
yield.tap do |rendered_partial|
|
43
|
+
collection_cache.write(cache_key, rendered_partial)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -15,12 +15,8 @@ module ActionView
|
|
15
15
|
@lookup_context = lookup_context
|
16
16
|
end
|
17
17
|
|
18
|
-
# Main render entry point shared by
|
18
|
+
# Main render entry point shared by Action View and Action Controller.
|
19
19
|
def render(context, options)
|
20
|
-
if options.respond_to?(:permitted?) && !options.permitted?
|
21
|
-
raise ArgumentError, "render parameters are not permitted"
|
22
|
-
end
|
23
|
-
|
24
20
|
if options.key?(:partial)
|
25
21
|
render_partial(context, options)
|
26
22
|
else
|
@@ -41,7 +37,7 @@ module ActionView
|
|
41
37
|
end
|
42
38
|
end
|
43
39
|
|
44
|
-
# Direct
|
40
|
+
# Direct access to template rendering.
|
45
41
|
def render_template(context, options) #:nodoc:
|
46
42
|
TemplateRenderer.new(@lookup_context).render(context, options)
|
47
43
|
end
|
@@ -47,7 +47,7 @@ module ActionView
|
|
47
47
|
return [super] unless layout_name && template.supports_streaming?
|
48
48
|
|
49
49
|
locals ||= {}
|
50
|
-
layout = layout_name && find_layout(layout_name, locals.keys)
|
50
|
+
layout = layout_name && find_layout(layout_name, locals.keys, [formats.first])
|
51
51
|
|
52
52
|
Body.new do |buffer|
|
53
53
|
delayed_render(buffer, template, layout, @view, locals)
|
@@ -40,7 +40,7 @@ module ActionView
|
|
40
40
|
find_template(options[:template], options[:prefixes], false, keys, @details)
|
41
41
|
end
|
42
42
|
else
|
43
|
-
raise ArgumentError, "You invoked render but did not give any of :partial, :template, :inline, :file, :plain, :text or :body option."
|
43
|
+
raise ArgumentError, "You invoked render but did not give any of :partial, :template, :inline, :file, :plain, :html, :text or :body option."
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
@@ -57,7 +57,7 @@ module ActionView
|
|
57
57
|
end
|
58
58
|
|
59
59
|
def render_with_layout(path, locals) #:nodoc:
|
60
|
-
layout = path && find_layout(path, locals.keys)
|
60
|
+
layout = path && find_layout(path, locals.keys, [formats.first])
|
61
61
|
content = yield(layout)
|
62
62
|
|
63
63
|
if layout
|
@@ -72,27 +72,28 @@ module ActionView
|
|
72
72
|
# This is the method which actually finds the layout using details in the lookup
|
73
73
|
# context object. If no layout is found, it checks if at least a layout with
|
74
74
|
# the given name exists across all details before raising the error.
|
75
|
-
def find_layout(layout, keys)
|
76
|
-
|
75
|
+
def find_layout(layout, keys, formats)
|
76
|
+
resolve_layout(layout, keys, formats)
|
77
77
|
end
|
78
78
|
|
79
|
-
def resolve_layout(layout, keys)
|
79
|
+
def resolve_layout(layout, keys, formats)
|
80
|
+
details = @details.dup
|
81
|
+
details[:formats] = formats
|
82
|
+
|
80
83
|
case layout
|
81
84
|
when String
|
82
85
|
begin
|
83
86
|
if layout =~ /^\//
|
84
|
-
with_fallbacks { find_template(layout, nil, false, keys,
|
87
|
+
with_fallbacks { find_template(layout, nil, false, keys, details) }
|
85
88
|
else
|
86
|
-
find_template(layout, nil, false, keys,
|
89
|
+
find_template(layout, nil, false, keys, details)
|
87
90
|
end
|
88
91
|
rescue ActionView::MissingTemplate
|
89
92
|
all_details = @details.merge(:formats => @lookup_context.default_formats)
|
90
93
|
raise unless template_exists?(layout, nil, false, keys, all_details)
|
91
94
|
end
|
92
95
|
when Proc
|
93
|
-
resolve_layout(layout.call, keys)
|
94
|
-
when FalseClass
|
95
|
-
nil
|
96
|
+
resolve_layout(layout.call(formats), keys, formats)
|
96
97
|
else
|
97
98
|
layout
|
98
99
|
end
|
@@ -59,7 +59,7 @@ module ActionView
|
|
59
59
|
@_view_context_class ||= self.class.view_context_class
|
60
60
|
end
|
61
61
|
|
62
|
-
# An instance of a view class. The default view class is ActionView::Base
|
62
|
+
# An instance of a view class. The default view class is ActionView::Base.
|
63
63
|
#
|
64
64
|
# The view class must have the following methods:
|
65
65
|
# View.new[lookup_context, assigns, controller]
|
@@ -84,7 +84,8 @@ module ActionView
|
|
84
84
|
end
|
85
85
|
|
86
86
|
def rendered_format
|
87
|
-
|
87
|
+
format = lookup_context.rendered_format
|
88
|
+
Template::Types[format] || format
|
88
89
|
end
|
89
90
|
|
90
91
|
private
|
@@ -92,16 +93,19 @@ module ActionView
|
|
92
93
|
# Find and render a template based on the options given.
|
93
94
|
# :api: private
|
94
95
|
def _render_template(options) #:nodoc:
|
95
|
-
variant = options
|
96
|
+
variant = options.delete(:variant)
|
97
|
+
assigns = options.delete(:assigns)
|
98
|
+
context = view_context
|
96
99
|
|
100
|
+
context.assign assigns if assigns
|
97
101
|
lookup_context.rendered_format = nil if options[:formats]
|
98
102
|
lookup_context.variants = variant if variant
|
99
103
|
|
100
|
-
view_renderer.render(
|
104
|
+
view_renderer.render(context, options)
|
101
105
|
end
|
102
106
|
|
103
|
-
# Assign the rendered format to
|
104
|
-
def _process_format(format
|
107
|
+
# Assign the rendered format to look up context.
|
108
|
+
def _process_format(format) #:nodoc:
|
105
109
|
super
|
106
110
|
lookup_context.formats = [format.to_sym]
|
107
111
|
lookup_context.rendered_format = lookup_context.formats.first
|
@@ -121,7 +125,11 @@ module ActionView
|
|
121
125
|
key = action.include?(?/) ? :template : :action
|
122
126
|
options[key] = action
|
123
127
|
else
|
124
|
-
|
128
|
+
if action.respond_to?(:permitted?) && action.permitted?
|
129
|
+
options = action
|
130
|
+
else
|
131
|
+
options[:partial] = action
|
132
|
+
end
|
125
133
|
end
|
126
134
|
|
127
135
|
options
|
@@ -32,7 +32,7 @@ module ActionView
|
|
32
32
|
#
|
33
33
|
# ==== Examples
|
34
34
|
# <%= url_for(action: 'index') %>
|
35
|
-
# # => /
|
35
|
+
# # => /blogs/
|
36
36
|
#
|
37
37
|
# <%= url_for(action: 'find', controller: 'books') %>
|
38
38
|
# # => /books/find
|
@@ -84,11 +84,13 @@ module ActionView
|
|
84
84
|
when Hash
|
85
85
|
options = options.symbolize_keys
|
86
86
|
unless options.key?(:only_path)
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
87
|
+
options[:only_path] = only_path?(options[:host])
|
88
|
+
end
|
89
|
+
|
90
|
+
super(options)
|
91
|
+
when ActionController::Parameters
|
92
|
+
unless options.key?(:only_path)
|
93
|
+
options[:only_path] = only_path?(options[:host])
|
92
94
|
end
|
93
95
|
|
94
96
|
super(options)
|
@@ -131,5 +133,15 @@ module ActionView
|
|
131
133
|
controller.optimize_routes_generation? : super
|
132
134
|
end
|
133
135
|
protected :optimize_routes_generation?
|
136
|
+
|
137
|
+
private
|
138
|
+
|
139
|
+
def _generate_paths_by_default
|
140
|
+
true
|
141
|
+
end
|
142
|
+
|
143
|
+
def only_path?(host)
|
144
|
+
_generate_paths_by_default unless host
|
145
|
+
end
|
134
146
|
end
|
135
147
|
end
|