Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Changeset 6736

Show
Ignore:
Timestamp:
05/15/07 06:36:34 (1 year ago)
Author:
rick
Message:

Add some performance enhancements to ActionView.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/actionpack/CHANGELOG

    r6734 r6736  
    11*SVN* 
     2 
     3* Add some performance enhancements to ActionView. 
     4 
     5  * Cache base_paths in @@cached_base_paths 
     6  * Cache template extensions in @@cached_template_extension 
     7  * Remove unnecessary rescues 
    28 
    39* Assume that rendered partials go by the HTML format by default 
  • trunk/actionpack/lib/action_controller/base.rb

    r6731 r6736  
    12141214 
    12151215      def template_exempt_from_layout?(template_name = default_template_name) 
    1216         extension = @template.pick_template_extension(template_name) rescue nil 
     1216        extension = @template && @template.pick_template_extension(template_name) 
    12171217        name_with_extension = !template_name.include?('.') && extension ? "#{template_name}.#{extension}" : template_name 
    12181218        extension == :rjs || @@exempt_from_layout.any? { |ext| name_with_extension =~ ext } 
     
    12211221      def assert_existence_of_template_file(template_name) 
    12221222        unless template_exists?(template_name) || ignore_missing_templates 
    1223           full_template_path = template_name.include?('.') ? template_name : @template.send(:full_template_path, template_name, "#{@template.send(:template_format)}.erb") 
     1223          full_template_path = template_name.include?('.') ? template_name : @template.full_template_path(template_name, "#{@template.template_format}.erb") 
    12241224          template_type = (template_name =~ /layouts/i) ? 'layout' : 'template' 
    12251225          raise(MissingTemplate, "Missing #{template_type} #{full_template_path}") 
  • trunk/actionpack/lib/action_controller/layout.rb

    r6516 r6736  
    215215    def active_layout(passed_layout = nil) 
    216216      layout = passed_layout || self.class.default_layout 
    217  
    218217      active_layout = case layout 
    219218        when String then layout 
  • trunk/actionpack/lib/action_view/base.rb

    r6734 r6736  
    171171    cattr_accessor :cache_template_loading 
    172172 
    173     # Specify whether file extension lookup should be cached
     173    # Specify whether file extension lookup should be cached, and whether template base path lookup should be cached
    174174    # Should be +false+ for development environments. Defaults to +true+. 
    175175    @@cache_template_extensions = true 
     
    209209    # used by pick_template_extension determines whether ext1 or ext2 will be stored. 
    210210    @@cached_template_extension = {} 
     211    # Maps template paths / extensions to  
     212    @@cached_base_paths = {} 
     213 
     214    @@templates_requiring_setup = Set.new(%w(builder rxml rjs)) 
    211215 
    212216    # Order of template handers checked by #file_exists? depending on the current #template_format 
    213     DEFAULT_TEMPLATE_HANDLER_PREFERENCE = %w(erb rhtml builder rxml javascript delegate) 
     217    DEFAULT_TEMPLATE_HANDLER_PREFERENCE = [:erb, :rhtml, :builder, :rxml, :javascript, :delegate] 
    214218    TEMPLATE_HANDLER_PREFERENCES = { 
    215       :js       => %w(javascript erb rhtml builder rxml delegate)
    216       :xml      => %w(builder rxml erb rhtml javascript delegate)
    217       :delegate => %w(delegate) 
     219      :js       => [:javascript, :erb, :rhtml, :builder, :rxml, :delegate]
     220      :xml      => [:builder, :rxml, :erb, :rhtml, :javascript, :delegate]
     221      :delegate => [:delegate] 
    218222    } 
    219223 
     
    263267        else 
    264268          template_extension = pick_template_extension(template_path).to_s 
     269          unless template_extension 
     270            raise ActionViewError, "No #{template_handler_preferences.to_sentence} template found for #{template_path} in #{@view_paths.inspect}" 
     271          end 
    265272          template_file_name = full_template_path(template_path, template_extension) 
    266273          template_extension = template_extension.gsub(/^\w+\./, '') # strip off any formats 
     
    342349    end 
    343350 
     351    # Gets the full template path with base path for the given template_path and extension. 
     352    # 
     353    #   full_template_path('users/show', 'html.erb') 
     354    #   # => '~/rails/app/views/users/show.html.erb 
     355    # 
     356    def full_template_path(template_path, extension) 
     357      if @@cache_template_extensions 
     358        (@@cached_base_paths[template_path] ||= {})[extension.to_s] = find_full_template_path(template_path, extension) 
     359      else 
     360        find_full_template_path(template_path, extension) 
     361      end 
     362    end 
     363 
     364    # Gets the extension for an existing template with the given template_path. 
     365    # Returns the format with the extension if that template exists. 
     366    # 
     367    #   pick_template_extension('users/show') 
     368    #   # => 'html.erb' 
     369    # 
     370    #   pick_template_extension('users/legacy') 
     371    #   # => "rhtml" 
     372    # 
    344373    def pick_template_extension(template_path)#:nodoc: 
    345374      if @@cache_template_extensions 
    346         formatted_template_path = "#{template_path}.#{template_format}" 
    347         @@cached_template_extension[formatted_template_path] ||= find_template_extension_for(template_path) 
     375        (@@cached_template_extension[template_path] ||= {})[template_format] ||= find_template_extension_for(template_path) 
    348376      else 
    349377        find_template_extension_for(template_path) 
     
    357385 
    358386    def erb_template_exists?(template_path)#:nodoc: 
    359       template_exists?(template_path, :erb) && :erb 
     387      template_exists?(template_path, :erb) 
    360388    end 
    361389 
    362390    def builder_template_exists?(template_path)#:nodoc: 
    363       template_exists?(template_path, :builder) && :builder 
     391      template_exists?(template_path, :builder) 
    364392    end 
    365393 
    366394    def rhtml_template_exists?(template_path)#:nodoc: 
    367       template_exists?(template_path, :rhtml) && :rhtml 
     395      template_exists?(template_path, :rhtml) 
    368396    end 
    369397 
    370398    def rxml_template_exists?(template_path)#:nodoc: 
    371       template_exists?(template_path, :rxml) && :rxml 
     399      template_exists?(template_path, :rxml) 
    372400    end 
    373401 
    374402    def javascript_template_exists?(template_path)#:nodoc: 
    375       template_exists?(template_path, :rjs) && :rjs 
     403      template_exists?(template_path, :rjs) 
    376404    end 
    377405 
     
    379407      template_file_name, template_file_extension = path_and_extension(template_path) 
    380408      if template_file_extension 
    381         template_exists?(template_file_name, template_file_extension) && template_file_extension 
     409        template_exists?(template_file_name, template_file_extension) 
    382410      else 
    383         formatted_template_path = "#{template_path}.#{template_format}" 
    384         return true if cached_template_extension(formatted_template_path) 
    385         template_handler_preferences.each do |template_type| 
    386           if extension = send("#{template_type}_template_exists?", formatted_template_path) 
    387             return "#{template_format}.#{extension}" 
    388           end 
    389         end 
    390         template_handler_preferences.each do |template_type| 
    391           if extension = send("#{template_type}_template_exists?", template_path) 
    392             return extension 
    393           end 
    394         end 
    395         nil 
     411        pick_template_extension(template_path) 
    396412      end 
    397413    end 
     
    404420    # symbolized version of the :format parameter of the request, or :html by default. 
    405421    def template_format 
    406       @template_format ||= controller.request.parameters[:format].to_sym rescue :html 
     422      return @template_format if @template_format 
     423      format = controller && controller.respond_to?(:request) && controller.request.parameters[:format] 
     424      @template_format = format.blank? ? :html : format.to_sym 
    407425    end 
    408426 
     
    412430 
    413431    private 
    414       def full_template_path(template_path, extension) 
     432      def find_full_template_path(template_path, extension) 
    415433        file_name = "#{template_path}.#{extension}" 
    416434        base_path = find_base_path_for(file_name) 
    417         "#{base_path}/#{file_name}" 
     435        base_path.blank? ? "" : "#{base_path}/#{file_name}" 
    418436      end 
    419437 
     
    421439      def template_exists?(template_path, extension) 
    422440        file_path = full_template_path(template_path, extension) 
    423         @@method_names.has_key?(file_path) || FileTest.exists?(file_path) 
     441        !file_path.blank? && @@method_names.has_key?(file_path) || FileTest.exists?(file_path) 
    424442      end 
    425443 
     
    429447        [ template_path_without_extension, $1 ] 
    430448      end 
    431  
    432       # Caches the extension for the given formatted template path.  The extension may have the format 
    433       # too, such as 'html.erb'. 
    434       def cached_template_extension(formatted_template_path) 
    435         @@cache_template_extensions && @@cached_template_extension[formatted_template_path] 
    436       end 
    437449       
    438450      # Returns the view path that contains the given relative template path. 
     
    448460      # Determines the template's file extension, such as rhtml, rxml, or rjs. 
    449461      def find_template_extension_for(template_path) 
    450         if extension = file_exists?(template_path) 
    451           return extension 
    452         else 
    453           raise ActionViewError, "No erb, builder, rhtml, rxml, rjs or delegate template found for #{template_path} in #{@view_paths.inspect}" 
    454         end 
     462        find_template_extension_from_handler(template_path, true) || find_template_extension_from_handler(template_path) 
     463      end 
     464 
     465      def find_template_extension_from_handler(template_path, formatted = nil) 
     466        checked_template_path = formatted ? "#{template_path}.#{template_format}" : template_path 
     467        template_handler_preferences.each do |template_type| 
     468          extension = 
     469            case template_type 
     470              when :javascript 
     471                template_exists?(checked_template_path, :rjs) && :rjs 
     472              when :delegate 
     473                delegate_template_exists?(checked_template_path) 
     474              else 
     475                template_exists?(checked_template_path, template_type) && template_type 
     476            end 
     477          if extension 
     478            return formatted ? "#{template_format}.#{extension}" : extension.to_s 
     479          end 
     480        end 
     481        nil 
    455482      end 
    456483 
     
    538565 
    539566      def template_requires_setup?(extension) #:nodoc: 
    540         templates_requiring_setup.include? extension.to_s 
    541       end 
    542  
    543       def templates_requiring_setup #:nodoc: 
    544         %w(builder rxml rjs) 
     567        @@templates_requiring_setup.include? extension.to_s 
    545568      end 
    546569 
  • trunk/actionpack/test/controller/layout_test.rb

    r6516 r6736  
    6767    get :hello 
    6868    assert_equal 'layouts/third_party_template_library', @controller.active_layout 
     69    assert_equal 'layouts/third_party_template_library', @response.layout 
    6970    assert_equal 'Mab', @response.body 
    7071  end