diff options
author | David Heinemeier Hansson <david@loudthinking.com> | 2005-05-22 07:43:05 +0000 |
---|---|---|
committer | David Heinemeier Hansson <david@loudthinking.com> | 2005-05-22 07:43:05 +0000 |
commit | 0367317dd62ecd177d57d469a4d57974b75e425b (patch) | |
tree | aea47bdb80239ffdbd43f24387a78bc742b06b72 /actionpack/lib/action_controller | |
parent | dab360e18129c8f4916b78d00d49ed9dda5ccd8a (diff) | |
download | rails-0367317dd62ecd177d57d469a4d57974b75e425b.tar.gz rails-0367317dd62ecd177d57d469a4d57974b75e425b.tar.bz2 rails-0367317dd62ecd177d57d469a4d57974b75e425b.zip |
Deprecated redirect_to_path and redirect_to_url in favor of letting redirect_to do the right thing when passed either a path or url. Introduced r as a unified method for render (still under construction)
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@1349 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
Diffstat (limited to 'actionpack/lib/action_controller')
-rwxr-xr-x | actionpack/lib/action_controller/base.rb | 103 | ||||
-rw-r--r-- | actionpack/lib/action_controller/layout.rb | 34 | ||||
-rwxr-xr-x | actionpack/lib/action_controller/request.rb | 37 | ||||
-rwxr-xr-x | actionpack/lib/action_controller/response.rb | 2 |
4 files changed, 134 insertions, 42 deletions
diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb index 5eba5c7167..c449d33c22 100755 --- a/actionpack/lib/action_controller/base.rb +++ b/actionpack/lib/action_controller/base.rb @@ -439,6 +439,52 @@ module ActionController #:nodoc: end protected + # A unified replacement for the individual renders (work-in-progress). + def r(options = {}, &block) + raise DoubleRenderError, "Can only render or redirect once per action" if performed? + add_variables_to_assigns + options[:status] = (options[:status] || DEFAULT_RENDER_STATUS_CODE).to_s + + if options[:text] + @response.headers["Status"] = options[:status] + @response.body = block_given? ? block : options[:text] + @performed_render = true + return options[:text] + + elsif options[:file] + assert_existance_of_template_file(options[:file]) if options[:use_full_path] + logger.info("Rendering #{options[:file]} (#{options[:status]})") unless logger.nil? + r(options.merge({ :text => @template.render_file(options[:file], options[:use_full_path])})) + + elsif options[:template] + r(options.merge({ :file => options[:template], :use_full_path => true })) + + elsif options[:inline] + r(options.merge({ :text => @template.render_template(options[:type] || :rhtml, options[:inline]) })) + + elsif options[:action] + r(options.merge({ :template => default_template_name(options[:action]) })) + + elsif options[:partial] && options[:collection] + r(options.merge({ + :text => ( + @template.render_partial_collection( + options[:partial], options[:collection], options[:spacer_template], options[:local_assigns] + ) || '' + ) + })) + + elsif options[:partial] + r(options.merge({ :text => @template.render_partial(options[:partial], options[:object], options[:local_assigns]) })) + + elsif options[:nothing] + r(options.merge({ :text => "" })) + + else + r(options.merge({ :template => default_template_name })) + end + end + # Renders the template specified by <tt>template_name</tt>, which defaults to the name of the current controller and action. # So calling +render+ in WeblogController#show will attempt to render "#{template_root}/weblog/show.rhtml" or # "#{template_root}/weblog/show.rxml" (in that order). The template_root is set on the ActionController::Base class and is @@ -480,7 +526,7 @@ module ActionController #:nodoc: def render_text(text = nil, status = nil, &block) #:doc: raise DoubleRenderError, "Can only render or redirect once per action" if performed? add_variables_to_assigns - @response.headers["Status"] = status.to_s || DEFAULT_RENDER_STATUS_CODE + @response.headers["Status"] = (status || DEFAULT_RENDER_STATUS_CODE).to_s @response.body = block_given? ? block : text @performed_render = true end @@ -645,32 +691,51 @@ module ActionController #:nodoc: def default_url_options(options) #:doc: end - # Redirects the browser to an URL that has been rewritten according to the hash of +options+ using a "302 Moved" HTTP header. - # See url_for for a description of the valid options. + # Redirects the browser to the target specified in +options+. This parameter can take one of three forms: + # + # * <tt>Hash</tt>: The URL will be generated by calling url_for with the +options+. + # * <tt>String starting with protocol:// (like http://)</tt>: Is passed straight through as the target for redirection. + # * <tt>String not containing a protocol</tt>: The current current protocol and host is prepended to the string. + # + # Examples: + # redirect_to :action => "show", :id => 5 + # redirect_to "http://www.rubyonrails.org" + # redirect_to "/images/screenshot.jpg" + # + # The redirection happens as a "302 Moved" header. def redirect_to(options = {}, *parameters_for_method_reference) #:doc: - if parameters_for_method_reference.empty? - @response.redirected_to = options - redirect_to_url(url_for(options)) - else - @response.redirected_to, @response.redirected_to_method_params = options, parameters_for_method_reference - redirect_to_url(url_for(options, *parameters_for_method_reference)) + case options + when %r{^\w+://.*} + raise DoubleRenderError, "Can only render or redirect once per action" if performed? + logger.info("Redirected to #{url}") unless logger.nil? + @response.redirect(options) + @performed_redirect = true + + when String + redirect_to(request.protocol + request.host_with_port + options) + + else + if parameters_for_method_reference.empty? + response.redirected_to = options + redirect_to(url_for(options)) + else + response.redirected_to, response.redirected_to_method_params = options, parameters_for_method_reference + redirect_to(url_for(options, *parameters_for_method_reference)) + end end end - # Redirects the browser to the specified <tt>path</tt> within the current host (specified with a leading /). Used to sidestep - # the URL rewriting and go directly to a known path. Example: <tt>redirect_to_path "/images/screenshot.jpg"</tt>. + # Deprecated in favor of calling redirect_to directly with the path. def redirect_to_path(path) #:doc: - redirect_to_url(@request.protocol + @request.host_with_port + path) + redirect_to(path) end - # Redirects the browser to the specified <tt>url</tt>. Used to redirect outside of the current application. Example: - # <tt>redirect_to_url "http://www.rubyonrails.org"</tt>. If the resource has moved permanently, it's possible to pass true as the - # second parameter and the browser will get "301 Moved Permanently" instead of "302 Found". + # Deprecated in favor of calling redirect_to directly with the url. If the resource has moved permanently, it's possible to pass + # true as the second parameter and the browser will get "301 Moved Permanently" instead of "302 Found". This can also be done through + # just setting the headers["Status"] to "301 Moved Permanently" before using the redirect_to. def redirect_to_url(url, permanently = false) #:doc: - raise DoubleRenderError, "Can only render or redirect once per action" if performed? - logger.info("Redirected to #{url}") unless logger.nil? - @response.redirect(url, permanently) - @performed_redirect = true + headers["Status"] = "301 Moved Permanently" if permanently + redirect_to(url) end # Resets the session by clearing out all the objects stored within and initializing a new session object. diff --git a/actionpack/lib/action_controller/layout.rb b/actionpack/lib/action_controller/layout.rb index aca3dbd797..37dba36186 100644 --- a/actionpack/lib/action_controller/layout.rb +++ b/actionpack/lib/action_controller/layout.rb @@ -5,6 +5,10 @@ module ActionController #:nodoc: base.class_eval do alias_method :render_without_layout, :render alias_method :render, :render_with_layout + + alias_method :r_without_layout, :r + alias_method :r, :r_with_layout + class << self alias_method :inherited_without_layout, :inherited end @@ -212,8 +216,33 @@ module ActionController #:nodoc: end end + def r_with_layout(options = {}) + if (layout = active_layout_for_r(options)) && options[:text] + add_variables_to_assigns + logger.info("Rendering #{template_name} within #{layout}") unless logger.nil? + + @content_for_layout = r_without_layout(options) + add_variables_to_assigns + + erase_render_results + r_without_layout(options.merge({ :text => @template.render_file(layout, true)})) + else + r_without_layout(options) + end + end + private - + def active_layout_for_r(options = {}) + case options[:layout] + when FalseClass + nil + when NilClass + active_layout if action_has_layout? + else + active_layout(options[:layout]) + end + end + def action_has_layout? conditions = self.class.layout_conditions case @@ -225,6 +254,5 @@ module ActionController #:nodoc: true end end - end -end +end
\ No newline at end of file diff --git a/actionpack/lib/action_controller/request.rb b/actionpack/lib/action_controller/request.rb index af81f0775a..2cb4377273 100755 --- a/actionpack/lib/action_controller/request.rb +++ b/actionpack/lib/action_controller/request.rb @@ -1,6 +1,8 @@ module ActionController # These methods are available in both the production and test Request objects. class AbstractRequest + cattr_accessor :relative_url_root + # Returns both GET and POST parameters in a single hash. def parameters @parameters ||= request_parameters.merge(query_parameters).merge(path_parameters).with_indifferent_access @@ -57,6 +59,16 @@ module ActionController def yaml_post? post_format == :yaml && post? end + + + # Returns true if the request's "X-Requested-With" header contains + # "XMLHttpRequest". (The Prototype Javascript library sends this header with + # every Ajax request.) + def xml_http_request? + env['HTTP_X_REQUESTED_WITH'] =~ /XMLHttpRequest/i + end + alias xhr? :xml_http_request? + # Determine originating IP address. REMOTE_ADDR is the standard @@ -120,20 +132,15 @@ module ActionController protocol == 'https://' end - # returns the interpreted path to requested resource after - # all the installation directory of this application was taken into account + # Returns the interpreted path to requested resource after all the installation directory of this application was taken into account def path - uri = request_uri - path = uri ? uri.split('?').first : '' - - # cut off the part of the url which leads to the installation directory of this app - path[relative_url_root.length..-1] + path = (uri = request_uri) ? uri.split('?').first : '' + path[relative_url_root.length..-1] # cut off the part of the url which leads to the installation directory of this app end - # returns the path minus the web server relative - # installation directory - def relative_url_root - @@relative_url_root ||= File.dirname(env["SCRIPT_NAME"].to_s).gsub /(^\.$|^\/$)/, '' + # Returns the path minus the web server relative installation directory + def relative_url_root(force_reload = false) + @@relative_url_root ||= File.dirname(env["SCRIPT_NAME"].to_s).gsub(/(^\.$|^\/$)/, '') end def port @@ -158,14 +165,6 @@ module ActionController @path_parameters ||= {} end - # Returns true if the request's "X-Requested-With" header contains - # "XMLHttpRequest". (The Prototype Javascript library sends this header with - # every Ajax request.) - def xml_http_request? - env['HTTP_X_REQUESTED_WITH'] =~ /XMLHttpRequest/i - end - alias xhr? :xml_http_request? - #-- # Must be implemented in the concrete request #++ diff --git a/actionpack/lib/action_controller/response.rb b/actionpack/lib/action_controller/response.rb index 2e6c5fcc37..227aa27cc5 100755 --- a/actionpack/lib/action_controller/response.rb +++ b/actionpack/lib/action_controller/response.rb @@ -8,7 +8,7 @@ module ActionController end def redirect(to_url, permanently = false) - @headers["Status"] = permanently ? "301 Moved Permanently" : "302 Found" + @headers["Status"] ||= "302 Found" @headers["location"] = to_url @body = "<html><body>You are being <a href=\"#{to_url}\">redirected</a>.</body></html>" |