actionpack 3.1.12 → 3.2.0.rc1
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.
- data/CHANGELOG.md +5503 -108
- data/README.rdoc +3 -3
- data/lib/abstract_controller/asset_paths.rb +1 -1
- data/lib/abstract_controller/base.rb +1 -1
- data/lib/abstract_controller/callbacks.rb +102 -18
- data/lib/abstract_controller/helpers.rb +1 -1
- data/lib/abstract_controller/layouts.rb +116 -50
- data/lib/abstract_controller/logger.rb +1 -1
- data/lib/abstract_controller/railties/routes_helpers.rb +2 -2
- data/lib/abstract_controller/rendering.rb +1 -6
- data/lib/abstract_controller/view_paths.rb +6 -5
- data/lib/action_controller.rb +0 -15
- data/lib/action_controller/caching.rb +0 -1
- data/lib/action_controller/caching/actions.rb +5 -6
- data/lib/action_controller/caching/fragments.rb +18 -18
- data/lib/action_controller/caching/pages.rb +7 -6
- data/lib/action_controller/caching/sweeping.rb +1 -1
- data/lib/action_controller/log_subscriber.rb +8 -4
- data/lib/action_controller/metal.rb +7 -1
- data/lib/action_controller/metal/conditional_get.rb +49 -4
- data/lib/action_controller/metal/data_streaming.rb +17 -5
- data/lib/action_controller/metal/force_ssl.rb +8 -5
- data/lib/action_controller/metal/helpers.rb +7 -4
- data/lib/action_controller/metal/http_authentication.rb +9 -12
- data/lib/action_controller/metal/instrumentation.rb +9 -4
- data/lib/action_controller/metal/mime_responds.rb +4 -4
- data/lib/action_controller/metal/params_wrapper.rb +12 -8
- data/lib/action_controller/metal/redirecting.rb +7 -6
- data/lib/action_controller/metal/renderers.rb +9 -11
- data/lib/action_controller/metal/request_forgery_protection.rb +2 -1
- data/lib/action_controller/metal/rescue.rb +13 -0
- data/lib/action_controller/metal/responder.rb +11 -23
- data/lib/action_controller/metal/streaming.rb +0 -25
- data/lib/action_controller/railtie.rb +1 -0
- data/lib/action_controller/railties/paths.rb +4 -3
- data/lib/action_controller/record_identifier.rb +4 -4
- data/lib/action_controller/test_case.rb +60 -56
- data/lib/action_controller/vendor/html-scanner/html/sanitizer.rb +6 -6
- data/lib/action_dispatch.rb +5 -1
- data/lib/action_dispatch/http/cache.rb +27 -15
- data/lib/action_dispatch/http/filter_parameters.rb +3 -1
- data/lib/action_dispatch/http/headers.rb +3 -5
- data/lib/action_dispatch/http/mime_negotiation.rb +2 -1
- data/lib/action_dispatch/http/mime_type.rb +7 -3
- data/lib/action_dispatch/http/mime_types.rb +12 -0
- data/lib/action_dispatch/http/parameter_filter.rb +3 -1
- data/lib/action_dispatch/http/parameters.rb +0 -4
- data/lib/action_dispatch/http/request.rb +18 -68
- data/lib/action_dispatch/http/response.rb +11 -32
- data/lib/action_dispatch/http/upload.rb +3 -14
- data/lib/action_dispatch/http/url.rb +1 -1
- data/lib/action_dispatch/middleware/callbacks.rb +1 -2
- data/lib/action_dispatch/middleware/cookies.rb +20 -16
- data/lib/action_dispatch/middleware/debug_exceptions.rb +82 -0
- data/lib/action_dispatch/middleware/exception_wrapper.rb +78 -0
- data/lib/action_dispatch/middleware/flash.rb +6 -9
- data/lib/action_dispatch/middleware/params_parser.rb +6 -11
- data/lib/action_dispatch/middleware/public_exceptions.rb +30 -0
- data/lib/action_dispatch/middleware/reloader.rb +38 -14
- data/lib/action_dispatch/middleware/remote_ip.rb +66 -36
- data/lib/action_dispatch/middleware/request_id.rb +39 -0
- data/lib/action_dispatch/middleware/session/abstract_store.rb +4 -16
- data/lib/action_dispatch/middleware/session/cache_store.rb +50 -0
- data/lib/action_dispatch/middleware/session/cookie_store.rb +1 -1
- data/lib/action_dispatch/middleware/show_exceptions.rb +58 -142
- data/lib/action_dispatch/middleware/static.rb +2 -10
- data/lib/action_dispatch/middleware/templates/rescues/layout.erb +1 -0
- data/lib/action_dispatch/middleware/templates/rescues/routing_error.erb +13 -8
- data/lib/action_dispatch/railtie.rb +15 -1
- data/lib/action_dispatch/routing.rb +1 -2
- data/lib/action_dispatch/routing/mapper.rb +108 -107
- data/lib/action_dispatch/routing/redirection.rb +63 -69
- data/lib/action_dispatch/routing/route_set.rb +75 -43
- data/lib/action_dispatch/routing/routes_proxy.rb +0 -4
- data/lib/action_dispatch/routing/url_for.rb +3 -3
- data/lib/action_dispatch/testing/assertions/response.rb +5 -7
- data/lib/action_dispatch/testing/assertions/routing.rb +10 -9
- data/lib/action_dispatch/testing/integration.rb +8 -25
- data/lib/action_dispatch/testing/test_process.rb +3 -2
- data/lib/action_dispatch/testing/test_request.rb +4 -23
- data/lib/action_pack/version.rb +3 -3
- data/lib/action_view.rb +1 -5
- data/lib/action_view/asset_paths.rb +7 -8
- data/lib/action_view/base.rb +7 -5
- data/lib/action_view/helpers/asset_paths.rb +1 -1
- data/lib/action_view/helpers/asset_tag_helper.rb +4 -8
- data/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb +3 -0
- data/lib/action_view/helpers/atom_feed_helper.rb +2 -2
- data/lib/action_view/helpers/capture_helper.rb +3 -3
- data/lib/action_view/helpers/controller_helper.rb +1 -1
- data/lib/action_view/helpers/date_helper.rb +26 -18
- data/lib/action_view/helpers/debug_helper.rb +1 -1
- data/lib/action_view/helpers/form_helper.rb +71 -13
- data/lib/action_view/helpers/form_options_helper.rb +65 -34
- data/lib/action_view/helpers/form_tag_helper.rb +24 -18
- data/lib/action_view/helpers/javascript_helper.rb +12 -3
- data/lib/action_view/helpers/number_helper.rb +3 -2
- data/lib/action_view/helpers/record_tag_helper.rb +51 -5
- data/lib/action_view/helpers/rendering_helper.rb +2 -2
- data/lib/action_view/helpers/sanitize_helper.rb +6 -7
- data/lib/action_view/helpers/tag_helper.rb +1 -1
- data/lib/action_view/helpers/text_helper.rb +5 -4
- data/lib/action_view/helpers/url_helper.rb +19 -11
- data/lib/action_view/locale/en.yml +6 -0
- data/lib/action_view/log_subscriber.rb +1 -1
- data/lib/action_view/lookup_context.rb +123 -125
- data/lib/action_view/path_set.rb +60 -13
- data/lib/action_view/renderer/abstract_renderer.rb +16 -11
- data/lib/action_view/renderer/partial_renderer.rb +59 -40
- data/lib/action_view/renderer/template_renderer.rb +29 -17
- data/lib/action_view/template.rb +0 -1
- data/lib/action_view/template/error.rb +6 -5
- data/lib/action_view/template/handlers.rb +0 -6
- data/lib/action_view/template/handlers/builder.rb +10 -1
- data/lib/action_view/template/handlers/erb.rb +2 -2
- data/lib/action_view/template/resolver.rb +20 -31
- data/lib/action_view/test_case.rb +7 -10
- data/lib/sprockets/assets.rake +1 -1
- data/lib/sprockets/bootstrap.rb +3 -31
- data/lib/sprockets/compressors.rb +69 -7
- data/lib/sprockets/helpers/rails_helper.rb +6 -11
- data/lib/sprockets/railtie.rb +1 -0
- data/lib/sprockets/static_compiler.rb +0 -3
- metadata +57 -86
- checksums.yaml +0 -7
- data/lib/action_dispatch/middleware/closed_error.rb +0 -7
- data/lib/action_dispatch/routing/route.rb +0 -67
- data/lib/action_view/template/handler.rb +0 -49
data/README.rdoc
CHANGED
@@ -283,7 +283,7 @@ methods:
|
|
283
283
|
|
284
284
|
The last two lines are responsible for telling ActionController where the
|
285
285
|
template files are located and actually running the controller on a new
|
286
|
-
request from the web-server (
|
286
|
+
request from the web-server (e.g., Apache).
|
287
287
|
|
288
288
|
And the templates look like this:
|
289
289
|
|
@@ -316,7 +316,7 @@ an URL such as /weblog/5 (where 5 is the id of the post).
|
|
316
316
|
|
317
317
|
== Download and installation
|
318
318
|
|
319
|
-
The latest version of Action Pack can be installed with
|
319
|
+
The latest version of Action Pack can be installed with RubyGems:
|
320
320
|
|
321
321
|
% [sudo] gem install actionpack
|
322
322
|
|
@@ -334,7 +334,7 @@ Action Pack is released under the MIT license.
|
|
334
334
|
|
335
335
|
API documentation is at
|
336
336
|
|
337
|
-
* http://api.rubyonrails.
|
337
|
+
* http://api.rubyonrails.org
|
338
338
|
|
339
339
|
Bug reports and feature requests can be filed with the rest for the Ruby on Rails project here:
|
340
340
|
|
@@ -10,7 +10,7 @@ module AbstractController
|
|
10
10
|
# <tt>AbstractController::Base</tt> is a low-level API. Nobody should be
|
11
11
|
# using it directly, and subclasses (like ActionController::Base) are
|
12
12
|
# expected to provide their own +render+ method, since rendering means
|
13
|
-
# different things depending on the context.
|
13
|
+
# different things depending on the context.
|
14
14
|
class Base
|
15
15
|
attr_internal :response_body
|
16
16
|
attr_internal :action_name
|
@@ -75,38 +75,122 @@ module AbstractController
|
|
75
75
|
end
|
76
76
|
end
|
77
77
|
|
78
|
+
##
|
79
|
+
# :method: before_filter
|
80
|
+
#
|
81
|
+
# :call-seq: before_filter(names, block)
|
82
|
+
#
|
83
|
+
# Append a before filter. See _insert_callbacks for parameter details.
|
84
|
+
|
85
|
+
##
|
86
|
+
# :method: prepend_before_filter
|
87
|
+
#
|
88
|
+
# :call-seq: prepend_before_filter(names, block)
|
89
|
+
#
|
90
|
+
# Prepend a before filter. See _insert_callbacks for parameter details.
|
91
|
+
|
92
|
+
##
|
93
|
+
# :method: skip_before_filter
|
94
|
+
#
|
95
|
+
# :call-seq: skip_before_filter(names, block)
|
96
|
+
#
|
97
|
+
# Skip a before filter. See _insert_callbacks for parameter details.
|
98
|
+
|
99
|
+
##
|
100
|
+
# :method: append_before_filter
|
101
|
+
#
|
102
|
+
# :call-seq: append_before_filter(names, block)
|
103
|
+
#
|
104
|
+
# Append a before filter. See _insert_callbacks for parameter details.
|
105
|
+
|
106
|
+
##
|
107
|
+
# :method: after_filter
|
108
|
+
#
|
109
|
+
# :call-seq: after_filter(names, block)
|
110
|
+
#
|
111
|
+
# Append an after filter. See _insert_callbacks for parameter details.
|
112
|
+
|
113
|
+
##
|
114
|
+
# :method: prepend_after_filter
|
115
|
+
#
|
116
|
+
# :call-seq: prepend_after_filter(names, block)
|
117
|
+
#
|
118
|
+
# Prepend an after filter. See _insert_callbacks for parameter details.
|
119
|
+
|
120
|
+
##
|
121
|
+
# :method: skip_after_filter
|
122
|
+
#
|
123
|
+
# :call-seq: skip_after_filter(names, block)
|
124
|
+
#
|
125
|
+
# Skip an after filter. See _insert_callbacks for parameter details.
|
126
|
+
|
127
|
+
##
|
128
|
+
# :method: append_after_filter
|
129
|
+
#
|
130
|
+
# :call-seq: append_after_filter(names, block)
|
131
|
+
#
|
132
|
+
# Append an after filter. See _insert_callbacks for parameter details.
|
133
|
+
|
134
|
+
##
|
135
|
+
# :method: around_filter
|
136
|
+
#
|
137
|
+
# :call-seq: around_filter(names, block)
|
138
|
+
#
|
139
|
+
# Append an around filter. See _insert_callbacks for parameter details.
|
140
|
+
|
141
|
+
##
|
142
|
+
# :method: prepend_around_filter
|
143
|
+
#
|
144
|
+
# :call-seq: prepend_around_filter(names, block)
|
145
|
+
#
|
146
|
+
# Prepend an around filter. See _insert_callbacks for parameter details.
|
147
|
+
|
148
|
+
##
|
149
|
+
# :method: skip_around_filter
|
150
|
+
#
|
151
|
+
# :call-seq: skip_around_filter(names, block)
|
152
|
+
#
|
153
|
+
# Skip an around filter. See _insert_callbacks for parameter details.
|
154
|
+
|
155
|
+
##
|
156
|
+
# :method: append_around_filter
|
157
|
+
#
|
158
|
+
# :call-seq: append_around_filter(names, block)
|
159
|
+
#
|
160
|
+
# Append an around filter. See _insert_callbacks for parameter details.
|
161
|
+
|
78
162
|
# set up before_filter, prepend_before_filter, skip_before_filter, etc.
|
79
163
|
# for each of before, after, and around.
|
80
164
|
[:before, :after, :around].each do |filter|
|
81
165
|
class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
|
82
166
|
# Append a before, after or around filter. See _insert_callbacks
|
83
167
|
# for details on the allowed parameters.
|
84
|
-
def #{filter}_filter(*names, &blk)
|
85
|
-
_insert_callbacks(names, blk) do |name, options|
|
86
|
-
options[:if] = (Array.wrap(options[:if]) << "!halted") if #{filter == :after}
|
87
|
-
set_callback(:process_action, :#{filter}, name, options)
|
88
|
-
end
|
89
|
-
end
|
168
|
+
def #{filter}_filter(*names, &blk) # def before_filter(*names, &blk)
|
169
|
+
_insert_callbacks(names, blk) do |name, options| # _insert_callbacks(names, blk) do |name, options|
|
170
|
+
options[:if] = (Array.wrap(options[:if]) << "!halted") if #{filter == :after} # options[:if] = (Array.wrap(options[:if]) << "!halted") if false
|
171
|
+
set_callback(:process_action, :#{filter}, name, options) # set_callback(:process_action, :before, name, options)
|
172
|
+
end # end
|
173
|
+
end # end
|
90
174
|
|
91
175
|
# Prepend a before, after or around filter. See _insert_callbacks
|
92
176
|
# for details on the allowed parameters.
|
93
|
-
def prepend_#{filter}_filter(*names, &blk)
|
94
|
-
_insert_callbacks(names, blk) do |name, options|
|
95
|
-
options[:if] = (Array.wrap(options[:if]) << "!halted") if #{filter == :after}
|
96
|
-
set_callback(:process_action, :#{filter}, name, options.merge(:prepend => true))
|
97
|
-
end
|
98
|
-
end
|
177
|
+
def prepend_#{filter}_filter(*names, &blk) # def prepend_before_filter(*names, &blk)
|
178
|
+
_insert_callbacks(names, blk) do |name, options| # _insert_callbacks(names, blk) do |name, options|
|
179
|
+
options[:if] = (Array.wrap(options[:if]) << "!halted") if #{filter == :after} # options[:if] = (Array.wrap(options[:if]) << "!halted") if false
|
180
|
+
set_callback(:process_action, :#{filter}, name, options.merge(:prepend => true)) # set_callback(:process_action, :before, name, options.merge(:prepend => true))
|
181
|
+
end # end
|
182
|
+
end # end
|
99
183
|
|
100
184
|
# Skip a before, after or around filter. See _insert_callbacks
|
101
185
|
# for details on the allowed parameters.
|
102
|
-
def skip_#{filter}_filter(*names, &blk)
|
103
|
-
_insert_callbacks(names, blk) do |name, options|
|
104
|
-
skip_callback(:process_action, :#{filter}, name, options)
|
105
|
-
end
|
106
|
-
end
|
186
|
+
def skip_#{filter}_filter(*names, &blk) # def skip_before_filter(*names, &blk)
|
187
|
+
_insert_callbacks(names, blk) do |name, options| # _insert_callbacks(names, blk) do |name, options|
|
188
|
+
skip_callback(:process_action, :#{filter}, name, options) # skip_callback(:process_action, :before, name, options)
|
189
|
+
end # end
|
190
|
+
end # end
|
107
191
|
|
108
192
|
# *_filter is the same as append_*_filter
|
109
|
-
alias_method :append_#{filter}_filter, :#{filter}_filter
|
193
|
+
alias_method :append_#{filter}_filter, :#{filter}_filter # alias_method :append_before_filter, :before_filter
|
110
194
|
RUBY_EVAL
|
111
195
|
end
|
112
196
|
end
|
@@ -67,7 +67,7 @@ module AbstractController
|
|
67
67
|
# helper FooHelper # => includes FooHelper
|
68
68
|
#
|
69
69
|
# When the argument is a string or symbol, the method will provide the "_helper" suffix, require the file
|
70
|
-
# and include the module in the template class.
|
70
|
+
# and include the module in the template class. The second form illustrates how to include custom helpers
|
71
71
|
# when working with namespaced controllers, or other cases where the file containing the helper definition is not
|
72
72
|
# in one of Rails' standard load paths:
|
73
73
|
# helper :foo # => requires 'foo_helper' and includes FooHelper
|
@@ -66,27 +66,40 @@ module AbstractController
|
|
66
66
|
# == Inheritance Examples
|
67
67
|
#
|
68
68
|
# class BankController < ActionController::Base
|
69
|
-
#
|
69
|
+
# # bank.html.erb exists
|
70
|
+
#
|
71
|
+
# class ExchangeController < BankController
|
72
|
+
# # exchange.html.erb exists
|
73
|
+
#
|
74
|
+
# class CurrencyController < BankController
|
70
75
|
#
|
71
76
|
# class InformationController < BankController
|
77
|
+
# layout "information"
|
72
78
|
#
|
73
|
-
# class TellerController <
|
79
|
+
# class TellerController < InformationController
|
74
80
|
# # teller.html.erb exists
|
75
81
|
#
|
76
|
-
# class
|
82
|
+
# class EmployeeController < InformationController
|
83
|
+
# # employee.html.erb exists
|
84
|
+
# layout nil
|
77
85
|
#
|
78
86
|
# class VaultController < BankController
|
79
87
|
# layout :access_level_layout
|
80
88
|
#
|
81
|
-
# class
|
82
|
-
# layout
|
89
|
+
# class TillController < BankController
|
90
|
+
# layout false
|
91
|
+
#
|
92
|
+
# In these examples, we have three implicit lookup scenrios:
|
93
|
+
# * The BankController uses the "bank" layout.
|
94
|
+
# * The ExchangeController uses the "exchange" layout.
|
95
|
+
# * The CurrencyController inherits the layout from BankController.
|
83
96
|
#
|
84
|
-
#
|
85
|
-
# * The InformationController uses the "
|
86
|
-
# * The TellerController
|
87
|
-
# * The
|
97
|
+
# However, when a layout is explicitly set, the explicitly set layout wins:
|
98
|
+
# * The InformationController uses the "information" layout, explicitly set.
|
99
|
+
# * The TellerController also uses the "information" layout, because the parent explicitly set it.
|
100
|
+
# * The EmployeeController uses the "employee" layout, because it set the layout to nil, resetting the parent configuration.
|
88
101
|
# * The VaultController chooses a layout dynamically by calling the <tt>access_level_layout</tt> method.
|
89
|
-
# * The
|
102
|
+
# * The TillController does not use a layout at all.
|
90
103
|
#
|
91
104
|
# == Types of layouts
|
92
105
|
#
|
@@ -126,6 +139,22 @@ module AbstractController
|
|
126
139
|
# If no directory is specified for the template name, the template will by default be looked for in <tt>app/views/layouts/</tt>.
|
127
140
|
# Otherwise, it will be looked up relative to the template root.
|
128
141
|
#
|
142
|
+
# Setting the layout to nil forces it to be looked up in the filesystem and fallbacks to the parent behavior if none exists.
|
143
|
+
# Setting it to nil is useful to re-enable template lookup overriding a previous configuration set in the parent:
|
144
|
+
#
|
145
|
+
# class ApplicationController < ActionController::Base
|
146
|
+
# layout "application"
|
147
|
+
# end
|
148
|
+
#
|
149
|
+
# class PostsController < ApplicationController
|
150
|
+
# # Will use "application" layout
|
151
|
+
# end
|
152
|
+
#
|
153
|
+
# class CommentsController < ApplicationController
|
154
|
+
# # Will search for "comments" layout and fallback "application" layout
|
155
|
+
# layout nil
|
156
|
+
# end
|
157
|
+
#
|
129
158
|
# == Conditional layouts
|
130
159
|
#
|
131
160
|
# If you have a layout that by default is applied to all the actions of a controller, you still have the option of rendering
|
@@ -168,11 +197,12 @@ module AbstractController
|
|
168
197
|
included do
|
169
198
|
class_attribute :_layout_conditions
|
170
199
|
remove_possible_method :_layout_conditions
|
171
|
-
delegate :_layout_conditions, :to => :'self.class'
|
172
200
|
self._layout_conditions = {}
|
173
201
|
_write_layout_method
|
174
202
|
end
|
175
203
|
|
204
|
+
delegate :_layout_conditions, :to => "self.class"
|
205
|
+
|
176
206
|
module ClassMethods
|
177
207
|
def inherited(klass)
|
178
208
|
super
|
@@ -188,7 +218,7 @@ module AbstractController
|
|
188
218
|
#
|
189
219
|
# ==== Returns
|
190
220
|
# * <tt> Boolean</tt> - True if the action has a layout, false otherwise.
|
191
|
-
def
|
221
|
+
def conditional_layout?
|
192
222
|
return unless super
|
193
223
|
|
194
224
|
conditions = _layout_conditions
|
@@ -244,43 +274,71 @@ module AbstractController
|
|
244
274
|
def _write_layout_method
|
245
275
|
remove_possible_method(:_layout)
|
246
276
|
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
277
|
+
prefixes = _implied_layout_name =~ /\blayouts/ ? [] : ["layouts"]
|
278
|
+
name_clause = if name
|
279
|
+
<<-RUBY
|
280
|
+
lookup_context.find_all("#{_implied_layout_name}", #{prefixes.inspect}).first || super
|
281
|
+
RUBY
|
282
|
+
end
|
283
|
+
|
284
|
+
if defined?(@_layout)
|
285
|
+
layout_definition = case @_layout
|
286
|
+
when String
|
287
|
+
@_layout.inspect
|
288
|
+
when Symbol
|
289
|
+
<<-RUBY
|
290
|
+
#{@_layout}.tap do |layout|
|
291
|
+
unless layout.is_a?(String) || !layout
|
292
|
+
raise ArgumentError, "Your layout method :#{@_layout} returned \#{layout}. It " \
|
293
|
+
"should have returned a String, false, or nil"
|
294
|
+
end
|
257
295
|
end
|
258
|
-
|
296
|
+
RUBY
|
297
|
+
when Proc
|
298
|
+
define_method :_layout_from_proc, &@_layout
|
299
|
+
"_layout_from_proc(self)"
|
300
|
+
when false
|
301
|
+
nil
|
302
|
+
when true
|
303
|
+
raise ArgumentError, "Layouts must be specified as a String, Symbol, false, or nil"
|
304
|
+
when nil
|
305
|
+
name_clause
|
259
306
|
end
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
self.
|
266
|
-
|
267
|
-
|
268
|
-
when nil
|
269
|
-
if name
|
270
|
-
_prefixes = _implied_layout_name =~ /\blayouts/ ? [] : ["layouts"]
|
307
|
+
else
|
308
|
+
# Add a deprecation if the parent layout was explicitly set and the child
|
309
|
+
# still does a dynamic lookup. In next Rails release, we should @_layout
|
310
|
+
# to be inheritable so we can skip the child lookup if the parent explicitly
|
311
|
+
# set the layout.
|
312
|
+
parent = self.superclass.instance_variable_get(:@_layout)
|
313
|
+
@_layout = nil
|
314
|
+
inspect = parent.is_a?(Proc) ? parent.inspect : parent
|
271
315
|
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
316
|
+
layout_definition = if parent.nil?
|
317
|
+
name_clause
|
318
|
+
elsif name
|
319
|
+
<<-RUBY
|
320
|
+
if template = lookup_context.find_all("#{_implied_layout_name}", #{prefixes.inspect}).first
|
321
|
+
ActiveSupport::Deprecation.warn 'Layout found at "#{_implied_layout_name}" for #{name} but parent controller ' \
|
322
|
+
'set layout to #{inspect.inspect}. Please explicitly set your layout to "#{_implied_layout_name}" ' \
|
323
|
+
'or set it to nil to force a dynamic lookup.'
|
324
|
+
template
|
276
325
|
else
|
277
326
|
super
|
278
327
|
end
|
279
|
-
|
280
|
-
|
281
|
-
end
|
328
|
+
RUBY
|
329
|
+
end
|
282
330
|
end
|
283
|
-
|
331
|
+
|
332
|
+
self.class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
333
|
+
def _layout
|
334
|
+
if conditional_layout?
|
335
|
+
#{layout_definition}
|
336
|
+
else
|
337
|
+
#{name_clause}
|
338
|
+
end
|
339
|
+
end
|
340
|
+
private :_layout
|
341
|
+
RUBY
|
284
342
|
end
|
285
343
|
end
|
286
344
|
|
@@ -289,8 +347,7 @@ module AbstractController
|
|
289
347
|
|
290
348
|
if _include_layout?(options)
|
291
349
|
layout = options.key?(:layout) ? options.delete(:layout) : :default
|
292
|
-
|
293
|
-
options[:layout] = (value =~ /\blayouts/ ? value : "layouts/#{value}") if value
|
350
|
+
options[:layout] = _layout_for_option(layout)
|
294
351
|
end
|
295
352
|
end
|
296
353
|
|
@@ -305,6 +362,10 @@ module AbstractController
|
|
305
362
|
@_action_has_layout
|
306
363
|
end
|
307
364
|
|
365
|
+
def conditional_layout?
|
366
|
+
true
|
367
|
+
end
|
368
|
+
|
308
369
|
private
|
309
370
|
|
310
371
|
# This will be overwritten by _write_layout_method
|
@@ -316,9 +377,10 @@ module AbstractController
|
|
316
377
|
# * <tt>name</tt> - The name of the template
|
317
378
|
def _layout_for_option(name)
|
318
379
|
case name
|
319
|
-
when String then name
|
320
|
-
when
|
321
|
-
when
|
380
|
+
when String then _normalize_layout(name)
|
381
|
+
when Proc then name
|
382
|
+
when true then Proc.new { _default_layout(true) }
|
383
|
+
when :default then Proc.new { _default_layout(false) }
|
322
384
|
when false, nil then nil
|
323
385
|
else
|
324
386
|
raise ArgumentError,
|
@@ -326,6 +388,10 @@ module AbstractController
|
|
326
388
|
end
|
327
389
|
end
|
328
390
|
|
391
|
+
def _normalize_layout(value)
|
392
|
+
value.is_a?(String) && value !~ /\blayouts/ ? "layouts/#{value}" : value
|
393
|
+
end
|
394
|
+
|
329
395
|
# Returns the default layout for this controller.
|
330
396
|
# Optionally raises an exception if the layout could not be found.
|
331
397
|
#
|
@@ -337,17 +403,17 @@ module AbstractController
|
|
337
403
|
# * <tt>template</tt> - The template object for the default layout (or nil)
|
338
404
|
def _default_layout(require_layout = false)
|
339
405
|
begin
|
340
|
-
|
406
|
+
value = _layout if action_has_layout?
|
341
407
|
rescue NameError => e
|
342
408
|
raise e, "Could not render layout: #{e.message}"
|
343
409
|
end
|
344
410
|
|
345
|
-
if require_layout && action_has_layout? && !
|
411
|
+
if require_layout && action_has_layout? && !value
|
346
412
|
raise ArgumentError,
|
347
413
|
"There was no default layout for #{self.class} in #{view_paths.inspect}"
|
348
414
|
end
|
349
415
|
|
350
|
-
|
416
|
+
_normalize_layout(value)
|
351
417
|
end
|
352
418
|
|
353
419
|
def _include_layout?(options)
|