diff options
Diffstat (limited to 'actionpack/lib')
-rw-r--r-- | actionpack/lib/action_controller/base.rb | 59 | ||||
-rw-r--r-- | actionpack/lib/action_controller/dispatcher.rb | 4 | ||||
-rw-r--r-- | actionpack/lib/action_controller/routing/optimisations.rb | 26 | ||||
-rw-r--r-- | actionpack/lib/action_controller/routing/recognition_optimisation.rb | 8 | ||||
-rw-r--r-- | actionpack/lib/action_controller/test_process.rb | 2 | ||||
-rw-r--r-- | actionpack/lib/action_view/base.rb | 11 | ||||
-rw-r--r-- | actionpack/lib/action_view/helpers/asset_tag_helper.rb | 2 | ||||
-rw-r--r-- | actionpack/lib/action_view/helpers/translation_helper.rb | 9 | ||||
-rw-r--r-- | actionpack/lib/action_view/helpers/url_helper.rb | 17 | ||||
-rw-r--r-- | actionpack/lib/action_view/partials.rb | 2 | ||||
-rw-r--r-- | actionpack/lib/action_view/renderable.rb | 14 |
11 files changed, 117 insertions, 37 deletions
diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb index 006a3039af..cf86c5eed0 100644 --- a/actionpack/lib/action_controller/base.rb +++ b/actionpack/lib/action_controller/base.rb @@ -801,6 +801,19 @@ module ActionController #:nodoc: # # Renders "Hello from code!" # render :text => proc { |response, output| output.write("Hello from code!") } # + # === Rendering XML + # + # Rendering XML sets the content type to application/xml. + # + # # Renders '<name>David</name>' + # render :xml => {:name => "David"}.to_xml + # + # It's not necessary to call <tt>to_xml</tt> on the object you want to render, since <tt>render</tt> will + # automatically do that for you: + # + # # Also renders '<name>David</name>' + # render :xml => {:name => "David"} + # # === Rendering JSON # # Rendering JSON sets the content type to application/json and optionally wraps the JSON in a callback. It is expected @@ -846,8 +859,14 @@ module ActionController #:nodoc: # page.visual_effect :highlight, 'user_list' # end # - # === Rendering with status and location headers + # === Rendering vanilla JavaScript + # + # In addition to using RJS with render :update, you can also just render vanilla JavaScript with :js. + # + # # Renders "alert('hello')" and sets the mime type to text/javascript + # render :js => "alert('hello')" # + # === Rendering with status and location headers # All renders take the <tt>:status</tt> and <tt>:location</tt> options and turn them into headers. They can even be used together: # # render :xml => post.to_xml, :status => :created, :location => post_url(post) @@ -898,6 +917,10 @@ module ActionController #:nodoc: response.content_type ||= Mime::XML render_for_text(xml.respond_to?(:to_xml) ? xml.to_xml : xml, options[:status]) + elsif js = options[:js] + response.content_type ||= Mime::JS + render_for_text(js, options[:status]) + elsif json = options[:json] json = json.to_json unless json.is_a?(String) json = "#{options[:callback]}(#{json})" unless options[:callback].blank? @@ -933,6 +956,7 @@ module ActionController #:nodoc: def render_to_string(options = nil, &block) #:doc: render(options, &block) ensure + response.content_type = nil erase_render_results reset_variables_added_to_assigns end @@ -1056,7 +1080,10 @@ module ActionController #:nodoc: logger.info("Redirected to #{options}") if logger && logger.info? case options - when %r{^\w+://.*} + # The scheme name consist of a letter followed by any combination of + # letters, digits, and the plus ("+"), period ("."), or hyphen ("-") + # characters; and is terminated by a colon (":"). + when %r{^\w[\w\d+.-]*:.*} redirect_to_full_url(options, status) when String redirect_to_full_url(request.protocol + request.host_with_port + options, status) @@ -1201,11 +1228,33 @@ module ActionController #:nodoc: def log_processing if logger && logger.info? - logger.info "\n\nProcessing #{self.class.name}\##{action_name} (for #{request_origin}) [#{request.method.to_s.upcase}]" - logger.info " Session ID: #{@_session.session_id}" if @_session and @_session.respond_to?(:session_id) - logger.info " Parameters: #{respond_to?(:filter_parameters) ? filter_parameters(params).inspect : params.inspect}" + log_processing_for_request_id + log_processing_for_session_id + log_processing_for_parameters end end + + def log_processing_for_request_id + request_id = "\n\nProcessing #{self.class.name}\##{action_name} " + request_id << "to #{params[:format]} " if params[:format] + request_id << "(for #{request_origin}) [#{request.method.to_s.upcase}]" + + logger.info(request_id) + end + + def log_processing_for_session_id + if @_session && @_session.respond_to?(:session_id) && @_session.respond_to?(:dbman) && + !@_session.dbman.is_a?(CGI::Session::CookieStore) + logger.info " Session ID: #{@_session.session_id}" + end + end + + def log_processing_for_parameters + parameters = respond_to?(:filter_parameters) ? filter_parameters(params) : params + parameters = parameters.except(:controller, :action, :format) + + logger.info " Parameters: #{parameters.inspect}" + end def default_render #:nodoc: render diff --git a/actionpack/lib/action_controller/dispatcher.rb b/actionpack/lib/action_controller/dispatcher.rb index 28f8ce3d53..f3e173004a 100644 --- a/actionpack/lib/action_controller/dispatcher.rb +++ b/actionpack/lib/action_controller/dispatcher.rb @@ -28,6 +28,10 @@ module ActionController end after_dispatch :flush_logger if Base.logger && Base.logger.respond_to?(:flush) + + to_prepare do + I18n.reload! + end end # Backward-compatible class method takes CGI-specific args. Deprecated diff --git a/actionpack/lib/action_controller/routing/optimisations.rb b/actionpack/lib/action_controller/routing/optimisations.rb index 894d4109e4..0a87303bda 100644 --- a/actionpack/lib/action_controller/routing/optimisations.rb +++ b/actionpack/lib/action_controller/routing/optimisations.rb @@ -20,14 +20,20 @@ module ActionController class Optimiser attr_reader :route, :kind + GLOBAL_GUARD_CONDITIONS = [ + "(!defined?(default_url_options) || default_url_options.blank?)", + "(!defined?(controller.default_url_options) || controller.default_url_options.blank?)", + "defined?(request)", + "request" + ] def initialize(route, kind) @route = route @kind = kind end - def guard_condition - 'false' + def guard_conditions + ["false"] end def generation_code @@ -36,6 +42,7 @@ module ActionController def source_code if applicable? + guard_condition = (GLOBAL_GUARD_CONDITIONS + guard_conditions).join(" && ") "return #{generation_code} if #{guard_condition}\n" else "\n" @@ -57,14 +64,14 @@ module ActionController # return a string like "/people/#{@person.to_param}" # rather than triggering the expensive logic in +url_for+. class PositionalArguments < Optimiser - def guard_condition + def guard_conditions number_of_arguments = route.segment_keys.size # if they're using foo_url(:id=>2) it's one # argument, but we don't want to generate /foos/id2 if number_of_arguments == 1 - "(!defined?(default_url_options) || default_url_options.blank?) && defined?(request) && request && args.size == 1 && !args.first.is_a?(Hash)" + ["args.size == 1", "!args.first.is_a?(Hash)"] else - "(!defined?(default_url_options) || default_url_options.blank?) && defined?(request) && request && args.size == #{number_of_arguments}" + ["args.size == #{number_of_arguments}"] end end @@ -98,8 +105,13 @@ module ActionController # above, but it supports additional query parameters as the last # argument class PositionalArgumentsWithAdditionalParams < PositionalArguments - def guard_condition - "(!defined?(default_url_options) || default_url_options.blank?) && defined?(request) && request && args.size == #{route.segment_keys.size + 1} && !args.last.has_key?(:anchor) && !args.last.has_key?(:port) && !args.last.has_key?(:host)" + def guard_conditions + [ + "args.size == #{route.segment_keys.size + 1}", + "!args.last.has_key?(:anchor)", + "!args.last.has_key?(:port)", + "!args.last.has_key?(:host)" + ] end # This case uses almost the same code as positional arguments, diff --git a/actionpack/lib/action_controller/routing/recognition_optimisation.rb b/actionpack/lib/action_controller/routing/recognition_optimisation.rb index 4935432d87..6c47ced6d1 100644 --- a/actionpack/lib/action_controller/routing/recognition_optimisation.rb +++ b/actionpack/lib/action_controller/routing/recognition_optimisation.rb @@ -153,13 +153,7 @@ module ActionController def clear_recognize_optimized! remove_recognize_optimized! - - class << self - def recognize_optimized(path, environment) - write_recognize_optimized! - recognize_optimized(path, environment) - end - end + write_recognize_optimized! end def remove_recognize_optimized! diff --git a/actionpack/lib/action_controller/test_process.rb b/actionpack/lib/action_controller/test_process.rb index f84c48f102..7a31f0e8d5 100644 --- a/actionpack/lib/action_controller/test_process.rb +++ b/actionpack/lib/action_controller/test_process.rb @@ -218,7 +218,7 @@ module ActionController #:nodoc: # Returns the template of the file which was used to # render this response (or nil) def rendered_template - template.send(:_first_render) + template.instance_variable_get(:@_first_render) end # A shortcut to the flash. Returns an empty hash if no session flash exists. diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index e22978fe27..945246a39a 100644 --- a/actionpack/lib/action_view/base.rb +++ b/actionpack/lib/action_view/base.rb @@ -222,6 +222,7 @@ module ActionView #:nodoc: def initialize(view_paths = [], assigns_for_first_render = {}, controller = nil)#:nodoc: @assigns = assigns_for_first_render @assigns_added = nil + @_render_stack = [] @controller = controller @helpers = ProxyModule.new(self) self.view_paths = view_paths @@ -271,9 +272,13 @@ module ActionView #:nodoc: end end - private - attr_accessor :_first_render, :_last_render + # Access the current template being rendered. + # Returns a ActionView::Template object. + def template + @_render_stack.last + end + private # Evaluates the local assigns and controller ivars, pushes them to the view. def _evaluate_assigns_and_ivars #:nodoc: unless @assigns_added @@ -312,7 +317,7 @@ module ActionView #:nodoc: template elsif template = self.view_paths[template_file_name] template - elsif _first_render && template = self.view_paths["#{template_file_name}.#{_first_render.format_and_extension}"] + elsif @_render_stack.first && template = self.view_paths["#{template_file_name}.#{@_render_stack.first.format_and_extension}"] template elsif template_format == :js && template = self.view_paths["#{template_file_name}.html"] @template_format = :html diff --git a/actionpack/lib/action_view/helpers/asset_tag_helper.rb b/actionpack/lib/action_view/helpers/asset_tag_helper.rb index 93d38eb929..8bbe74b7ef 100644 --- a/actionpack/lib/action_view/helpers/asset_tag_helper.rb +++ b/actionpack/lib/action_view/helpers/asset_tag_helper.rb @@ -588,8 +588,8 @@ module ActionView source += ".#{extension}" if missing_extension?(source) unless source =~ ProtocolRegexp source = "/#{directory}/#{source}" unless source[0] == ?/ - source = prepend_relative_url_root(source) source = rewrite_asset_path(source) + source = prepend_relative_url_root(source) end source = prepend_asset_host(source) source diff --git a/actionpack/lib/action_view/helpers/translation_helper.rb b/actionpack/lib/action_view/helpers/translation_helper.rb index de4c1d7689..dc41ef5305 100644 --- a/actionpack/lib/action_view/helpers/translation_helper.rb +++ b/actionpack/lib/action_view/helpers/translation_helper.rb @@ -3,12 +3,11 @@ require 'action_view/helpers/tag_helper' module ActionView module Helpers module TranslationHelper - def translate(*args) - args << args.extract_options!.merge(:raise => true) - I18n.translate *args - + def translate(key, options = {}) + options[:raise] = true + I18n.translate(key, options) rescue I18n::MissingTranslationData => e - keys = I18n.send :normalize_translation_keys, e.locale, e.key, e.options[:scope] + keys = I18n.send(:normalize_translation_keys, e.locale, e.key, e.options[:scope]) content_tag('span', keys.join(', '), :class => 'translation_missing') end alias :t :translate diff --git a/actionpack/lib/action_view/helpers/url_helper.rb b/actionpack/lib/action_view/helpers/url_helper.rb index 7ba42a3b72..2e0eb8766b 100644 --- a/actionpack/lib/action_view/helpers/url_helper.rb +++ b/actionpack/lib/action_view/helpers/url_helper.rb @@ -499,7 +499,7 @@ module ActionView # True if the current request URI was generated by the given +options+. # # ==== Examples - # Let's say we're in the <tt>/shop/checkout</tt> action. + # Let's say we're in the <tt>/shop/checkout?order=desc</tt> action. # # current_page?(:action => 'process') # # => false @@ -507,6 +507,9 @@ module ActionView # current_page?(:controller => 'shop', :action => 'checkout') # # => true # + # current_page?(:controller => 'shop', :action => 'checkout', :order => 'asc) + # # => false + # # current_page?(:action => 'checkout') # # => true # @@ -515,10 +518,18 @@ module ActionView def current_page?(options) url_string = CGI.escapeHTML(url_for(options)) request = @controller.request + # We ignore any extra parameters in the request_uri if the + # submitted url doesn't have any either. This lets the function + # work with things like ?order=asc + if url_string.index("?") + request_uri = request.request_uri + else + request_uri = request.request_uri.split('?').first + end if url_string =~ /^\w+:\/\// - url_string == "#{request.protocol}#{request.host_with_port}#{request.request_uri}" + url_string == "#{request.protocol}#{request.host_with_port}#{request_uri}" else - url_string == request.request_uri + url_string == request_uri end end diff --git a/actionpack/lib/action_view/partials.rb b/actionpack/lib/action_view/partials.rb index 373bb92dc4..8841099900 100644 --- a/actionpack/lib/action_view/partials.rb +++ b/actionpack/lib/action_view/partials.rb @@ -181,7 +181,7 @@ module ActionView ActionController::RecordIdentifier.partial_path(object, controller.class.controller_path) template = _pick_partial_template(_partial_path) local_assigns[template.counter_name] = index - result = template.render_partial(self, object, local_assigns, as) + result = template.render_partial(self, object, local_assigns.dup, as) index += 1 result end.join(spacer) diff --git a/actionpack/lib/action_view/renderable.rb b/actionpack/lib/action_view/renderable.rb index 0134bc988f..c23b8cde89 100644 --- a/actionpack/lib/action_view/renderable.rb +++ b/actionpack/lib/action_view/renderable.rb @@ -25,20 +25,26 @@ module ActionView def render(view, local_assigns = {}) compile(local_assigns) - view.send(:_first_render=, self) unless view.send(:_first_render) - view.send(:_last_render=, self) + stack = view.instance_variable_get(:@_render_stack) + stack.push(self) + + # This is only used for TestResponse to set rendered_template + view.instance_variable_set(:@_first_render, self) unless view.instance_variable_get(:@_first_render) view.send(:_evaluate_assigns_and_ivars) view.send(:_set_controller_content_type, mime_type) if respond_to?(:mime_type) - view.send(method_name(local_assigns), local_assigns) do |*names| + result = view.send(method_name(local_assigns), local_assigns) do |*names| ivar = :@_proc_for_layout - if view.instance_variable_defined?(ivar) and proc = view.instance_variable_get(ivar) + if !view.instance_variable_defined?(:"@content_for_#{names.first}") && view.instance_variable_defined?(ivar) && (proc = view.instance_variable_get(ivar)) view.capture(*names, &proc) elsif view.instance_variable_defined?(ivar = :"@content_for_#{names.first || :layout}") view.instance_variable_get(ivar) end end + + stack.pop + result end def method_name(local_assigns) |