aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib/action_controller
diff options
context:
space:
mode:
Diffstat (limited to 'actionpack/lib/action_controller')
-rwxr-xr-xactionpack/lib/action_controller/base.rb103
-rw-r--r--actionpack/lib/action_controller/layout.rb34
-rwxr-xr-xactionpack/lib/action_controller/request.rb37
-rwxr-xr-xactionpack/lib/action_controller/response.rb2
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>"