actionpack 1.11.2 → 1.12.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 +392 -5
- data/lib/action_controller.rb +8 -4
- data/lib/action_controller/assertions.rb +9 -10
- data/lib/action_controller/base.rb +177 -88
- data/lib/action_controller/benchmarking.rb +5 -5
- data/lib/action_controller/caching.rb +44 -36
- data/lib/action_controller/cgi_ext/cgi_methods.rb +71 -6
- data/lib/action_controller/cgi_ext/cookie_performance_fix.rb +1 -1
- data/lib/action_controller/cgi_process.rb +36 -24
- data/lib/action_controller/components.rb +152 -52
- data/lib/action_controller/dependencies.rb +1 -1
- data/lib/action_controller/deprecated_redirects.rb +2 -2
- data/lib/action_controller/deprecated_request_methods.rb +34 -0
- data/lib/action_controller/filters.rb +59 -19
- data/lib/action_controller/flash.rb +53 -47
- data/lib/action_controller/helpers.rb +2 -2
- data/lib/action_controller/integration.rb +524 -0
- data/lib/action_controller/layout.rb +58 -23
- data/lib/action_controller/mime_responds.rb +163 -0
- data/lib/action_controller/mime_type.rb +142 -0
- data/lib/action_controller/pagination.rb +13 -7
- data/lib/action_controller/request.rb +59 -56
- data/lib/action_controller/rescue.rb +1 -1
- data/lib/action_controller/routing.rb +29 -10
- data/lib/action_controller/scaffolding.rb +8 -0
- data/lib/action_controller/session/active_record_store.rb +21 -10
- data/lib/action_controller/session/mem_cache_store.rb +18 -12
- data/lib/action_controller/session_management.rb +30 -11
- data/lib/action_controller/templates/rescues/_trace.rhtml +1 -1
- data/lib/action_controller/templates/scaffolds/layout.rhtml +4 -4
- data/lib/action_controller/templates/scaffolds/list.rhtml +1 -1
- data/lib/action_controller/test_process.rb +189 -118
- data/lib/action_controller/vendor/html-scanner/html/node.rb +20 -1
- data/lib/action_controller/vendor/html-scanner/html/tokenizer.rb +3 -0
- data/lib/action_controller/vendor/html-scanner/html/version.rb +1 -1
- data/lib/action_controller/vendor/xml_node.rb +97 -0
- data/lib/action_controller/verification.rb +2 -0
- data/lib/action_pack/version.rb +3 -3
- data/lib/action_view.rb +0 -2
- data/lib/action_view/base.rb +109 -36
- data/lib/action_view/compiled_templates.rb +1 -1
- data/lib/action_view/helpers/active_record_helper.rb +4 -2
- data/lib/action_view/helpers/asset_tag_helper.rb +6 -7
- data/lib/action_view/helpers/capture_helper.rb +49 -12
- data/lib/action_view/helpers/date_helper.rb +14 -4
- data/lib/action_view/helpers/form_helper.rb +136 -20
- data/lib/action_view/helpers/form_options_helper.rb +29 -7
- data/lib/action_view/helpers/form_tag_helper.rb +22 -20
- data/lib/action_view/helpers/java_script_macros_helper.rb +29 -9
- data/lib/action_view/helpers/javascript_helper.rb +50 -446
- data/lib/action_view/helpers/javascripts/controls.js +95 -30
- data/lib/action_view/helpers/javascripts/dragdrop.js +161 -21
- data/lib/action_view/helpers/javascripts/effects.js +310 -211
- data/lib/action_view/helpers/javascripts/prototype.js +228 -28
- data/lib/action_view/helpers/number_helper.rb +9 -9
- data/lib/action_view/helpers/pagination_helper.rb +1 -1
- data/lib/action_view/helpers/prototype_helper.rb +900 -0
- data/lib/action_view/helpers/scriptaculous_helper.rb +135 -0
- data/lib/action_view/helpers/text_helper.rb +7 -6
- data/lib/action_view/helpers/url_helper.rb +23 -14
- data/lib/action_view/partials.rb +12 -4
- data/rakefile +13 -5
- data/test/abstract_unit.rb +4 -3
- data/test/active_record_unit.rb +88 -0
- data/test/{controller → activerecord}/active_record_assertions_test.rb +7 -50
- data/test/{controller → activerecord}/active_record_store_test.rb +27 -4
- data/test/activerecord/pagination_test.rb +161 -0
- data/test/controller/action_pack_assertions_test.rb +18 -15
- data/test/controller/base_test.rb +31 -42
- data/test/controller/benchmark_test.rb +8 -11
- data/test/controller/capture_test.rb +33 -1
- data/test/controller/cgi_test.rb +33 -0
- data/test/controller/custom_handler_test.rb +8 -0
- data/test/controller/fake_controllers.rb +9 -17
- data/test/controller/filters_test.rb +32 -3
- data/test/controller/flash_test.rb +26 -41
- data/test/controller/fragment_store_setting_test.rb +1 -1
- data/test/controller/layout_test.rb +73 -0
- data/test/controller/mime_responds_test.rb +257 -0
- data/test/controller/mime_type_test.rb +24 -0
- data/test/controller/new_render_test.rb +157 -1
- data/test/controller/redirect_test.rb +23 -0
- data/test/controller/render_test.rb +54 -56
- data/test/controller/request_test.rb +25 -0
- data/test/controller/routing_test.rb +74 -66
- data/test/controller/test_test.rb +66 -1
- data/test/controller/verification_test.rb +3 -1
- data/test/controller/webservice_test.rb +255 -0
- data/test/fixtures/companies.yml +24 -0
- data/test/fixtures/company.rb +9 -0
- data/test/fixtures/db_definitions/sqlite.sql +42 -0
- data/test/fixtures/developer.rb +7 -0
- data/test/fixtures/developers.yml +21 -0
- data/test/fixtures/developers_projects.yml +13 -0
- data/test/fixtures/layout_tests/layouts/controller_name_space/nested.rhtml +1 -0
- data/test/fixtures/layout_tests/layouts/item.rhtml +1 -0
- data/test/fixtures/layout_tests/layouts/layout_test.rhtml +1 -0
- data/test/fixtures/layout_tests/layouts/third_party_template_library.mab +1 -0
- data/test/fixtures/layout_tests/views/hello.rhtml +1 -0
- data/test/fixtures/multipart/mona_lisa.jpg +0 -0
- data/test/fixtures/project.rb +3 -0
- data/test/fixtures/projects.yml +7 -0
- data/test/fixtures/replies.yml +13 -0
- data/test/fixtures/reply.rb +5 -0
- data/test/fixtures/respond_to/all_types_with_layout.rhtml +1 -0
- data/test/fixtures/respond_to/all_types_with_layout.rjs +1 -0
- data/test/fixtures/respond_to/layouts/standard.rhtml +1 -0
- data/test/fixtures/respond_to/using_defaults.rhtml +1 -0
- data/test/fixtures/respond_to/using_defaults.rjs +1 -0
- data/test/fixtures/respond_to/using_defaults.rxml +1 -0
- data/test/fixtures/respond_to/using_defaults_with_type_list.rhtml +1 -0
- data/test/fixtures/respond_to/using_defaults_with_type_list.rjs +1 -0
- data/test/fixtures/respond_to/using_defaults_with_type_list.rxml +1 -0
- data/test/fixtures/test/block_content_for.rhtml +2 -0
- data/test/fixtures/test/delete_with_js.rjs +2 -0
- data/test/fixtures/test/dot.directory/render_file_with_ivar.rhtml +1 -0
- data/test/fixtures/test/enum_rjs_test.rjs +6 -0
- data/test/fixtures/test/erb_content_for.rhtml +2 -0
- data/test/fixtures/test/hello_world.rxml +3 -0
- data/test/fixtures/test/hello_world_with_layout_false.rhtml +1 -0
- data/test/fixtures/test/non_erb_block_content_for.rxml +4 -0
- data/test/fixtures/topic.rb +3 -0
- data/test/fixtures/topics.yml +22 -0
- data/test/template/active_record_helper_test.rb +4 -0
- data/test/template/asset_tag_helper_test.rb +7 -2
- data/test/template/date_helper_test.rb +39 -2
- data/test/template/form_helper_test.rb +238 -5
- data/test/template/form_options_helper_test.rb +78 -0
- data/test/template/form_tag_helper_test.rb +11 -0
- data/test/template/java_script_macros_helper_test.rb +51 -6
- data/test/template/javascript_helper_test.rb +7 -153
- data/test/template/number_helper_test.rb +14 -13
- data/test/template/prototype_helper_test.rb +423 -0
- data/test/template/scriptaculous_helper_test.rb +90 -0
- data/test/template/text_helper_test.rb +12 -9
- data/test/template/url_helper_test.rb +31 -15
- metadata +291 -246
- data/lib/action_controller/cgi_ext/multipart_progress.rb +0 -169
- data/lib/action_controller/upload_progress.rb +0 -473
- data/lib/action_controller/vendor/html-scanner/html/node.rb.rej +0 -17
- data/lib/action_view/helpers/upload_progress_helper.rb +0 -433
- data/lib/action_view/vendor/builder.rb +0 -13
- data/lib/action_view/vendor/builder/blankslate.rb +0 -53
- data/lib/action_view/vendor/builder/xmlbase.rb +0 -143
- data/lib/action_view/vendor/builder/xmlevents.rb +0 -63
- data/lib/action_view/vendor/builder/xmlmarkup.rb +0 -308
- data/test/controller/multipart_progress_testx.rb +0 -365
- data/test/controller/upload_progress_testx.rb +0 -89
- data/test/template/upload_progress_helper_testx.rb +0 -136
@@ -85,8 +85,9 @@ module Test #:nodoc:
|
|
85
85
|
assert_equal(eurl, url, msg) if eurl && url
|
86
86
|
assert_equal(epath, path, msg) if epath && path
|
87
87
|
else
|
88
|
-
|
89
|
-
|
88
|
+
@response_diff = options.diff(@response.redirected_to) if options.is_a?(Hash) && @response.redirected_to.is_a?(Hash)
|
89
|
+
msg = build_message(message, "response is not a redirection to all of the options supplied (redirection is <?>)#{', difference: <?>' if @response_diff}",
|
90
|
+
@response.redirected_to || @response.redirect_url, @response_diff)
|
90
91
|
|
91
92
|
assert_block(msg) do
|
92
93
|
if options.is_a?(Symbol)
|
@@ -302,19 +303,17 @@ module Test #:nodoc:
|
|
302
303
|
end
|
303
304
|
|
304
305
|
# ensures that the passed record is valid by active record standards. returns the error messages if not
|
305
|
-
def assert_valid(record)
|
306
|
+
def assert_valid(record)
|
306
307
|
clean_backtrace do
|
307
|
-
assert record.valid?, record.errors.full_messages
|
308
|
+
assert record.valid?, record.errors.full_messages.join("\n")
|
308
309
|
end
|
309
310
|
end
|
310
311
|
|
311
312
|
def clean_backtrace(&block)
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
raise AssertionFailedError, e.message, e.backtrace.reject { |line| File.expand_path(line) =~ /#{path}/ }
|
317
|
-
end
|
313
|
+
yield
|
314
|
+
rescue AssertionFailedError => e
|
315
|
+
path = File.expand_path(__FILE__)
|
316
|
+
raise AssertionFailedError, e.message, e.backtrace.reject { |line| File.expand_path(line) =~ /#{path}/ }
|
318
317
|
end
|
319
318
|
end
|
320
319
|
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'action_controller/mime_type'
|
1
2
|
require 'action_controller/request'
|
2
3
|
require 'action_controller/response'
|
3
4
|
require 'action_controller/routing'
|
@@ -40,6 +41,13 @@ module ActionController #:nodoc:
|
|
40
41
|
super(message || DEFAULT_MESSAGE)
|
41
42
|
end
|
42
43
|
end
|
44
|
+
class RedirectBackError < ActionControllerError #:nodoc:
|
45
|
+
DEFAULT_MESSAGE = 'No HTTP_REFERER was set in the request to this action, so redirect_to :back could not be called successfully. If this is a test, make sure to specify @request.env["HTTP_REFERER"].'
|
46
|
+
|
47
|
+
def initialize(message = nil)
|
48
|
+
super(message || DEFAULT_MESSAGE)
|
49
|
+
end
|
50
|
+
end
|
43
51
|
|
44
52
|
# Action Controllers are made up of one or more actions that performs its purpose and then either renders a template or
|
45
53
|
# redirects to another action. An action is defined as a public method on the controller, which will automatically be
|
@@ -217,7 +225,9 @@ module ActionController #:nodoc:
|
|
217
225
|
# FCGI.each_cgi{ |cgi| WeblogController.process_cgi(cgi) }
|
218
226
|
class Base
|
219
227
|
DEFAULT_RENDER_STATUS_CODE = "200 OK"
|
220
|
-
|
228
|
+
|
229
|
+
include Reloadable::Subclasses
|
230
|
+
|
221
231
|
# Determines whether the view has access to controller internals @request, @response, @session, and @template.
|
222
232
|
# By default, it does.
|
223
233
|
@@view_controller_internals = true
|
@@ -251,10 +261,37 @@ module ActionController #:nodoc:
|
|
251
261
|
@@allow_concurrency = false
|
252
262
|
cattr_accessor :allow_concurrency
|
253
263
|
|
264
|
+
# Modern REST web services often need to submit complex data to the web application.
|
265
|
+
# The param_parsers hash lets you register handlers wich will process the http body and add parameters to the
|
266
|
+
# @params hash. These handlers are invoked for post and put requests.
|
267
|
+
#
|
268
|
+
# By default application/xml and application/x-yaml are enabled. For application/xml, a XmlSimple class with
|
269
|
+
# the same param name as the root will be instanciated in the @params. This allows XML requests to mask themselves
|
270
|
+
# as regular form submissions, so you can have one action serve both regular forms and web service requests. For
|
271
|
+
# application/x-yaml, the YAML document is merged into the parameters and appears to the application as if the
|
272
|
+
# YAML elements were simply form submissions.
|
273
|
+
#
|
274
|
+
# Example of doing your own parser for a custom content type:
|
275
|
+
#
|
276
|
+
# ActionController::Base.param_parsers[Mime::Type.lookup('application/atom+xml')] = Proc.new do |data|
|
277
|
+
# node = REXML::Document.new(post)
|
278
|
+
# { node.root.name => node.root }
|
279
|
+
# end
|
280
|
+
#
|
281
|
+
# Note: Up until release 1.1 of Rails, Action Controller would default to using XmlSimple configured to discard the
|
282
|
+
# root node for such requests. The new default is to keep the root, such that "<r><name>David</name></r>" results
|
283
|
+
# in params[:r][:name] for "David" instead of params[:name]. To get the old behavior, you can
|
284
|
+
# re-register XmlSimple as application/xml handler ike this:
|
285
|
+
#
|
286
|
+
# ActionController::Base.param_parsers[Mime::XML] =
|
287
|
+
# Proc.new { |data| XmlSimple.xml_in(data, 'ForceArray' => false) }
|
288
|
+
@@param_parsers = { Mime::XML => :xml_simple, Mime::YAML => :yaml }
|
289
|
+
cattr_accessor :param_parsers
|
290
|
+
|
254
291
|
# Template root determines the base from which template references will be made. So a call to render("test/template")
|
255
292
|
# will be converted to "#{template_root}/test/template.rhtml".
|
256
293
|
class_inheritable_accessor :template_root
|
257
|
-
|
294
|
+
|
258
295
|
# The logger is used for generating information on the action run-time (including benchmarking) if available.
|
259
296
|
# Can be set to nil for no logging. Compatible with both Ruby's own Logger and Log4r loggers.
|
260
297
|
cattr_accessor :logger
|
@@ -293,7 +330,7 @@ module ActionController #:nodoc:
|
|
293
330
|
|
294
331
|
# Returns the name of the action this controller is processing.
|
295
332
|
attr_accessor :action_name
|
296
|
-
|
333
|
+
|
297
334
|
class << self
|
298
335
|
# Factory for the standard create, process loop where the controller is discarded after processing.
|
299
336
|
def process(request, response) #:nodoc:
|
@@ -312,19 +349,12 @@ module ActionController #:nodoc:
|
|
312
349
|
|
313
350
|
# Converts the class name from something like "OneModule::TwoModule::NeatController" to "one_module/two_module/neat".
|
314
351
|
def controller_path
|
315
|
-
|
316
|
-
components = self.name.to_s.split('::')
|
317
|
-
components[-1] = $1 if /^(.*)Controller$/ =~ components.last
|
318
|
-
# Accomodate the root Controllers module.
|
319
|
-
components.shift if components.first == 'Controllers'
|
320
|
-
@controller_path = components.map { |name| name.underscore }.join('/')
|
321
|
-
end
|
322
|
-
@controller_path
|
352
|
+
@controller_path ||= name.gsub(/Controller$/, '').underscore
|
323
353
|
end
|
324
354
|
|
325
355
|
# Return an array containing the names of public methods that have been marked hidden from the action processor.
|
326
356
|
# By default, all methods defined in ActionController::Base and included modules are hidden.
|
327
|
-
# More methods can be hidden using
|
357
|
+
# More methods can be hidden using <tt>hide_actions</tt>.
|
328
358
|
def hidden_actions
|
329
359
|
write_inheritable_attribute(:hidden_actions, ActionController::Base.public_instance_methods) unless read_inheritable_attribute(:hidden_actions)
|
330
360
|
read_inheritable_attribute(:hidden_actions)
|
@@ -332,51 +362,32 @@ module ActionController #:nodoc:
|
|
332
362
|
|
333
363
|
# Hide each of the given methods from being callable as actions.
|
334
364
|
def hide_action(*names)
|
335
|
-
write_inheritable_attribute(:hidden_actions, hidden_actions | names.collect {|n| n.to_s})
|
336
|
-
end
|
337
|
-
|
338
|
-
# Set the template root to be one directory behind the root dir of the controller. Examples:
|
339
|
-
# /code/weblog/components/admin/users_controller.rb with Admin::UsersController
|
340
|
-
# will use /code/weblog/components as template root
|
341
|
-
# and find templates in /code/weblog/components/admin/users/
|
342
|
-
#
|
343
|
-
# /code/weblog/components/admin/parties/users_controller.rb with Admin::Parties::UsersController
|
344
|
-
# will also use /code/weblog/components as template root
|
345
|
-
# and find templates in /code/weblog/components/admin/parties/users/
|
346
|
-
def uses_component_template_root
|
347
|
-
path_of_calling_controller = File.dirname(caller[0].split(/:\d+:/).first)
|
348
|
-
path_of_controller_root = path_of_calling_controller.sub(/#{controller_path.split("/")[0..-2]}$/, "") # " (for ruby-mode)
|
349
|
-
self.template_root = path_of_controller_root
|
350
|
-
end
|
351
|
-
|
352
|
-
# Temporary method for enabling upload progress until it's ready to leave experimental mode
|
353
|
-
def enable_upload_progress # :nodoc:
|
354
|
-
require 'action_controller/upload_progress'
|
355
|
-
include ActionController::UploadProgress
|
365
|
+
write_inheritable_attribute(:hidden_actions, hidden_actions | names.collect { |n| n.to_s })
|
356
366
|
end
|
357
367
|
end
|
358
368
|
|
359
|
-
public
|
369
|
+
public
|
360
370
|
# Extracts the action_name from the request parameters and performs that action.
|
361
371
|
def process(request, response, method = :perform_action, *arguments) #:nodoc:
|
362
372
|
initialize_template_class(response)
|
363
373
|
assign_shortcuts(request, response)
|
364
374
|
initialize_current_url
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
log_processing
|
375
|
+
assign_names
|
376
|
+
forget_variables_added_to_assigns
|
377
|
+
|
378
|
+
log_processing
|
369
379
|
send(method, *arguments)
|
370
|
-
|
380
|
+
|
381
|
+
response
|
371
382
|
ensure
|
372
|
-
|
383
|
+
process_cleanup
|
373
384
|
end
|
374
385
|
|
375
386
|
# Returns a URL that has been rewritten according to the options hash and the defined Routes.
|
376
387
|
# (For doing a complete redirect, use redirect_to).
|
377
|
-
#
|
388
|
+
#
|
378
389
|
# <tt>url_for</tt> is used to:
|
379
|
-
#
|
390
|
+
#
|
380
391
|
# All keys given to url_for are forwarded to the Route module, save for the following:
|
381
392
|
# * <tt>:anchor</tt> -- specifies the anchor name to be appended to the path. For example,
|
382
393
|
# <tt>url_for :controller => 'posts', :action => 'show', :id => 10, :anchor => 'comments'</tt>
|
@@ -392,7 +403,7 @@ module ActionController #:nodoc:
|
|
392
403
|
#
|
393
404
|
# The default Routes setup supports a typical Rails path of "controller/action/id" where action and id are optional, with
|
394
405
|
# action defaulting to 'index' when not given. Here are some typical url_for statements and their corresponding URLs:
|
395
|
-
#
|
406
|
+
#
|
396
407
|
# url_for :controller => 'posts', :action => 'recent' # => 'proto://host.com/posts/recent'
|
397
408
|
# url_for :controller => 'posts', :action => 'index' # => 'proto://host.com/posts'
|
398
409
|
# url_for :controller => 'posts', :action => 'show', :id => 10 # => 'proto://host.com/posts/show/10'
|
@@ -401,7 +412,7 @@ module ActionController #:nodoc:
|
|
401
412
|
# <tt>url_for :action => 'some_action'</tt> will retain the current controller, as expected. This behavior extends to
|
402
413
|
# other parameters, including <tt>:controller</tt>, <tt>:id</tt>, and any other parameters that are placed into a Route's
|
403
414
|
# path.
|
404
|
-
#
|
415
|
+
#
|
405
416
|
# The URL helpers such as <tt>url_for</tt> have a limited form of memory: when generating a new URL, they can look for
|
406
417
|
# missing values in the current request's parameters. Routes attempts to guess when a value should and should not be
|
407
418
|
# taken from the defaults. There are a few simple rules on how this is performed:
|
@@ -424,7 +435,7 @@ module ActionController #:nodoc:
|
|
424
435
|
# answer has to do with the order in which the parameters appear in the generated path. In a nutshell, since the
|
425
436
|
# value that appears in the slot for <tt>:first</tt> is not equal to default value for <tt>:first</tt> we stop using
|
426
437
|
# defaults. On it's own, this rule can account for much of the typical Rails URL behavior.
|
427
|
-
#
|
438
|
+
#
|
428
439
|
# Although a convienence, defaults can occasionaly get in your way. In some cases a default persists longer than desired.
|
429
440
|
# The default may be cleared by adding <tt>:name => nil</tt> to <tt>url_for</tt>'s options.
|
430
441
|
# This is often required when writing form helpers, since the defaults in play may vary greatly depending upon where the
|
@@ -577,6 +588,16 @@ module ActionController #:nodoc:
|
|
577
588
|
#
|
578
589
|
# _Deprecation_ _notice_: This used to have the signature <tt>render_template(template, status = 200, type = :rhtml)</tt>
|
579
590
|
#
|
591
|
+
# === Rendering inline JavaScriptGenerator page updates
|
592
|
+
#
|
593
|
+
# In addition to rendering JavaScriptGenerator page updates with Ajax in RJS templates (see ActionView::Base for details),
|
594
|
+
# you can also pass the <tt>:update</tt> parameter to +render+, along with a block, to render page updates inline.
|
595
|
+
#
|
596
|
+
# render :update do |page|
|
597
|
+
# page.replace_html 'user_list', :partial => 'user', :collection => @users
|
598
|
+
# page.visual_effect :highlight, 'user_list'
|
599
|
+
# end
|
600
|
+
#
|
580
601
|
# === Rendering nothing
|
581
602
|
#
|
582
603
|
# Rendering nothing is often convenient in combination with Ajax calls that perform their effect client-side or
|
@@ -587,12 +608,20 @@ module ActionController #:nodoc:
|
|
587
608
|
#
|
588
609
|
# # Renders an empty response with status code 401 (access denied)
|
589
610
|
# render :nothing => true, :status => 401
|
590
|
-
def render(options = nil, deprecated_status = nil) #:doc:
|
611
|
+
def render(options = nil, deprecated_status = nil, &block) #:doc:
|
591
612
|
raise DoubleRenderError, "Can only render or redirect once per action" if performed?
|
592
613
|
|
593
614
|
# Backwards compatibility
|
594
615
|
unless options.is_a?(Hash)
|
595
|
-
|
616
|
+
if options == :update
|
617
|
+
options = {:update => true}
|
618
|
+
else
|
619
|
+
return render_file(options || default_template_name, deprecated_status, true)
|
620
|
+
end
|
621
|
+
end
|
622
|
+
|
623
|
+
if content_type = options[:content_type]
|
624
|
+
headers["Content-Type"] = content_type
|
596
625
|
end
|
597
626
|
|
598
627
|
if text = options[:text]
|
@@ -610,7 +639,10 @@ module ActionController #:nodoc:
|
|
610
639
|
|
611
640
|
elsif action_name = options[:action]
|
612
641
|
render_action(action_name, options[:status], options[:layout])
|
613
|
-
|
642
|
+
|
643
|
+
elsif xml = options[:xml]
|
644
|
+
render_xml(xml, options[:status])
|
645
|
+
|
614
646
|
elsif partial = options[:partial]
|
615
647
|
partial = default_template_name if partial == true
|
616
648
|
if collection = options[:collection]
|
@@ -619,6 +651,13 @@ module ActionController #:nodoc:
|
|
619
651
|
render_partial(partial, ActionView::Base::ObjectWrapper.new(options[:object]), options[:locals], options[:status])
|
620
652
|
end
|
621
653
|
|
654
|
+
elsif options[:update]
|
655
|
+
add_variables_to_assigns
|
656
|
+
@template.send :evaluate_assigns
|
657
|
+
|
658
|
+
generator = ActionView::Helpers::PrototypeHelper::JavaScriptGenerator.new(@template, &block)
|
659
|
+
render_javascript(generator.to_s)
|
660
|
+
|
622
661
|
elsif options[:nothing]
|
623
662
|
# Safari doesn't pass the headers of the return if the response is zero length
|
624
663
|
render_text(" ", options[:status])
|
@@ -632,74 +671,87 @@ module ActionController #:nodoc:
|
|
632
671
|
|
633
672
|
# Renders according to the same rules as <tt>render</tt>, but returns the result in a string instead
|
634
673
|
# of sending it as the response body to the browser.
|
635
|
-
def render_to_string(options = nil) #:doc:
|
636
|
-
result = render(options)
|
674
|
+
def render_to_string(options = nil, &block) #:doc:
|
675
|
+
result = render(options, &block)
|
676
|
+
|
637
677
|
erase_render_results
|
638
|
-
|
639
|
-
|
678
|
+
forget_variables_added_to_assigns
|
679
|
+
reset_variables_added_to_assigns
|
680
|
+
|
640
681
|
result
|
641
682
|
end
|
642
683
|
|
643
|
-
def render_action(action_name, status = nil, with_layout = true)
|
644
|
-
|
645
|
-
|
684
|
+
def render_action(action_name, status = nil, with_layout = true) #:nodoc:
|
685
|
+
template = default_template_name(action_name.to_s)
|
686
|
+
if with_layout && !template_exempt_from_layout?(template)
|
687
|
+
render_with_layout(template, status)
|
646
688
|
else
|
647
|
-
|
689
|
+
render_without_layout(template, status)
|
648
690
|
end
|
649
691
|
end
|
650
692
|
|
651
|
-
def render_file(template_path, status = nil, use_full_path = false, locals = {})
|
693
|
+
def render_file(template_path, status = nil, use_full_path = false, locals = {}) #:nodoc:
|
652
694
|
add_variables_to_assigns
|
653
|
-
|
695
|
+
assert_existence_of_template_file(template_path) if use_full_path
|
654
696
|
logger.info("Rendering #{template_path}" + (status ? " (#{status})" : '')) if logger
|
655
697
|
render_text(@template.render_file(template_path, use_full_path, locals), status)
|
656
698
|
end
|
657
699
|
|
658
|
-
def render_template(template, status = nil, type = :rhtml, local_assigns = {})
|
700
|
+
def render_template(template, status = nil, type = :rhtml, local_assigns = {}) #:nodoc:
|
659
701
|
add_variables_to_assigns
|
660
702
|
render_text(@template.render_template(type, template, nil, local_assigns), status)
|
661
703
|
end
|
662
704
|
|
663
|
-
def render_text(text = nil, status = nil)
|
705
|
+
def render_text(text = nil, status = nil) #:nodoc:
|
664
706
|
@performed_render = true
|
665
707
|
@response.headers['Status'] = (status || DEFAULT_RENDER_STATUS_CODE).to_s
|
666
708
|
@response.body = text
|
667
709
|
end
|
668
710
|
|
669
|
-
def
|
711
|
+
def render_javascript(javascript, status = nil) #:nodoc:
|
712
|
+
@response.headers['Content-Type'] = 'text/javascript; charset=UTF-8'
|
713
|
+
render_text(javascript, status)
|
714
|
+
end
|
715
|
+
|
716
|
+
def render_xml(xml, status = nil) #:nodoc:
|
717
|
+
@response.headers['Content-Type'] = 'application/xml'
|
718
|
+
render_text(xml, status)
|
719
|
+
end
|
720
|
+
|
721
|
+
def render_nothing(status = nil) #:nodoc:
|
670
722
|
render_text(' ', status)
|
671
723
|
end
|
672
724
|
|
673
|
-
def render_partial(partial_path = default_template_name, object = nil, local_assigns = nil, status = nil)
|
725
|
+
def render_partial(partial_path = default_template_name, object = nil, local_assigns = nil, status = nil) #:nodoc:
|
674
726
|
add_variables_to_assigns
|
675
727
|
render_text(@template.render_partial(partial_path, object, local_assigns), status)
|
676
728
|
end
|
677
729
|
|
678
|
-
def render_partial_collection(partial_name, collection, partial_spacer_template = nil, local_assigns = nil, status = nil)
|
730
|
+
def render_partial_collection(partial_name, collection, partial_spacer_template = nil, local_assigns = nil, status = nil) #:nodoc:
|
679
731
|
add_variables_to_assigns
|
680
732
|
render_text(@template.render_partial_collection(partial_name, collection, partial_spacer_template, local_assigns), status)
|
681
733
|
end
|
682
734
|
|
683
|
-
def render_with_layout(template_name = default_template_name, status = nil, layout = nil)
|
735
|
+
def render_with_layout(template_name = default_template_name, status = nil, layout = nil) #:nodoc:
|
684
736
|
render_with_a_layout(template_name, status, layout)
|
685
737
|
end
|
686
738
|
|
687
|
-
def render_without_layout(template_name = default_template_name, status = nil)
|
739
|
+
def render_without_layout(template_name = default_template_name, status = nil) #:nodoc:
|
688
740
|
render_with_no_layout(template_name, status)
|
689
741
|
end
|
690
742
|
|
691
743
|
|
692
744
|
# Clears the rendered results, allowing for another render to be performed.
|
693
|
-
def erase_render_results
|
745
|
+
def erase_render_results #:nodoc:
|
694
746
|
@response.body = nil
|
695
747
|
@performed_render = false
|
696
748
|
end
|
697
|
-
|
749
|
+
|
698
750
|
# Clears the redirected results from the headers, resets the status to 200 and returns
|
699
751
|
# the URL that was used to redirect or nil if there was no redirected URL
|
700
752
|
# Note that +redirect_to+ will change the body of the response to indicate a redirection.
|
701
753
|
# The response body is not reset here, see +erase_render_results+
|
702
|
-
def erase_redirect_results
|
754
|
+
def erase_redirect_results #:nodoc:
|
703
755
|
@performed_redirect = false
|
704
756
|
response.redirected_to = nil
|
705
757
|
response.redirected_to_method_params = nil
|
@@ -708,12 +760,12 @@ module ActionController #:nodoc:
|
|
708
760
|
end
|
709
761
|
|
710
762
|
# Erase both render and redirect results
|
711
|
-
def erase_results
|
763
|
+
def erase_results #:nodoc:
|
712
764
|
erase_render_results
|
713
765
|
erase_redirect_results
|
714
766
|
end
|
715
767
|
|
716
|
-
def rewrite_options(options)
|
768
|
+
def rewrite_options(options) #:nodoc:
|
717
769
|
if defaults = default_url_options(options)
|
718
770
|
defaults.merge(options)
|
719
771
|
else
|
@@ -753,7 +805,7 @@ module ActionController #:nodoc:
|
|
753
805
|
case options
|
754
806
|
when %r{^\w+://.*}
|
755
807
|
raise DoubleRenderError if performed?
|
756
|
-
logger.info("Redirected to #{options}")
|
808
|
+
logger.info("Redirected to #{options}") if logger
|
757
809
|
response.redirect(options)
|
758
810
|
response.redirected_to = options
|
759
811
|
@performed_redirect = true
|
@@ -762,7 +814,7 @@ module ActionController #:nodoc:
|
|
762
814
|
redirect_to(request.protocol + request.host_with_port + options)
|
763
815
|
|
764
816
|
when :back
|
765
|
-
redirect_to(request.env["HTTP_REFERER"])
|
817
|
+
request.env["HTTP_REFERER"] ? redirect_to(request.env["HTTP_REFERER"]) : raise(RedirectBackError)
|
766
818
|
|
767
819
|
else
|
768
820
|
if parameters_for_method_reference.empty?
|
@@ -807,12 +859,11 @@ module ActionController #:nodoc:
|
|
807
859
|
|
808
860
|
private
|
809
861
|
def self.view_class
|
810
|
-
|
862
|
+
@view_class ||=
|
811
863
|
# create a new class based on the default template class and include helper methods
|
812
|
-
|
813
|
-
|
814
|
-
|
815
|
-
@view_class
|
864
|
+
returning Class.new(ActionView::Base) do |view_class|
|
865
|
+
view_class.send(:include, master_helper_module)
|
866
|
+
end
|
816
867
|
end
|
817
868
|
|
818
869
|
def self.view_root
|
@@ -835,7 +886,8 @@ module ActionController #:nodoc:
|
|
835
886
|
|
836
887
|
@session = @response.session
|
837
888
|
@template = @response.template
|
838
|
-
@assigns = @response.template.assigns
|
889
|
+
@assigns = @response.template.assigns
|
890
|
+
|
839
891
|
@headers = @response.headers
|
840
892
|
end
|
841
893
|
|
@@ -844,8 +896,11 @@ module ActionController #:nodoc:
|
|
844
896
|
end
|
845
897
|
|
846
898
|
def log_processing
|
847
|
-
logger
|
848
|
-
|
899
|
+
if logger
|
900
|
+
logger.info "\n\nProcessing #{controller_class_name}\##{action_name} (for #{request_origin}) [#{request.method.to_s.upcase}]"
|
901
|
+
logger.info " Session ID: #{@session.session_id}" if @session and @session.respond_to?(:session_id)
|
902
|
+
logger.info " Parameters: #{@params.inspect}"
|
903
|
+
end
|
849
904
|
end
|
850
905
|
|
851
906
|
def perform_action
|
@@ -863,6 +918,10 @@ module ActionController #:nodoc:
|
|
863
918
|
@performed_render || @performed_redirect
|
864
919
|
end
|
865
920
|
|
921
|
+
def assign_names
|
922
|
+
@action_name = (params['action'] || 'index')
|
923
|
+
end
|
924
|
+
|
866
925
|
def action_methods
|
867
926
|
self.class.action_methods
|
868
927
|
end
|
@@ -878,6 +937,14 @@ module ActionController #:nodoc:
|
|
878
937
|
@variables_added = true
|
879
938
|
end
|
880
939
|
end
|
940
|
+
|
941
|
+
def forget_variables_added_to_assigns
|
942
|
+
@variables_added = nil
|
943
|
+
end
|
944
|
+
|
945
|
+
def reset_variables_added_to_assigns
|
946
|
+
@template.instance_variable_set("@assigns_added", nil)
|
947
|
+
end
|
881
948
|
|
882
949
|
def add_instance_variables_to_assigns
|
883
950
|
@@protected_variables_cache ||= protected_instance_variables.inject({}) { |h, k| h[k] = true; h }
|
@@ -897,23 +964,23 @@ module ActionController #:nodoc:
|
|
897
964
|
if view_controller_internals
|
898
965
|
[ "@assigns", "@performed_redirect", "@performed_render" ]
|
899
966
|
else
|
900
|
-
[ "@assigns", "@performed_redirect", "@performed_render", "@request", "@response", "@session", "@cookies", "@template" ]
|
967
|
+
[ "@assigns", "@performed_redirect", "@performed_render", "@request", "@response", "@session", "@cookies", "@template", "@request_origin", "@parent_controller" ]
|
901
968
|
end
|
902
969
|
end
|
903
970
|
|
904
|
-
|
905
971
|
def request_origin
|
906
|
-
|
972
|
+
# this *needs* to be cached!
|
973
|
+
# otherwise you'd get different results if calling it more than once
|
974
|
+
@request_origin ||= "#{@request.remote_ip} at #{Time.now.to_s(:db)}"
|
907
975
|
end
|
908
976
|
|
909
977
|
def complete_request_uri
|
910
|
-
request.protocol
|
978
|
+
"#{@request.protocol}#{@request.host}#{@request.request_uri}"
|
911
979
|
end
|
912
980
|
|
913
981
|
def close_session
|
914
982
|
@session.close unless @session.nil? || Hash === @session
|
915
983
|
end
|
916
|
-
|
917
984
|
|
918
985
|
def template_exists?(template_name = default_template_name)
|
919
986
|
@template.file_exists?(template_name)
|
@@ -923,7 +990,11 @@ module ActionController #:nodoc:
|
|
923
990
|
@template.file_public?(template_name)
|
924
991
|
end
|
925
992
|
|
926
|
-
def
|
993
|
+
def template_exempt_from_layout?(template_name = default_template_name)
|
994
|
+
template_name =~ /\.rjs$/ || (@template.pick_template_extension(template_name) == :rjs rescue false)
|
995
|
+
end
|
996
|
+
|
997
|
+
def assert_existence_of_template_file(template_name)
|
927
998
|
unless template_exists?(template_name) || ignore_missing_templates
|
928
999
|
full_template_path = @template.send(:full_template_path, template_name, 'rhtml')
|
929
1000
|
template_type = (template_name =~ /layouts/i) ? 'layout' : 'template'
|
@@ -931,8 +1002,26 @@ module ActionController #:nodoc:
|
|
931
1002
|
end
|
932
1003
|
end
|
933
1004
|
|
934
|
-
def default_template_name(
|
935
|
-
|
1005
|
+
def default_template_name(action_name = self.action_name)
|
1006
|
+
if action_name
|
1007
|
+
action_name = action_name.to_s
|
1008
|
+
if action_name.include?('/') && template_path_includes_controller?(action_name)
|
1009
|
+
action_name = strip_out_controller(action_name)
|
1010
|
+
end
|
1011
|
+
end
|
1012
|
+
"#{self.class.controller_path}/#{action_name}"
|
1013
|
+
end
|
1014
|
+
|
1015
|
+
def strip_out_controller(path)
|
1016
|
+
path.split('/', 2).last
|
1017
|
+
end
|
1018
|
+
|
1019
|
+
def template_path_includes_controller?(path)
|
1020
|
+
self.class.controller_path.split('/')[-1] == path.split('/')[0]
|
1021
|
+
end
|
1022
|
+
|
1023
|
+
def process_cleanup
|
1024
|
+
close_session
|
936
1025
|
end
|
937
1026
|
end
|
938
1027
|
end
|