actionpack 3.2.22.5 → 4.0.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of actionpack might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +641 -418
- data/MIT-LICENSE +1 -1
- data/README.rdoc +5 -288
- data/lib/abstract_controller.rb +1 -8
- data/lib/abstract_controller/asset_paths.rb +2 -2
- data/lib/abstract_controller/base.rb +39 -37
- data/lib/abstract_controller/callbacks.rb +101 -82
- data/lib/abstract_controller/collector.rb +7 -3
- data/lib/abstract_controller/helpers.rb +23 -11
- data/lib/abstract_controller/layouts.rb +68 -73
- data/lib/abstract_controller/logger.rb +1 -2
- data/lib/abstract_controller/rendering.rb +22 -13
- data/lib/abstract_controller/translation.rb +16 -1
- data/lib/abstract_controller/url_for.rb +6 -6
- data/lib/abstract_controller/view_paths.rb +1 -1
- data/lib/action_controller.rb +15 -6
- data/lib/action_controller/base.rb +46 -22
- data/lib/action_controller/caching.rb +46 -33
- data/lib/action_controller/caching/fragments.rb +23 -53
- data/lib/action_controller/deprecated.rb +5 -1
- data/lib/action_controller/deprecated/integration_test.rb +3 -0
- data/lib/action_controller/log_subscriber.rb +11 -8
- data/lib/action_controller/metal.rb +16 -30
- data/lib/action_controller/metal/conditional_get.rb +76 -32
- data/lib/action_controller/metal/data_streaming.rb +20 -26
- data/lib/action_controller/metal/exceptions.rb +19 -6
- data/lib/action_controller/metal/flash.rb +24 -9
- data/lib/action_controller/metal/force_ssl.rb +32 -9
- data/lib/action_controller/metal/head.rb +25 -4
- data/lib/action_controller/metal/helpers.rb +6 -9
- data/lib/action_controller/metal/hide_actions.rb +1 -2
- data/lib/action_controller/metal/http_authentication.rb +105 -87
- data/lib/action_controller/metal/implicit_render.rb +1 -1
- data/lib/action_controller/metal/instrumentation.rb +2 -1
- data/lib/action_controller/metal/live.rb +141 -0
- data/lib/action_controller/metal/mime_responds.rb +161 -47
- data/lib/action_controller/metal/params_wrapper.rb +112 -74
- data/lib/action_controller/metal/rack_delegation.rb +9 -3
- data/lib/action_controller/metal/redirecting.rb +15 -20
- data/lib/action_controller/metal/renderers.rb +11 -9
- data/lib/action_controller/metal/rendering.rb +8 -0
- data/lib/action_controller/metal/request_forgery_protection.rb +112 -19
- data/lib/action_controller/metal/responder.rb +20 -19
- data/lib/action_controller/metal/streaming.rb +12 -18
- data/lib/action_controller/metal/strong_parameters.rb +516 -0
- data/lib/action_controller/metal/testing.rb +13 -18
- data/lib/action_controller/metal/url_for.rb +27 -25
- data/lib/action_controller/model_naming.rb +12 -0
- data/lib/action_controller/railtie.rb +33 -17
- data/lib/action_controller/railties/helpers.rb +22 -0
- data/lib/action_controller/record_identifier.rb +18 -72
- data/lib/action_controller/test_case.rb +215 -123
- data/lib/action_controller/vendor/html-scanner.rb +4 -19
- data/lib/action_dispatch.rb +27 -19
- data/lib/action_dispatch/http/cache.rb +63 -11
- data/lib/action_dispatch/http/filter_parameters.rb +18 -8
- data/lib/action_dispatch/http/filter_redirect.rb +37 -0
- data/lib/action_dispatch/http/headers.rb +27 -19
- data/lib/action_dispatch/http/mime_negotiation.rb +25 -2
- data/lib/action_dispatch/http/mime_type.rb +145 -113
- data/lib/action_dispatch/http/mime_types.rb +1 -1
- data/lib/action_dispatch/http/parameter_filter.rb +44 -46
- data/lib/action_dispatch/http/parameters.rb +12 -5
- data/lib/action_dispatch/http/rack_cache.rb +2 -3
- data/lib/action_dispatch/http/request.rb +49 -18
- data/lib/action_dispatch/http/response.rb +129 -35
- data/lib/action_dispatch/http/upload.rb +60 -17
- data/lib/action_dispatch/http/url.rb +53 -31
- data/lib/action_dispatch/journey.rb +5 -0
- data/lib/action_dispatch/journey/backwards.rb +5 -0
- data/lib/action_dispatch/journey/formatter.rb +146 -0
- data/lib/action_dispatch/journey/gtg/builder.rb +162 -0
- data/lib/action_dispatch/journey/gtg/simulator.rb +44 -0
- data/lib/action_dispatch/journey/gtg/transition_table.rb +156 -0
- data/lib/action_dispatch/journey/nfa/builder.rb +76 -0
- data/lib/action_dispatch/journey/nfa/dot.rb +36 -0
- data/lib/action_dispatch/journey/nfa/simulator.rb +47 -0
- data/lib/action_dispatch/journey/nfa/transition_table.rb +163 -0
- data/lib/action_dispatch/journey/nodes/node.rb +124 -0
- data/lib/action_dispatch/journey/parser.rb +206 -0
- data/lib/action_dispatch/journey/parser.y +47 -0
- data/lib/action_dispatch/journey/parser_extras.rb +23 -0
- data/lib/action_dispatch/journey/path/pattern.rb +196 -0
- data/lib/action_dispatch/journey/route.rb +116 -0
- data/lib/action_dispatch/journey/router.rb +164 -0
- data/lib/action_dispatch/journey/router/strexp.rb +24 -0
- data/lib/action_dispatch/journey/router/utils.rb +54 -0
- data/lib/action_dispatch/journey/routes.rb +75 -0
- data/lib/action_dispatch/journey/scanner.rb +61 -0
- data/lib/action_dispatch/journey/visitors.rb +189 -0
- data/lib/action_dispatch/journey/visualizer/fsm.css +34 -0
- data/lib/action_dispatch/journey/visualizer/fsm.js +134 -0
- data/lib/action_dispatch/journey/visualizer/index.html.erb +52 -0
- data/lib/action_dispatch/middleware/callbacks.rb +9 -4
- data/lib/action_dispatch/middleware/cookies.rb +168 -57
- data/lib/action_dispatch/middleware/debug_exceptions.rb +26 -17
- data/lib/action_dispatch/middleware/exception_wrapper.rb +27 -3
- data/lib/action_dispatch/middleware/flash.rb +58 -58
- data/lib/action_dispatch/middleware/params_parser.rb +14 -29
- data/lib/action_dispatch/middleware/public_exceptions.rb +31 -14
- data/lib/action_dispatch/middleware/reloader.rb +6 -6
- data/lib/action_dispatch/middleware/remote_ip.rb +145 -39
- data/lib/action_dispatch/middleware/request_id.rb +2 -6
- data/lib/action_dispatch/middleware/session/abstract_store.rb +22 -20
- data/lib/action_dispatch/middleware/session/cache_store.rb +3 -3
- data/lib/action_dispatch/middleware/session/cookie_store.rb +81 -7
- data/lib/action_dispatch/middleware/session/mem_cache_store.rb +8 -3
- data/lib/action_dispatch/middleware/show_exceptions.rb +12 -45
- data/lib/action_dispatch/middleware/ssl.rb +70 -0
- data/lib/action_dispatch/middleware/stack.rb +6 -1
- data/lib/action_dispatch/middleware/static.rb +5 -24
- data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb +14 -11
- data/lib/action_dispatch/middleware/templates/rescues/_source.erb +25 -0
- data/lib/action_dispatch/middleware/templates/rescues/_trace.erb +3 -3
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb +15 -9
- data/lib/action_dispatch/middleware/templates/rescues/layout.erb +121 -5
- data/lib/action_dispatch/middleware/templates/rescues/missing_template.erb +7 -2
- data/lib/action_dispatch/middleware/templates/rescues/routing_error.erb +30 -15
- data/lib/action_dispatch/middleware/templates/rescues/template_error.erb +39 -13
- data/lib/action_dispatch/middleware/templates/rescues/unknown_action.erb +6 -2
- data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +16 -0
- data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +144 -0
- data/lib/action_dispatch/railtie.rb +16 -6
- data/lib/action_dispatch/request/session.rb +181 -0
- data/lib/action_dispatch/routing.rb +41 -40
- data/lib/action_dispatch/routing/inspector.rb +240 -0
- data/lib/action_dispatch/routing/mapper.rb +501 -273
- data/lib/action_dispatch/routing/polymorphic_routes.rb +16 -20
- data/lib/action_dispatch/routing/redirection.rb +46 -29
- data/lib/action_dispatch/routing/route_set.rb +203 -164
- data/lib/action_dispatch/routing/routes_proxy.rb +2 -0
- data/lib/action_dispatch/routing/url_for.rb +48 -33
- data/lib/action_dispatch/testing/assertions/dom.rb +3 -13
- data/lib/action_dispatch/testing/assertions/response.rb +32 -40
- data/lib/action_dispatch/testing/assertions/routing.rb +40 -39
- data/lib/action_dispatch/testing/assertions/selector.rb +15 -20
- data/lib/action_dispatch/testing/assertions/tag.rb +20 -23
- data/lib/action_dispatch/testing/integration.rb +41 -22
- data/lib/action_dispatch/testing/test_process.rb +9 -6
- data/lib/action_dispatch/testing/test_request.rb +7 -3
- data/lib/action_pack.rb +1 -1
- data/lib/action_pack/version.rb +4 -4
- data/lib/action_view.rb +17 -8
- data/lib/action_view/base.rb +15 -34
- data/lib/action_view/buffers.rb +1 -1
- data/lib/action_view/context.rb +4 -4
- data/lib/action_view/dependency_tracker.rb +91 -0
- data/lib/action_view/digestor.rb +85 -0
- data/lib/action_view/flows.rb +1 -4
- data/lib/action_view/helpers.rb +2 -4
- data/lib/action_view/helpers/active_model_helper.rb +3 -4
- data/lib/action_view/helpers/asset_tag_helper.rb +211 -353
- data/lib/action_view/helpers/asset_url_helper.rb +354 -0
- data/lib/action_view/helpers/atom_feed_helper.rb +13 -10
- data/lib/action_view/helpers/cache_helper.rb +150 -18
- data/lib/action_view/helpers/capture_helper.rb +42 -29
- data/lib/action_view/helpers/csrf_helper.rb +0 -2
- data/lib/action_view/helpers/date_helper.rb +268 -247
- data/lib/action_view/helpers/debug_helper.rb +10 -11
- data/lib/action_view/helpers/form_helper.rb +904 -547
- data/lib/action_view/helpers/form_options_helper.rb +341 -166
- data/lib/action_view/helpers/form_tag_helper.rb +188 -88
- data/lib/action_view/helpers/javascript_helper.rb +23 -16
- data/lib/action_view/helpers/number_helper.rb +148 -354
- data/lib/action_view/helpers/output_safety_helper.rb +3 -3
- data/lib/action_view/helpers/record_tag_helper.rb +17 -22
- data/lib/action_view/helpers/rendering_helper.rb +2 -4
- data/lib/action_view/helpers/sanitize_helper.rb +3 -6
- data/lib/action_view/helpers/tag_helper.rb +43 -37
- data/lib/action_view/helpers/tags.rb +39 -0
- data/lib/action_view/helpers/tags/base.rb +148 -0
- data/lib/action_view/helpers/tags/check_box.rb +64 -0
- data/lib/action_view/helpers/tags/checkable.rb +16 -0
- data/lib/action_view/helpers/tags/collection_check_boxes.rb +43 -0
- data/lib/action_view/helpers/tags/collection_helpers.rb +83 -0
- data/lib/action_view/helpers/tags/collection_radio_buttons.rb +36 -0
- data/lib/action_view/helpers/tags/collection_select.rb +28 -0
- data/lib/action_view/helpers/tags/color_field.rb +25 -0
- data/lib/action_view/helpers/tags/date_field.rb +13 -0
- data/lib/action_view/helpers/tags/date_select.rb +72 -0
- data/lib/action_view/helpers/tags/datetime_field.rb +22 -0
- data/lib/action_view/helpers/tags/datetime_local_field.rb +19 -0
- data/lib/action_view/helpers/tags/datetime_select.rb +8 -0
- data/lib/action_view/helpers/tags/email_field.rb +8 -0
- data/lib/action_view/helpers/tags/file_field.rb +8 -0
- data/lib/action_view/helpers/tags/grouped_collection_select.rb +29 -0
- data/lib/action_view/helpers/tags/hidden_field.rb +8 -0
- data/lib/action_view/helpers/tags/label.rb +65 -0
- data/lib/action_view/helpers/tags/month_field.rb +13 -0
- data/lib/action_view/helpers/tags/number_field.rb +18 -0
- data/lib/action_view/helpers/tags/password_field.rb +12 -0
- data/lib/action_view/helpers/tags/radio_button.rb +31 -0
- data/lib/action_view/helpers/tags/range_field.rb +8 -0
- data/lib/action_view/helpers/tags/search_field.rb +24 -0
- data/lib/action_view/helpers/tags/select.rb +41 -0
- data/lib/action_view/helpers/tags/tel_field.rb +8 -0
- data/lib/action_view/helpers/tags/text_area.rb +18 -0
- data/lib/action_view/helpers/tags/text_field.rb +29 -0
- data/lib/action_view/helpers/tags/time_field.rb +13 -0
- data/lib/action_view/helpers/tags/time_select.rb +8 -0
- data/lib/action_view/helpers/tags/time_zone_select.rb +20 -0
- data/lib/action_view/helpers/tags/url_field.rb +8 -0
- data/lib/action_view/helpers/tags/week_field.rb +13 -0
- data/lib/action_view/helpers/text_helper.rb +126 -113
- data/lib/action_view/helpers/translation_helper.rb +32 -16
- data/lib/action_view/helpers/url_helper.rb +200 -271
- data/lib/action_view/locale/en.yml +1 -105
- data/lib/action_view/log_subscriber.rb +6 -4
- data/lib/action_view/lookup_context.rb +15 -39
- data/lib/action_view/model_naming.rb +12 -0
- data/lib/action_view/path_set.rb +9 -39
- data/lib/action_view/railtie.rb +6 -22
- data/lib/action_view/record_identifier.rb +84 -0
- data/lib/action_view/renderer/abstract_renderer.rb +10 -19
- data/lib/action_view/renderer/partial_renderer.rb +144 -81
- data/lib/action_view/renderer/renderer.rb +2 -19
- data/lib/action_view/renderer/streaming_template_renderer.rb +2 -5
- data/lib/action_view/renderer/template_renderer.rb +14 -13
- data/lib/action_view/routing_url_for.rb +107 -0
- data/lib/action_view/template.rb +22 -21
- data/lib/action_view/template/error.rb +22 -12
- data/lib/action_view/template/handlers.rb +12 -9
- data/lib/action_view/template/handlers/builder.rb +1 -1
- data/lib/action_view/template/handlers/erb.rb +11 -16
- data/lib/action_view/template/handlers/raw.rb +11 -0
- data/lib/action_view/template/resolver.rb +111 -83
- data/lib/action_view/template/text.rb +12 -8
- data/lib/action_view/template/types.rb +57 -0
- data/lib/action_view/test_case.rb +66 -43
- data/lib/action_view/testing/resolvers.rb +3 -2
- data/lib/action_view/vendor/html-scanner.rb +20 -0
- data/lib/{action_controller → action_view}/vendor/html-scanner/html/document.rb +0 -0
- data/lib/{action_controller → action_view}/vendor/html-scanner/html/node.rb +12 -12
- data/lib/{action_controller → action_view}/vendor/html-scanner/html/sanitizer.rb +18 -7
- data/lib/{action_controller → action_view}/vendor/html-scanner/html/selector.rb +1 -1
- data/lib/{action_controller → action_view}/vendor/html-scanner/html/tokenizer.rb +1 -1
- data/lib/{action_controller → action_view}/vendor/html-scanner/html/version.rb +0 -0
- metadata +135 -125
- data/lib/action_controller/caching/actions.rb +0 -185
- data/lib/action_controller/caching/pages.rb +0 -187
- data/lib/action_controller/caching/sweeping.rb +0 -97
- data/lib/action_controller/deprecated/performance_test.rb +0 -1
- data/lib/action_controller/metal/compatibility.rb +0 -65
- data/lib/action_controller/metal/session_management.rb +0 -14
- data/lib/action_controller/railties/paths.rb +0 -25
- data/lib/action_dispatch/middleware/best_standards_support.rb +0 -30
- data/lib/action_dispatch/middleware/body_proxy.rb +0 -30
- data/lib/action_dispatch/middleware/head.rb +0 -18
- data/lib/action_dispatch/middleware/rescue.rb +0 -26
- data/lib/action_dispatch/testing/performance_test.rb +0 -10
- data/lib/action_view/asset_paths.rb +0 -142
- data/lib/action_view/helpers/asset_paths.rb +0 -7
- data/lib/action_view/helpers/asset_tag_helpers/asset_include_tag.rb +0 -146
- data/lib/action_view/helpers/asset_tag_helpers/asset_paths.rb +0 -93
- data/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb +0 -193
- data/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb +0 -148
- data/lib/sprockets/assets.rake +0 -99
- data/lib/sprockets/bootstrap.rb +0 -37
- data/lib/sprockets/compressors.rb +0 -83
- data/lib/sprockets/helpers.rb +0 -6
- data/lib/sprockets/helpers/isolated_helper.rb +0 -13
- data/lib/sprockets/helpers/rails_helper.rb +0 -182
- data/lib/sprockets/railtie.rb +0 -62
- data/lib/sprockets/static_compiler.rb +0 -56
@@ -1,7 +1,6 @@
|
|
1
1
|
module ActionView
|
2
2
|
class AbstractRenderer #:nodoc:
|
3
|
-
delegate :find_template, :
|
4
|
-
:with_layout_format, :formats, :to => :@lookup_context
|
3
|
+
delegate :find_template, :template_exists?, :with_fallbacks, :with_layout_format, :formats, :to => :@lookup_context
|
5
4
|
|
6
5
|
def initialize(lookup_context)
|
7
6
|
@lookup_context = lookup_context
|
@@ -12,30 +11,22 @@ module ActionView
|
|
12
11
|
end
|
13
12
|
|
14
13
|
protected
|
15
|
-
|
14
|
+
|
16
15
|
def extract_details(options)
|
17
|
-
|
18
|
-
@lookup_context.registered_details.each do |key|
|
16
|
+
@lookup_context.registered_details.each_with_object({}) do |key, details|
|
19
17
|
next unless value = options[key]
|
20
|
-
details[key] = Array
|
21
|
-
end
|
22
|
-
details
|
23
|
-
end
|
24
|
-
|
25
|
-
def extract_format(value, details)
|
26
|
-
if value.is_a?(String) && value.sub!(formats_regexp, "")
|
27
|
-
ActiveSupport::Deprecation.warn "Passing the format in the template name is deprecated. " \
|
28
|
-
"Please pass render with :formats => [:#{$1}] instead.", caller
|
29
|
-
details[:formats] ||= [$1.to_sym]
|
18
|
+
details[key] = Array(value)
|
30
19
|
end
|
31
20
|
end
|
32
21
|
|
33
|
-
def formats_regexp
|
34
|
-
@@formats_regexp ||= /\.(#{Mime::SET.symbols.join('|')})$/
|
35
|
-
end
|
36
|
-
|
37
22
|
def instrument(name, options={})
|
38
23
|
ActiveSupport::Notifications.instrument("render_#{name}.action_view", options){ yield }
|
39
24
|
end
|
25
|
+
|
26
|
+
def prepend_formats(formats)
|
27
|
+
formats = Array(formats)
|
28
|
+
return if formats.empty? || @lookup_context.html_fallback_for_js
|
29
|
+
@lookup_context.formats = formats | @lookup_context.formats
|
30
|
+
end
|
40
31
|
end
|
41
32
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require '
|
1
|
+
require 'thread_safe'
|
2
2
|
|
3
3
|
module ActionView
|
4
4
|
# = Action View Partials
|
@@ -10,16 +10,16 @@ module ActionView
|
|
10
10
|
#
|
11
11
|
# In a template for Advertiser#account:
|
12
12
|
#
|
13
|
-
# <%= render :
|
13
|
+
# <%= render partial: "account" %>
|
14
14
|
#
|
15
15
|
# This would render "advertiser/_account.html.erb".
|
16
16
|
#
|
17
17
|
# In another template for Advertiser#buy, we could have:
|
18
18
|
#
|
19
|
-
# <%= render :
|
19
|
+
# <%= render partial: "account", locals: { account: @buyer } %>
|
20
20
|
#
|
21
21
|
# <% @advertisements.each do |ad| %>
|
22
|
-
# <%= render :
|
22
|
+
# <%= render partial: "ad", locals: { ad: ad } %>
|
23
23
|
# <% end %>
|
24
24
|
#
|
25
25
|
# This would first render "advertiser/_account.html.erb" with @buyer passed in as the local variable +account+, then
|
@@ -30,21 +30,21 @@ module ActionView
|
|
30
30
|
# By default <tt>ActionView::PartialRenderer</tt> doesn't have any local variables.
|
31
31
|
# The <tt>:object</tt> option can be used to pass an object to the partial. For instance:
|
32
32
|
#
|
33
|
-
# <%= render :
|
33
|
+
# <%= render partial: "account", object: @buyer %>
|
34
34
|
#
|
35
|
-
# would provide the
|
35
|
+
# would provide the <tt>@buyer</tt> object to the partial, available under the local variable +account+ and is
|
36
36
|
# equivalent to:
|
37
37
|
#
|
38
|
-
# <%= render :
|
38
|
+
# <%= render partial: "account", locals: { account: @buyer } %>
|
39
39
|
#
|
40
40
|
# With the <tt>:as</tt> option we can specify a different name for said local variable. For example, if we
|
41
41
|
# wanted it to be +user+ instead of +account+ we'd do:
|
42
42
|
#
|
43
|
-
# <%= render :
|
43
|
+
# <%= render partial: "account", object: @buyer, as: 'user' %>
|
44
44
|
#
|
45
45
|
# This is equivalent to
|
46
46
|
#
|
47
|
-
# <%= render :
|
47
|
+
# <%= render partial: "account", locals: { user: @buyer } %>
|
48
48
|
#
|
49
49
|
# == Rendering a collection of partials
|
50
50
|
#
|
@@ -53,7 +53,7 @@ module ActionView
|
|
53
53
|
# accepts an array and renders a partial by the same name as the elements contained within. So the three-lined
|
54
54
|
# example in "Using partials" can be rewritten with a single line:
|
55
55
|
#
|
56
|
-
# <%= render :
|
56
|
+
# <%= render partial: "ad", collection: @advertisements %>
|
57
57
|
#
|
58
58
|
# This will render "advertiser/_ad.html.erb" and pass the local variable +ad+ to the template for display. An
|
59
59
|
# iteration counter will automatically be made available to the template with a name of the form
|
@@ -64,12 +64,12 @@ module ActionView
|
|
64
64
|
# You can specify a partial to be rendered between elements via the <tt>:spacer_template</tt> option.
|
65
65
|
# The following example will render <tt>advertiser/_ad_divider.html.erb</tt> between each ad partial:
|
66
66
|
#
|
67
|
-
# <%= render :
|
67
|
+
# <%= render partial: "ad", collection: @advertisements, spacer_template: "ad_divider" %>
|
68
68
|
#
|
69
69
|
# If the given <tt>:collection</tt> is nil or empty, <tt>render</tt> will return nil. This will allow you
|
70
70
|
# to specify a text which will displayed instead by using this form:
|
71
71
|
#
|
72
|
-
# <%= render(:
|
72
|
+
# <%= render(partial: "ad", collection: @advertisements) || "There's no ad to be displayed" %>
|
73
73
|
#
|
74
74
|
# NOTE: Due to backwards compatibility concerns, the collection can't be one of hashes. Normally you'd also
|
75
75
|
# just keep domain objects, like Active Records, in there.
|
@@ -78,43 +78,42 @@ module ActionView
|
|
78
78
|
#
|
79
79
|
# Two controllers can share a set of partials and render them like this:
|
80
80
|
#
|
81
|
-
# <%= render :
|
81
|
+
# <%= render partial: "advertisement/ad", locals: { ad: @advertisement } %>
|
82
82
|
#
|
83
83
|
# This will render the partial "advertisement/_ad.html.erb" regardless of which controller this is being called from.
|
84
84
|
#
|
85
85
|
# == Rendering objects that respond to `to_partial_path`
|
86
86
|
#
|
87
87
|
# Instead of explicitly naming the location of a partial, you can also let PartialRenderer do the work
|
88
|
-
# and pick the proper path by checking `
|
89
|
-
# all objects must return the same path.
|
88
|
+
# and pick the proper path by checking `to_partial_path` method.
|
90
89
|
#
|
91
90
|
# # @account.to_partial_path returns 'accounts/account', so it can be used to replace:
|
92
|
-
# # <%= render :
|
93
|
-
# <%= render :
|
91
|
+
# # <%= render partial: "accounts/account", locals: { account: @account} %>
|
92
|
+
# <%= render partial: @account %>
|
94
93
|
#
|
95
94
|
# # @posts is an array of Post instances, so every post record returns 'posts/post' on `to_partial_path`,
|
96
95
|
# # that's why we can replace:
|
97
|
-
# # <%= render :
|
98
|
-
# <%= render :
|
96
|
+
# # <%= render partial: "posts/post", collection: @posts %>
|
97
|
+
# <%= render partial: @posts %>
|
99
98
|
#
|
100
99
|
# == Rendering the default case
|
101
100
|
#
|
102
101
|
# If you're not going to be using any of the options like collections or layouts, you can also use the short-hand
|
103
102
|
# defaults of render to render partials. Examples:
|
104
103
|
#
|
105
|
-
# # Instead of <%= render :
|
104
|
+
# # Instead of <%= render partial: "account" %>
|
106
105
|
# <%= render "account" %>
|
107
106
|
#
|
108
|
-
# # Instead of <%= render :
|
109
|
-
# <%= render "account", :
|
107
|
+
# # Instead of <%= render partial: "account", locals: { account: @buyer } %>
|
108
|
+
# <%= render "account", account: @buyer %>
|
110
109
|
#
|
111
110
|
# # @account.to_partial_path returns 'accounts/account', so it can be used to replace:
|
112
|
-
# # <%= render :
|
111
|
+
# # <%= render partial: "accounts/account", locals: { account: @account} %>
|
113
112
|
# <%= render @account %>
|
114
113
|
#
|
115
114
|
# # @posts is an array of Post instances, so every post record returns 'posts/post' on `to_partial_path`,
|
116
115
|
# # that's why we can replace:
|
117
|
-
# # <%= render :
|
116
|
+
# # <%= render partial: "posts/post", collection: @posts %>
|
118
117
|
# <%= render @posts %>
|
119
118
|
#
|
120
119
|
# == Rendering partials with layouts
|
@@ -125,10 +124,10 @@ module ActionView
|
|
125
124
|
#
|
126
125
|
# <%# app/views/users/index.html.erb &>
|
127
126
|
# Here's the administrator:
|
128
|
-
# <%= render :
|
127
|
+
# <%= render partial: "user", layout: "administrator", locals: { user: administrator } %>
|
129
128
|
#
|
130
129
|
# Here's the editor:
|
131
|
-
# <%= render :
|
130
|
+
# <%= render partial: "user", layout: "editor", locals: { user: editor } %>
|
132
131
|
#
|
133
132
|
# <%# app/views/users/_user.html.erb &>
|
134
133
|
# Name: <%= user.name %>
|
@@ -159,10 +158,51 @@ module ActionView
|
|
159
158
|
# Name: <%= user.name %>
|
160
159
|
# </div>
|
161
160
|
#
|
161
|
+
# If a collection is given, the layout will be rendered once for each item in
|
162
|
+
# the collection. Just think these two snippets have the same output:
|
163
|
+
#
|
164
|
+
# <%# app/views/users/_user.html.erb %>
|
165
|
+
# Name: <%= user.name %>
|
166
|
+
#
|
167
|
+
# <%# app/views/users/index.html.erb %>
|
168
|
+
# <%# This does not use layouts %>
|
169
|
+
# <ul>
|
170
|
+
# <% users.each do |user| -%>
|
171
|
+
# <li>
|
172
|
+
# <%= render partial: "user", locals: { user: user } %>
|
173
|
+
# </li>
|
174
|
+
# <% end -%>
|
175
|
+
# </ul>
|
176
|
+
#
|
177
|
+
# <%# app/views/users/_li_layout.html.erb %>
|
178
|
+
# <li>
|
179
|
+
# <%= yield %>
|
180
|
+
# </li>
|
181
|
+
#
|
182
|
+
# <%# app/views/users/index.html.erb %>
|
183
|
+
# <ul>
|
184
|
+
# <%= render partial: "user", layout: "li_layout", collection: users %>
|
185
|
+
# </ul>
|
186
|
+
#
|
187
|
+
# Given two users whose names are Alice and Bob, these snippets return:
|
188
|
+
#
|
189
|
+
# <ul>
|
190
|
+
# <li>
|
191
|
+
# Name: Alice
|
192
|
+
# </li>
|
193
|
+
# <li>
|
194
|
+
# Name: Bob
|
195
|
+
# </li>
|
196
|
+
# </ul>
|
197
|
+
#
|
198
|
+
# The current object being rendered, as well as the object_counter, will be
|
199
|
+
# available as local variables inside the layout template under the same names
|
200
|
+
# as available in the partial.
|
201
|
+
#
|
162
202
|
# You can also apply a layout to a block within any template:
|
163
203
|
#
|
164
204
|
# <%# app/views/users/_chief.html.erb &>
|
165
|
-
# <%= render(:
|
205
|
+
# <%= render(layout: "administrator", locals: { user: chief }) do %>
|
166
206
|
# Title: <%= chief.title %>
|
167
207
|
# <% end %>
|
168
208
|
#
|
@@ -185,7 +225,7 @@ module ActionView
|
|
185
225
|
# </div>
|
186
226
|
#
|
187
227
|
# <%# app/views/users/index.html.erb &>
|
188
|
-
# <%= render :
|
228
|
+
# <%= render layout: @users do |user| %>
|
189
229
|
# Title: <%= user.title %>
|
190
230
|
# <% end %>
|
191
231
|
#
|
@@ -201,7 +241,7 @@ module ActionView
|
|
201
241
|
# </div>
|
202
242
|
#
|
203
243
|
# <%# app/views/users/index.html.erb &>
|
204
|
-
# <%= render :
|
244
|
+
# <%= render layout: @users do |user, section| %>
|
205
245
|
# <%- case section when :header -%>
|
206
246
|
# Title: <%= user.title %>
|
207
247
|
# <%- when :footer -%>
|
@@ -209,12 +249,13 @@ module ActionView
|
|
209
249
|
# <%- end -%>
|
210
250
|
# <% end %>
|
211
251
|
class PartialRenderer < AbstractRenderer
|
212
|
-
|
252
|
+
PREFIXED_PARTIAL_NAMES = ThreadSafe::Cache.new do |h, k|
|
253
|
+
h[k] = ThreadSafe::Cache.new
|
254
|
+
end
|
213
255
|
|
214
256
|
def initialize(*)
|
215
257
|
super
|
216
258
|
@context_prefix = @lookup_context.prefixes.first
|
217
|
-
@partial_names = PARTIAL_NAMES[@context_prefix]
|
218
259
|
end
|
219
260
|
|
220
261
|
def render(context, options, block)
|
@@ -244,7 +285,7 @@ module ActionView
|
|
244
285
|
return nil if @collection.blank?
|
245
286
|
|
246
287
|
if @options.key?(:spacer_template)
|
247
|
-
spacer = find_template(@options[:spacer_template]).render(@view, @locals)
|
288
|
+
spacer = find_template(@options[:spacer_template], @locals.keys).render(@view, @locals)
|
248
289
|
end
|
249
290
|
|
250
291
|
result = @template ? collection_with_template : collection_without_template
|
@@ -252,11 +293,11 @@ module ActionView
|
|
252
293
|
end
|
253
294
|
|
254
295
|
def render_partial
|
255
|
-
|
296
|
+
view, locals, block = @view, @locals, @block
|
256
297
|
object, as = @object, @variable
|
257
298
|
|
258
299
|
if !block && (layout = @options[:layout])
|
259
|
-
layout = find_template(layout.to_s)
|
300
|
+
layout = find_template(layout.to_s, @template_keys)
|
260
301
|
end
|
261
302
|
|
262
303
|
object ||= locals[as]
|
@@ -281,6 +322,8 @@ module ActionView
|
|
281
322
|
@block = block
|
282
323
|
@details = extract_details(options)
|
283
324
|
|
325
|
+
prepend_formats(options[:formats])
|
326
|
+
|
284
327
|
if String === partial
|
285
328
|
@object = options[:object]
|
286
329
|
@path = partial
|
@@ -296,19 +339,18 @@ module ActionView
|
|
296
339
|
end
|
297
340
|
end
|
298
341
|
|
299
|
-
if
|
300
|
-
|
301
|
-
|
302
|
-
paths.map! { |path| retrieve_variable(path).unshift(path) }
|
342
|
+
if as = options[:as]
|
343
|
+
raise_invalid_identifier(as) unless as.to_s =~ /\A[a-z_]\w*\z/
|
344
|
+
as = as.to_sym
|
303
345
|
end
|
304
346
|
|
305
|
-
if
|
306
|
-
|
307
|
-
|
308
|
-
|
347
|
+
if @path
|
348
|
+
@variable, @variable_counter = retrieve_variable(@path, as)
|
349
|
+
@template_keys = retrieve_template_keys
|
350
|
+
else
|
351
|
+
paths.map! { |path| retrieve_variable(path, as).unshift(path) }
|
309
352
|
end
|
310
353
|
|
311
|
-
extract_format(@path, @details)
|
312
354
|
self
|
313
355
|
end
|
314
356
|
|
@@ -320,55 +362,55 @@ module ActionView
|
|
320
362
|
end
|
321
363
|
|
322
364
|
def collection_from_object
|
323
|
-
if @object.respond_to?(:to_ary)
|
324
|
-
@object.to_ary
|
325
|
-
end
|
365
|
+
@object.to_ary if @object.respond_to?(:to_ary)
|
326
366
|
end
|
327
367
|
|
328
368
|
def find_partial
|
329
369
|
if path = @path
|
330
|
-
|
331
|
-
locals << @variable
|
332
|
-
locals << @variable_counter if @collection
|
333
|
-
find_template(path, locals)
|
370
|
+
find_template(path, @template_keys)
|
334
371
|
end
|
335
372
|
end
|
336
373
|
|
337
|
-
def find_template(path
|
374
|
+
def find_template(path, locals)
|
338
375
|
prefixes = path.include?(?/) ? [] : @lookup_context.prefixes
|
339
376
|
@lookup_context.find_template(path, prefixes, true, locals, @details)
|
340
377
|
end
|
341
378
|
|
342
379
|
def collection_with_template
|
343
|
-
|
380
|
+
view, locals, template = @view, @locals, @template
|
344
381
|
as, counter = @variable, @variable_counter
|
345
382
|
|
346
|
-
|
347
|
-
|
348
|
-
@collection.each do |object|
|
349
|
-
locals[counter] += 1
|
350
|
-
locals[as] = object
|
351
|
-
segments << template.render(@view, locals)
|
383
|
+
if layout = @options[:layout]
|
384
|
+
layout = find_template(layout, @template_keys)
|
352
385
|
end
|
353
386
|
|
354
|
-
|
387
|
+
index = -1
|
388
|
+
@collection.map do |object|
|
389
|
+
locals[as] = object
|
390
|
+
locals[counter] = (index += 1)
|
391
|
+
|
392
|
+
content = template.render(view, locals)
|
393
|
+
content = layout.render(view, locals) { content } if layout
|
394
|
+
content
|
395
|
+
end
|
355
396
|
end
|
356
397
|
|
357
398
|
def collection_without_template
|
358
|
-
|
359
|
-
|
360
|
-
keys
|
399
|
+
view, locals, collection_data = @view, @locals, @collection_data
|
400
|
+
cache = {}
|
401
|
+
keys = @locals.keys
|
361
402
|
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
locals[data[1]] = (index += 1)
|
367
|
-
segments << template.render(@view, locals)
|
368
|
-
end
|
403
|
+
index = -1
|
404
|
+
@collection.map do |object|
|
405
|
+
index += 1
|
406
|
+
path, as, counter = collection_data[index]
|
369
407
|
|
370
|
-
|
371
|
-
|
408
|
+
locals[as] = object
|
409
|
+
locals[counter] = index
|
410
|
+
|
411
|
+
template = (cache[path] ||= find_template(path, keys + [as, counter]))
|
412
|
+
template.render(view, locals)
|
413
|
+
end
|
372
414
|
end
|
373
415
|
|
374
416
|
def partial_path(object = @object)
|
@@ -377,16 +419,18 @@ module ActionView
|
|
377
419
|
path = if object.respond_to?(:to_partial_path)
|
378
420
|
object.to_partial_path
|
379
421
|
else
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
422
|
+
raise ArgumentError.new("'#{object.inspect}' is not an ActiveModel-compatible object. It must implement :to_partial_path.")
|
423
|
+
end
|
424
|
+
|
425
|
+
if @view.prefix_partial_path_with_controller_namespace
|
426
|
+
prefixed_partial_names[path] ||= merge_prefix_into_object_path(@context_prefix, path.dup)
|
427
|
+
else
|
428
|
+
path
|
387
429
|
end
|
430
|
+
end
|
388
431
|
|
389
|
-
|
432
|
+
def prefixed_partial_names
|
433
|
+
@prefixed_partial_names ||= PREFIXED_PARTIAL_NAMES[@context_prefix]
|
390
434
|
end
|
391
435
|
|
392
436
|
def merge_prefix_into_object_path(prefix, object_path)
|
@@ -406,10 +450,29 @@ module ActionView
|
|
406
450
|
end
|
407
451
|
end
|
408
452
|
|
409
|
-
def
|
410
|
-
|
453
|
+
def retrieve_template_keys
|
454
|
+
keys = @locals.keys
|
455
|
+
keys << @variable if @object || @collection
|
456
|
+
keys << @variable_counter if @collection
|
457
|
+
keys
|
458
|
+
end
|
459
|
+
|
460
|
+
def retrieve_variable(path, as)
|
461
|
+
variable = as || begin
|
462
|
+
base = path[-1] == "/" ? "" : File.basename(path)
|
463
|
+
raise_invalid_identifier(path) unless base =~ /\A_?([a-z]\w*)(\.\w+)*\z/
|
464
|
+
$1.to_sym
|
465
|
+
end
|
411
466
|
variable_counter = :"#{variable}_counter" if @collection
|
412
467
|
[variable, variable_counter]
|
413
468
|
end
|
469
|
+
|
470
|
+
IDENTIFIER_ERROR_MESSAGE = "The partial name (%s) is not a valid Ruby identifier; " +
|
471
|
+
"make sure your partial name starts with a lowercase letter or underscore, " +
|
472
|
+
"and is followed by any combination of letters, numbers and underscores."
|
473
|
+
|
474
|
+
def raise_invalid_identifier(path)
|
475
|
+
raise ArgumentError.new(IDENTIFIER_ERROR_MESSAGE % (path))
|
476
|
+
end
|
414
477
|
end
|
415
478
|
end
|