actionpack 1.12.5 → 1.13.0
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 +517 -15
- data/MIT-LICENSE +1 -1
- data/README +18 -20
- data/Rakefile +7 -4
- data/examples/address_book_controller.rb +3 -3
- data/examples/blog_controller.cgi +3 -3
- data/examples/debate_controller.cgi +5 -5
- data/lib/action_controller.rb +2 -2
- data/lib/action_controller/assertions.rb +73 -311
- data/lib/action_controller/{deprecated_assertions.rb → assertions/deprecated_assertions.rb} +32 -8
- data/lib/action_controller/assertions/dom_assertions.rb +25 -0
- data/lib/action_controller/assertions/model_assertions.rb +12 -0
- data/lib/action_controller/assertions/response_assertions.rb +140 -0
- data/lib/action_controller/assertions/routing_assertions.rb +82 -0
- data/lib/action_controller/assertions/selector_assertions.rb +571 -0
- data/lib/action_controller/assertions/tag_assertions.rb +117 -0
- data/lib/action_controller/base.rb +334 -163
- data/lib/action_controller/benchmarking.rb +3 -6
- data/lib/action_controller/caching.rb +83 -22
- data/lib/action_controller/cgi_ext/cgi_ext.rb +0 -7
- data/lib/action_controller/cgi_ext/cgi_methods.rb +167 -173
- data/lib/action_controller/cgi_ext/raw_post_data_fix.rb +43 -22
- data/lib/action_controller/cgi_process.rb +50 -27
- data/lib/action_controller/components.rb +21 -25
- data/lib/action_controller/cookies.rb +10 -9
- data/lib/action_controller/{dependencies.rb → deprecated_dependencies.rb} +9 -27
- data/lib/action_controller/filters.rb +448 -225
- data/lib/action_controller/flash.rb +24 -20
- data/lib/action_controller/helpers.rb +2 -5
- data/lib/action_controller/integration.rb +40 -16
- data/lib/action_controller/layout.rb +11 -8
- data/lib/action_controller/macros/auto_complete.rb +3 -2
- data/lib/action_controller/macros/in_place_editing.rb +3 -2
- data/lib/action_controller/mime_responds.rb +41 -29
- data/lib/action_controller/mime_type.rb +68 -10
- data/lib/action_controller/pagination.rb +4 -3
- data/lib/action_controller/request.rb +22 -14
- data/lib/action_controller/rescue.rb +25 -22
- data/lib/action_controller/resources.rb +302 -0
- data/lib/action_controller/response.rb +20 -2
- data/lib/action_controller/response.rb.rej +17 -0
- data/lib/action_controller/routing.rb +1165 -567
- data/lib/action_controller/scaffolding.rb +30 -31
- data/lib/action_controller/session/active_record_store.rb +2 -0
- data/lib/action_controller/session/drb_store.rb +4 -0
- data/lib/action_controller/session/mem_cache_store.rb +4 -0
- data/lib/action_controller/session_management.rb +6 -9
- data/lib/action_controller/status_codes.rb +89 -0
- data/lib/action_controller/streaming.rb +6 -15
- data/lib/action_controller/templates/rescues/_request_and_response.rhtml +5 -5
- data/lib/action_controller/templates/rescues/diagnostics.rhtml +2 -2
- data/lib/action_controller/templates/rescues/routing_error.rhtml +4 -4
- data/lib/action_controller/templates/rescues/template_error.rhtml +1 -1
- data/lib/action_controller/templates/scaffolds/list.rhtml +1 -1
- data/lib/action_controller/test_process.rb +52 -30
- data/lib/action_controller/url_rewriter.rb +63 -29
- data/lib/action_controller/vendor/html-scanner/html/document.rb +1 -0
- data/lib/action_controller/vendor/html-scanner/html/node.rb +3 -4
- data/lib/action_controller/vendor/html-scanner/html/selector.rb +822 -0
- data/lib/action_controller/verification.rb +22 -11
- data/lib/action_pack.rb +1 -1
- data/lib/action_pack/version.rb +2 -2
- data/lib/action_view.rb +1 -1
- data/lib/action_view/base.rb +46 -43
- data/lib/action_view/compiled_templates.rb +1 -1
- data/lib/action_view/helpers/active_record_helper.rb +54 -17
- data/lib/action_view/helpers/asset_tag_helper.rb +97 -46
- data/lib/action_view/helpers/capture_helper.rb +1 -1
- data/lib/action_view/helpers/date_helper.rb +258 -136
- data/lib/action_view/helpers/debug_helper.rb +1 -1
- data/lib/action_view/helpers/deprecated_helper.rb +34 -0
- data/lib/action_view/helpers/form_helper.rb +75 -35
- data/lib/action_view/helpers/form_options_helper.rb +7 -5
- data/lib/action_view/helpers/form_tag_helper.rb +44 -6
- data/lib/action_view/helpers/java_script_macros_helper.rb +59 -46
- data/lib/action_view/helpers/javascript_helper.rb +71 -10
- data/lib/action_view/helpers/javascripts/controls.js +41 -23
- data/lib/action_view/helpers/javascripts/dragdrop.js +105 -76
- data/lib/action_view/helpers/javascripts/effects.js +293 -163
- data/lib/action_view/helpers/javascripts/prototype.js +897 -389
- data/lib/action_view/helpers/javascripts/prototype.js.rej +561 -0
- data/lib/action_view/helpers/number_helper.rb +111 -65
- data/lib/action_view/helpers/prototype_helper.rb +84 -109
- data/lib/action_view/helpers/scriptaculous_helper.rb +5 -0
- data/lib/action_view/helpers/tag_helper.rb +69 -16
- data/lib/action_view/helpers/text_helper.rb +149 -112
- data/lib/action_view/helpers/url_helper.rb +200 -107
- data/lib/action_view/template_error.rb +66 -42
- data/test/abstract_unit.rb +4 -2
- data/test/active_record_unit.rb +84 -56
- data/test/activerecord/active_record_assertions_test.rb +26 -18
- data/test/activerecord/active_record_store_test.rb +4 -36
- data/test/activerecord/pagination_test.rb +1 -6
- data/test/controller/action_pack_assertions_test.rb +230 -113
- data/test/controller/addresses_render_test.rb +2 -6
- data/test/controller/assert_select_test.rb +576 -0
- data/test/controller/base_test.rb +73 -3
- data/test/controller/caching_test.rb +228 -0
- data/test/controller/capture_test.rb +12 -10
- data/test/controller/cgi_test.rb +89 -12
- data/test/controller/components_test.rb +24 -2
- data/test/controller/content_type_test.rb +139 -0
- data/test/controller/controller_fixtures/app/controllers/admin/user_controller.rb +0 -0
- data/test/controller/controller_fixtures/app/controllers/user_controller.rb +0 -0
- data/test/controller/controller_fixtures/vendor/plugins/bad_plugin/lib/plugin_controller.rb +0 -0
- data/test/controller/cookie_test.rb +33 -25
- data/test/controller/deprecated_instance_variables_test.rb +48 -0
- data/test/controller/deprecation/deprecated_base_methods_test.rb +60 -0
- data/test/controller/fake_controllers.rb +0 -1
- data/test/controller/filters_test.rb +301 -16
- data/test/controller/flash_test.rb +19 -2
- data/test/controller/helper_test.rb +2 -2
- data/test/controller/integration_test.rb +154 -0
- data/test/controller/layout_test.rb +115 -1
- data/test/controller/mime_responds_test.rb +94 -0
- data/test/controller/mime_type_test.rb +9 -0
- data/test/controller/new_render_test.rb +161 -11
- data/test/controller/raw_post_test.rb +52 -15
- data/test/controller/redirect_test.rb +27 -14
- data/test/controller/render_test.rb +76 -29
- data/test/controller/request_test.rb +55 -4
- data/test/controller/resources_test.rb +274 -0
- data/test/controller/routing_test.rb +1533 -824
- data/test/controller/selector_test.rb +628 -0
- data/test/controller/send_file_test.rb +9 -1
- data/test/controller/session_management_test.rb +51 -0
- data/test/controller/test_test.rb +113 -29
- data/test/controller/url_rewriter_test.rb +86 -17
- data/test/controller/verification_test.rb +19 -17
- data/test/controller/webservice_test.rb +0 -7
- data/test/fixtures/content_type/render_default_content_types_for_respond_to.rhtml +1 -0
- data/test/fixtures/content_type/render_default_for_rhtml.rhtml +1 -0
- data/test/fixtures/content_type/render_default_for_rjs.rjs +1 -0
- data/test/fixtures/content_type/render_default_for_rxml.rxml +1 -0
- data/test/fixtures/deprecated_instance_variables/_cookies_ivar.rhtml +1 -0
- data/test/fixtures/deprecated_instance_variables/_cookies_method.rhtml +1 -0
- data/test/fixtures/deprecated_instance_variables/_flash_ivar.rhtml +1 -0
- data/test/fixtures/deprecated_instance_variables/_flash_method.rhtml +1 -0
- data/test/fixtures/deprecated_instance_variables/_headers_ivar.rhtml +1 -0
- data/test/fixtures/deprecated_instance_variables/_headers_method.rhtml +1 -0
- data/test/fixtures/deprecated_instance_variables/_params_ivar.rhtml +1 -0
- data/test/fixtures/deprecated_instance_variables/_params_method.rhtml +1 -0
- data/test/fixtures/deprecated_instance_variables/_request_ivar.rhtml +1 -0
- data/test/fixtures/deprecated_instance_variables/_request_method.rhtml +1 -0
- data/test/fixtures/deprecated_instance_variables/_response_ivar.rhtml +1 -0
- data/test/fixtures/deprecated_instance_variables/_response_method.rhtml +1 -0
- data/test/fixtures/deprecated_instance_variables/_session_ivar.rhtml +1 -0
- data/test/fixtures/deprecated_instance_variables/_session_method.rhtml +1 -0
- data/test/fixtures/multipart/binary_file +0 -0
- data/test/fixtures/public/javascripts/application.js +1 -0
- data/test/fixtures/test/_hello.rxml +1 -0
- data/test/fixtures/test/hello_world_container.rxml +3 -0
- data/test/fixtures/topic.rb +2 -2
- data/test/template/active_record_helper_test.rb +83 -12
- data/test/template/asset_tag_helper_test.rb +75 -95
- data/test/template/compiled_templates_test.rb +1 -0
- data/test/template/date_helper_test.rb +873 -181
- data/test/template/deprecated_helper_test.rb +36 -0
- data/test/template/deprecated_instance_variables_test.rb +43 -0
- data/test/template/form_helper_test.rb +77 -1
- data/test/template/form_options_helper_test.rb +4 -0
- data/test/template/form_tag_helper_test.rb +66 -2
- data/test/template/java_script_macros_helper_test.rb +4 -1
- data/test/template/javascript_helper_test.rb +29 -0
- data/test/template/number_helper_test.rb +63 -27
- data/test/template/prototype_helper_test.rb +77 -34
- data/test/template/tag_helper_test.rb +34 -6
- data/test/template/text_helper_test.rb +69 -34
- data/test/template/url_helper_test.rb +168 -16
- data/test/testing_sandbox.rb +7 -22
- metadata +66 -20
- data/filler.txt +0 -50
- data/lib/action_controller/code_generation.rb +0 -235
- data/lib/action_controller/vendor/xml_simple.rb +0 -1019
- data/test/controller/caching_filestore.rb +0 -74
- data/test/fixtures/application_root/app/controllers/a_class_that_contains_a_controller/poorly_placed_controller.rb +0 -7
- data/test/fixtures/application_root/app/controllers/module_that_holds_controllers/nested_controller.rb +0 -3
- data/test/fixtures/application_root/app/models/a_class_that_contains_a_controller.rb +0 -7
- data/test/fixtures/dont_load.rb +0 -3
@@ -17,7 +17,7 @@ module ActionController #:nodoc:
|
|
17
17
|
# end
|
18
18
|
#
|
19
19
|
# display.rhtml
|
20
|
-
# <% if
|
20
|
+
# <% if flash[:notice] %><div class="notice"><%= flash[:notice] %></div><% end %>
|
21
21
|
#
|
22
22
|
# This example just places a string in the flash, but you can put any object in there. And of course, you can put as many
|
23
23
|
# as you like at a time too. Just remember: They'll be gone by the time the next action has been performed.
|
@@ -28,11 +28,9 @@ module ActionController #:nodoc:
|
|
28
28
|
base.send :include, InstanceMethods
|
29
29
|
|
30
30
|
base.class_eval do
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
alias_method :process_cleanup_without_flash, :process_cleanup
|
35
|
-
alias_method :process_cleanup, :process_cleanup_with_flash
|
31
|
+
alias_method_chain :assign_shortcuts, :flash
|
32
|
+
alias_method_chain :process_cleanup, :flash
|
33
|
+
alias_method_chain :reset_session, :flash
|
36
34
|
end
|
37
35
|
end
|
38
36
|
|
@@ -94,7 +92,7 @@ module ActionController #:nodoc:
|
|
94
92
|
#
|
95
93
|
# flash.keep # keeps the entire flash
|
96
94
|
# flash.keep(:notice) # keeps only the "notice" entry, the rest of the flash is discarded
|
97
|
-
def keep(k=nil)
|
95
|
+
def keep(k = nil)
|
98
96
|
use(k, false)
|
99
97
|
end
|
100
98
|
|
@@ -102,7 +100,7 @@ module ActionController #:nodoc:
|
|
102
100
|
#
|
103
101
|
# flash.keep # keep entire flash available for the next action
|
104
102
|
# flash.discard(:warning) # discard the "warning" entry (it'll still be available for the current action)
|
105
|
-
def discard(k=nil)
|
103
|
+
def discard(k = nil)
|
106
104
|
use(k)
|
107
105
|
end
|
108
106
|
|
@@ -118,6 +116,7 @@ module ActionController #:nodoc:
|
|
118
116
|
@used.delete(k)
|
119
117
|
end
|
120
118
|
end
|
119
|
+
|
121
120
|
(@used.keys - keys).each{|k| @used.delete k } # clean up after keys that could have been left over by calling reject! or shift on the flash
|
122
121
|
end
|
123
122
|
|
@@ -143,36 +142,41 @@ module ActionController #:nodoc:
|
|
143
142
|
end
|
144
143
|
|
145
144
|
def process_cleanup_with_flash
|
146
|
-
flash.sweep if @
|
145
|
+
flash.sweep if @_session
|
147
146
|
process_cleanup_without_flash
|
148
147
|
end
|
148
|
+
|
149
|
+
def reset_session_with_flash
|
150
|
+
reset_session_without_flash
|
151
|
+
remove_instance_variable(:@_flash)
|
152
|
+
flash(:refresh)
|
153
|
+
end
|
149
154
|
|
150
155
|
protected
|
151
156
|
# Access the contents of the flash. Use <tt>flash["notice"]</tt> to read a notice you put there or
|
152
157
|
# <tt>flash["notice"] = "hello"</tt> to put a new one.
|
153
158
|
# Note that if sessions are disabled only flash.now will work.
|
154
159
|
def flash(refresh = false) #:doc:
|
155
|
-
if @
|
156
|
-
@
|
157
|
-
if
|
158
|
-
#
|
159
|
-
# we don't put the flash in the session in this case
|
160
|
+
if !defined?(@_flash) || refresh
|
161
|
+
@_flash =
|
162
|
+
if session.is_a?(Hash)
|
163
|
+
# don't put flash in session if disabled
|
160
164
|
FlashHash.new
|
161
165
|
else
|
162
|
-
# otherwise,
|
166
|
+
# otherwise, session is a CGI::Session or a TestSession
|
163
167
|
# so make sure it gets retrieved from/saved to session storage after request processing
|
164
|
-
|
168
|
+
session["flash"] ||= FlashHash.new
|
165
169
|
end
|
166
170
|
end
|
167
|
-
|
168
|
-
@
|
171
|
+
|
172
|
+
@_flash
|
169
173
|
end
|
170
174
|
|
171
175
|
# deprecated. use <tt>flash.keep</tt> instead
|
172
176
|
def keep_flash #:doc:
|
173
|
-
warn 'keep_flash is deprecated; use flash.keep instead.'
|
177
|
+
ActiveSupport::Deprecation.warn 'keep_flash is deprecated; use flash.keep instead.', caller
|
174
178
|
flash.keep
|
175
179
|
end
|
176
180
|
end
|
177
181
|
end
|
178
|
-
end
|
182
|
+
end
|
@@ -1,8 +1,6 @@
|
|
1
1
|
module ActionController #:nodoc:
|
2
2
|
module Helpers #:nodoc:
|
3
|
-
def self.
|
4
|
-
super
|
5
|
-
|
3
|
+
def self.included(base)
|
6
4
|
# Initialize the base module to aggregate its helpers.
|
7
5
|
base.class_inheritable_accessor :master_helper_module
|
8
6
|
base.master_helper_module = Module.new
|
@@ -13,8 +11,7 @@ module ActionController #:nodoc:
|
|
13
11
|
base.class_eval do
|
14
12
|
# Wrap inherited to create a new master helper module for subclasses.
|
15
13
|
class << self
|
16
|
-
|
17
|
-
alias_method :inherited, :inherited_with_helper
|
14
|
+
alias_method_chain :inherited, :helper
|
18
15
|
end
|
19
16
|
end
|
20
17
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'dispatcher'
|
2
2
|
require 'stringio'
|
3
3
|
require 'uri'
|
4
|
+
require 'action_controller/test_process'
|
4
5
|
|
5
6
|
module ActionController
|
6
7
|
module Integration #:nodoc:
|
@@ -13,6 +14,7 @@ module ActionController
|
|
13
14
|
# rather than instantiating Integration::Session directly.
|
14
15
|
class Session
|
15
16
|
include Test::Unit::Assertions
|
17
|
+
include ActionController::Assertions
|
16
18
|
include ActionController::TestProcess
|
17
19
|
|
18
20
|
# The integer HTTP status code of the last request.
|
@@ -73,11 +75,11 @@ module ActionController
|
|
73
75
|
unless @named_routes_configured
|
74
76
|
# install the named routes in this session instance.
|
75
77
|
klass = class<<self; self; end
|
76
|
-
Routing::
|
78
|
+
Routing::Routes.named_routes.install(klass)
|
77
79
|
|
78
80
|
# the helpers are made protected by default--we make them public for
|
79
81
|
# easier access during testing and troubleshooting.
|
80
|
-
klass.send(:public, *Routing::
|
82
|
+
klass.send(:public, *Routing::Routes.named_routes.helpers)
|
81
83
|
@named_routes_configured = true
|
82
84
|
end
|
83
85
|
end
|
@@ -111,7 +113,7 @@ module ActionController
|
|
111
113
|
# performed on the location header.
|
112
114
|
def follow_redirect!
|
113
115
|
raise "not a redirect! #{@status} #{@status_message}" unless redirect?
|
114
|
-
get(interpret_uri(headers[
|
116
|
+
get(interpret_uri(headers['location'].first))
|
115
117
|
status
|
116
118
|
end
|
117
119
|
|
@@ -143,19 +145,33 @@ module ActionController
|
|
143
145
|
# (application/x-www-form-urlencoded or multipart/form-data). The headers
|
144
146
|
# should be a hash. The keys will automatically be upcased, with the
|
145
147
|
# prefix 'HTTP_' added if needed.
|
148
|
+
#
|
149
|
+
# You can also perform POST, PUT, DELETE, and HEAD requests with #post,
|
150
|
+
# #put, #delete, and #head.
|
146
151
|
def get(path, parameters=nil, headers=nil)
|
147
152
|
process :get, path, parameters, headers
|
148
153
|
end
|
149
154
|
|
150
|
-
# Performs a POST request with the given parameters.
|
151
|
-
# be +nil+, a Hash, or a string that is appropriately encoded
|
152
|
-
# (application/x-www-form-urlencoded or multipart/form-data). The headers
|
153
|
-
# should be a hash. The keys will automatically be upcased, with the
|
154
|
-
# prefix 'HTTP_' added if needed.
|
155
|
+
# Performs a POST request with the given parameters. See get() for more details.
|
155
156
|
def post(path, parameters=nil, headers=nil)
|
156
157
|
process :post, path, parameters, headers
|
157
158
|
end
|
158
159
|
|
160
|
+
# Performs a PUT request with the given parameters. See get() for more details.
|
161
|
+
def put(path, parameters=nil, headers=nil)
|
162
|
+
process :put, path, parameters, headers
|
163
|
+
end
|
164
|
+
|
165
|
+
# Performs a DELETE request with the given parameters. See get() for more details.
|
166
|
+
def delete(path, parameters=nil, headers=nil)
|
167
|
+
process :delete, path, parameters, headers
|
168
|
+
end
|
169
|
+
|
170
|
+
# Performs a HEAD request with the given parameters. See get() for more details.
|
171
|
+
def head(path, parameters=nil, headers=nil)
|
172
|
+
process :head, path, parameters, headers
|
173
|
+
end
|
174
|
+
|
159
175
|
# Performs an XMLHttpRequest request with the given parameters, mimicing
|
160
176
|
# the request environment created by the Prototype library. The parameters
|
161
177
|
# may be +nil+, a Hash, or a string that is appropriately encoded
|
@@ -163,7 +179,11 @@ module ActionController
|
|
163
179
|
# should be a hash. The keys will automatically be upcased, with the
|
164
180
|
# prefix 'HTTP_' added if needed.
|
165
181
|
def xml_http_request(path, parameters=nil, headers=nil)
|
166
|
-
headers = (headers || {}).merge(
|
182
|
+
headers = (headers || {}).merge(
|
183
|
+
"X-Requested-With" => "XMLHttpRequest",
|
184
|
+
"Accept" => "text/javascript, text/html, application/xml, text/xml, */*"
|
185
|
+
)
|
186
|
+
|
167
187
|
post(path, parameters, headers)
|
168
188
|
end
|
169
189
|
|
@@ -174,7 +194,6 @@ module ActionController
|
|
174
194
|
end
|
175
195
|
|
176
196
|
private
|
177
|
-
|
178
197
|
class MockCGI < CGI #:nodoc:
|
179
198
|
attr_accessor :stdinput, :stdoutput, :env_table
|
180
199
|
|
@@ -224,7 +243,7 @@ module ActionController
|
|
224
243
|
|
225
244
|
(headers || {}).each do |key, value|
|
226
245
|
key = key.to_s.upcase.gsub(/-/, "_")
|
227
|
-
key = "HTTP_#{key}" unless env.has_key?(key) ||
|
246
|
+
key = "HTTP_#{key}" unless env.has_key?(key) || key =~ /^HTTP_/
|
228
247
|
env[key] = value
|
229
248
|
end
|
230
249
|
|
@@ -247,6 +266,8 @@ module ActionController
|
|
247
266
|
# tests.
|
248
267
|
@response.extend(TestResponseBehavior)
|
249
268
|
|
269
|
+
@html_document = nil
|
270
|
+
|
250
271
|
parse_result
|
251
272
|
return status
|
252
273
|
end
|
@@ -317,9 +338,8 @@ module ActionController
|
|
317
338
|
def self.included(base)
|
318
339
|
base.extend(ClassMethods)
|
319
340
|
base.class_eval do
|
320
|
-
class <<self
|
321
|
-
|
322
|
-
alias_method :new, :new_with_capture
|
341
|
+
class << self
|
342
|
+
alias_method_chain :new, :capture
|
323
343
|
end
|
324
344
|
end
|
325
345
|
end
|
@@ -330,9 +350,11 @@ module ActionController
|
|
330
350
|
def clear_last_instantiation!
|
331
351
|
self.last_instantiation = nil
|
332
352
|
end
|
333
|
-
|
353
|
+
|
334
354
|
def new_with_capture(*args)
|
335
|
-
|
355
|
+
controller = new_without_capture(*args)
|
356
|
+
self.last_instantiation ||= controller
|
357
|
+
controller
|
336
358
|
end
|
337
359
|
end
|
338
360
|
end
|
@@ -471,6 +493,8 @@ module ActionController
|
|
471
493
|
%w(get post cookies assigns xml_http_request).each do |method|
|
472
494
|
define_method(method) do |*args|
|
473
495
|
reset! unless @integration_session
|
496
|
+
# reset the html_document variable, but only for new get/post calls
|
497
|
+
@html_document = nil unless %w(cookies assigns).include?(method)
|
474
498
|
returning @integration_session.send(method, *args) do
|
475
499
|
copy_session_variables!
|
476
500
|
end
|
@@ -3,12 +3,13 @@ module ActionController #:nodoc:
|
|
3
3
|
def self.included(base)
|
4
4
|
base.extend(ClassMethods)
|
5
5
|
base.class_eval do
|
6
|
+
# NOTE: Can't use alias_method_chain here because +render_without_layout+ is already
|
7
|
+
# defined as a publicly exposed method
|
6
8
|
alias_method :render_with_no_layout, :render
|
7
9
|
alias_method :render, :render_with_a_layout
|
8
10
|
|
9
11
|
class << self
|
10
|
-
|
11
|
-
alias_method :inherited, :inherited_with_layout
|
12
|
+
alias_method_chain :inherited, :layout
|
12
13
|
end
|
13
14
|
end
|
14
15
|
end
|
@@ -26,9 +27,9 @@ module ActionController #:nodoc:
|
|
26
27
|
# With layouts, you can flip it around and have the common structure know where to insert changing content. This means
|
27
28
|
# that the header and footer are only mentioned in one place, like this:
|
28
29
|
#
|
29
|
-
#
|
30
|
+
# // The header part of this layout
|
30
31
|
# <%= yield %>
|
31
|
-
#
|
32
|
+
# // The footer part of this layout -->
|
32
33
|
#
|
33
34
|
# And then you have content pages that look like this:
|
34
35
|
#
|
@@ -37,9 +38,9 @@ module ActionController #:nodoc:
|
|
37
38
|
# Not a word about common structures. At rendering time, the content page is computed and then inserted in the layout,
|
38
39
|
# like this:
|
39
40
|
#
|
40
|
-
#
|
41
|
+
# // The header part of this layout
|
41
42
|
# hello world
|
42
|
-
#
|
43
|
+
# // The footer part of this layout -->
|
43
44
|
#
|
44
45
|
# == Accessing shared variables
|
45
46
|
#
|
@@ -182,7 +183,6 @@ module ActionController #:nodoc:
|
|
182
183
|
private
|
183
184
|
def inherited_with_layout(child)
|
184
185
|
inherited_without_layout(child)
|
185
|
-
child.send :include, Reloadable
|
186
186
|
layout_match = child.name.underscore.sub(/_controller$/, '').sub(/^controllers\//, '')
|
187
187
|
child.layout(layout_match) unless layout_list.grep(%r{layouts/#{layout_match}\.[a-z][0-9a-z]*$}).empty?
|
188
188
|
end
|
@@ -235,6 +235,8 @@ module ActionController #:nodoc:
|
|
235
235
|
template_with_options = options.is_a?(Hash)
|
236
236
|
|
237
237
|
if apply_layout?(template_with_options, options) && (layout = pick_layout(template_with_options, options, deprecated_layout))
|
238
|
+
assert_existence_of_template_file(layout)
|
239
|
+
|
238
240
|
options = options.merge :layout => false if template_with_options
|
239
241
|
logger.info("Rendering #{options} within #{layout}") if logger
|
240
242
|
|
@@ -248,6 +250,7 @@ module ActionController #:nodoc:
|
|
248
250
|
erase_render_results
|
249
251
|
add_variables_to_assigns
|
250
252
|
@template.instance_variable_set("@content_for_layout", content_for_layout)
|
253
|
+
response.layout = layout
|
251
254
|
render_text(@template.render_file(layout, true), deprecated_status)
|
252
255
|
else
|
253
256
|
render_with_no_layout(options, deprecated_status, &block)
|
@@ -263,7 +266,7 @@ module ActionController #:nodoc:
|
|
263
266
|
|
264
267
|
def candidate_for_layout?(options)
|
265
268
|
(options.has_key?(:layout) && options[:layout] != false) ||
|
266
|
-
options.values_at(:text, :xml, :file, :inline, :partial, :nothing).compact.empty? &&
|
269
|
+
options.values_at(:text, :xml, :json, :file, :inline, :partial, :nothing).compact.empty? &&
|
267
270
|
!template_exempt_from_layout?(default_template_name(options[:action] || options[:template]))
|
268
271
|
end
|
269
272
|
|
@@ -4,11 +4,12 @@ module ActionController
|
|
4
4
|
# backing.
|
5
5
|
module Macros
|
6
6
|
module AutoComplete #:nodoc:
|
7
|
-
def self.
|
8
|
-
super
|
7
|
+
def self.included(base) #:nodoc:
|
9
8
|
base.extend(ClassMethods)
|
10
9
|
end
|
11
10
|
|
11
|
+
# DEPRECATION WARNING: This method will become a separate plugin when Rails 2.0 ships.
|
12
|
+
#
|
12
13
|
# Example:
|
13
14
|
#
|
14
15
|
# # Controller
|
@@ -1,11 +1,12 @@
|
|
1
1
|
module ActionController
|
2
2
|
module Macros
|
3
3
|
module InPlaceEditing #:nodoc:
|
4
|
-
def self.
|
5
|
-
super
|
4
|
+
def self.included(base) #:nodoc:
|
6
5
|
base.extend(ClassMethods)
|
7
6
|
end
|
8
7
|
|
8
|
+
# DEPRECATION WARNING: This method will become a separate plugin when Rails 2.0 ships.
|
9
|
+
#
|
9
10
|
# Example:
|
10
11
|
#
|
11
12
|
# # Controller
|
@@ -8,18 +8,18 @@ module ActionController #:nodoc:
|
|
8
8
|
# Without web-service support, an action which collects the data for displaying a list of people
|
9
9
|
# might look something like this:
|
10
10
|
#
|
11
|
-
# def
|
11
|
+
# def index
|
12
12
|
# @people = Person.find(:all)
|
13
13
|
# end
|
14
14
|
#
|
15
15
|
# Here's the same action, with web-service support baked in:
|
16
16
|
#
|
17
|
-
# def
|
17
|
+
# def index
|
18
18
|
# @people = Person.find(:all)
|
19
19
|
#
|
20
|
-
# respond_to do |
|
21
|
-
#
|
22
|
-
#
|
20
|
+
# respond_to do |format|
|
21
|
+
# format.html
|
22
|
+
# format.xml { render :xml => @people.to_xml }
|
23
23
|
# end
|
24
24
|
# end
|
25
25
|
#
|
@@ -30,7 +30,7 @@ module ActionController #:nodoc:
|
|
30
30
|
# Supposing you have an action that adds a new person, optionally creating their company
|
31
31
|
# (by name) if it does not already exist, without web-services, it might look like this:
|
32
32
|
#
|
33
|
-
# def
|
33
|
+
# def create
|
34
34
|
# @company = Company.find_or_create_by_name(params[:company][:name])
|
35
35
|
# @person = @company.people.create(params[:person])
|
36
36
|
#
|
@@ -39,15 +39,15 @@ module ActionController #:nodoc:
|
|
39
39
|
#
|
40
40
|
# Here's the same action, with web-service support baked in:
|
41
41
|
#
|
42
|
-
# def
|
42
|
+
# def create
|
43
43
|
# company = params[:person].delete(:company)
|
44
44
|
# @company = Company.find_or_create_by_name(company[:name])
|
45
45
|
# @person = @company.people.create(params[:person])
|
46
46
|
#
|
47
|
-
# respond_to do |
|
48
|
-
#
|
49
|
-
#
|
50
|
-
#
|
47
|
+
# respond_to do |format|
|
48
|
+
# format.html { redirect_to(person_list_url) }
|
49
|
+
# format.js
|
50
|
+
# format.xml { render :xml => @person.to_xml(:include => @company) }
|
51
51
|
# end
|
52
52
|
# end
|
53
53
|
#
|
@@ -97,9 +97,8 @@ module ActionController #:nodoc:
|
|
97
97
|
# environment.rb as follows.
|
98
98
|
#
|
99
99
|
# Mime::Type.register "image/jpg", :jpg
|
100
|
-
#
|
101
100
|
def respond_to(*types, &block)
|
102
|
-
raise ArgumentError, "respond_to takes either types or a block, never
|
101
|
+
raise ArgumentError, "respond_to takes either types or a block, never both" unless types.any? ^ block
|
103
102
|
block ||= lambda { |responder| types.each { |type| responder.send(type) } }
|
104
103
|
responder = Responder.new(block.binding)
|
105
104
|
block.call(responder)
|
@@ -108,15 +107,19 @@ module ActionController #:nodoc:
|
|
108
107
|
end
|
109
108
|
|
110
109
|
class Responder #:nodoc:
|
111
|
-
DEFAULT_BLOCKS = {
|
112
|
-
:html
|
113
|
-
|
114
|
-
|
115
|
-
}
|
110
|
+
DEFAULT_BLOCKS = [:html, :js, :xml].inject({}) do |blocks, ext|
|
111
|
+
template_extension = (ext == :html ? '' : ".r#{ext}")
|
112
|
+
blocks.update ext => %(Proc.new { render :action => "\#{action_name}#{template_extension}", :content_type => Mime::#{ext.to_s.upcase} })
|
113
|
+
end
|
116
114
|
|
117
115
|
def initialize(block_binding)
|
118
116
|
@block_binding = block_binding
|
119
|
-
@mime_type_priority = eval(
|
117
|
+
@mime_type_priority = eval(
|
118
|
+
"(params[:format] && Mime::EXTENSION_LOOKUP[params[:format]]) ? " +
|
119
|
+
"[ Mime::EXTENSION_LOOKUP[params[:format]] ] : request.accepts",
|
120
|
+
block_binding
|
121
|
+
)
|
122
|
+
|
120
123
|
@order = []
|
121
124
|
@responses = {}
|
122
125
|
end
|
@@ -127,24 +130,33 @@ module ActionController #:nodoc:
|
|
127
130
|
@order << mime_type
|
128
131
|
|
129
132
|
if block_given?
|
130
|
-
@responses[mime_type] =
|
133
|
+
@responses[mime_type] = Proc.new do
|
134
|
+
eval "response.content_type = '#{mime_type.to_s}'", @block_binding
|
135
|
+
block.call
|
136
|
+
end
|
131
137
|
else
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
for mime_type in %w( all html js xml rss atom yaml )
|
137
|
-
eval <<-EOT
|
138
|
-
def #{mime_type}(&block)
|
139
|
-
custom(Mime::#{mime_type.upcase}, &block)
|
138
|
+
if source = DEFAULT_BLOCKS[mime_type.to_sym]
|
139
|
+
@responses[mime_type] = eval(source, @block_binding)
|
140
|
+
else
|
141
|
+
raise ActionController::RenderError, "Expected a block but none was given for custom mime handler #{mime_type}"
|
140
142
|
end
|
141
|
-
|
143
|
+
end
|
142
144
|
end
|
143
145
|
|
144
146
|
def any(*args, &block)
|
145
147
|
args.each { |type| send(type, &block) }
|
146
148
|
end
|
147
149
|
|
150
|
+
def method_missing(symbol, &block)
|
151
|
+
mime_constant = symbol.to_s.upcase
|
152
|
+
|
153
|
+
if Mime::SET.include?(Mime.const_get(mime_constant))
|
154
|
+
custom(Mime.const_get(mime_constant), &block)
|
155
|
+
else
|
156
|
+
super
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
148
160
|
def respond
|
149
161
|
for priority in @mime_type_priority
|
150
162
|
if priority == Mime::ALL
|