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

Changeset 8676

Show
Ignore:
Timestamp:
01/19/08 06:01:57 (8 months ago)
Author:
bitsweat
Message:

Revert r8669 for now, breaks Action Mailer. Reopens #10800.

Files:

Legend:

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

    r8674 r8676  
    22 
    33* Performance: optimize route recognition. Large speedup for apps with many resource routes.  #10835 [oleganza] 
    4  
    5 * Introduce TemplateFinder to handle view paths and lookups.  #10800 [Pratik Naik] 
    64 
    75* Make render :partial recognise form builders and use the _form partial.  #10814 [djanowski] 
  • trunk/actionpack/lib/action_controller/base.rb

    r8669 r8676  
    66require 'action_controller/url_rewriter' 
    77require 'action_controller/status_codes' 
    8 require 'action_view/template_finder' 
    98require 'drb' 
    109require 'set' 
     
    430429      def view_paths=(value) 
    431430        @view_paths = value 
    432         ActionView::TemplateFinder.process_view_paths(value) 
    433431      end 
    434432 
     
    443441        @view_paths = superclass.view_paths.dup if @view_paths.nil? 
    444442        view_paths.unshift(*path) 
    445         ActionView::TemplateFinder.process_view_paths(path) 
    446443      end 
    447444       
     
    456453        @view_paths = superclass.view_paths.dup if @view_paths.nil? 
    457454        view_paths.push(*path) 
    458         ActionView::TemplateFinder.process_view_paths(path) 
    459455      end 
    460456       
     
    647643      # View load paths for controller. 
    648644      def view_paths 
    649         @template.finder.view_paths 
     645        @template.view_paths 
    650646      end 
    651647     
    652648      def view_paths=(value) 
    653         @template.finder.view_paths = value  # Mutex needed 
     649        @template.view_paths = value 
    654650      end 
    655651 
     
    661657      # 
    662658      def prepend_view_path(path) 
    663         @template.finder.prepend_view_path(path)  # Mutex needed 
     659        @template.prepend_view_path(path) 
    664660      end 
    665661       
     
    671667      # 
    672668      def append_view_path(path) 
    673         @template.finder.append_view_path(path)  # Mutex needed 
     669      @template.append_view_path(path) 
    674670      end 
    675671 
     
    12541250 
    12551251      def template_exists?(template_name = default_template_name) 
    1256         @template.finder.file_exists?(template_name) 
     1252        @template.file_exists?(template_name) 
    12571253      end 
    12581254 
     
    12621258 
    12631259      def template_exempt_from_layout?(template_name = default_template_name) 
    1264         extension = @template && @template.finder.pick_template_extension(template_name) 
     1260        extension = @template && @template.pick_template_extension(template_name) 
    12651261        name_with_extension = !template_name.include?('.') && extension ? "#{template_name}.#{extension}" : template_name 
    12661262        @@exempt_from_layout.any? { |ext| name_with_extension =~ ext } 
  • trunk/actionpack/lib/action_controller/dispatcher.rb

    r8669 r8676  
    140140      if unprepared || force 
    141141        run_callbacks :prepare_dispatch 
    142         ActionView::TemplateFinder.reload! unless ActionView::Base.cache_template_loading 
    143142        self.unprepared = false 
    144143      end 
  • trunk/actionpack/lib/action_controller/layout.rb

    r8669 r8676  
    209209        end 
    210210         
     211        def layout_directory_exists_cache 
     212          @@layout_directory_exists_cache ||= Hash.new do |h, dirname| 
     213            h[dirname] = File.directory? dirname 
     214          end 
     215        end 
     216         
    211217        def default_layout_with_format(format, layout) 
    212218          list = layout_list 
     
    308314      end 
    309315       
     316      # Does a layout directory for this class exist? 
     317      # we cache this info in a class level hash 
    310318      def layout_directory?(layout_name) 
    311         @template.finder.find_template_extension_from_handler(File.join('layouts', layout_name)) 
     319        view_paths.find do |path|  
     320          next unless template_path = Dir[File.join(path, 'layouts', layout_name) + ".*"].first 
     321          self.class.send!(:layout_directory_exists_cache)[File.dirname(template_path)] 
     322        end 
    312323      end 
    313324  end 
  • trunk/actionpack/lib/action_view.rb

    r8669 r8676  
    2727require 'action_view/template_handlers/rjs' 
    2828 
    29 require 'action_view/template_finder' 
    30  
    3129require 'action_view/base' 
    3230require 'action_view/partials' 
  • trunk/actionpack/lib/action_view/base.rb

    r8669 r8676  
    151151    include ERB::Util 
    152152 
    153     attr_reader   :first_render, :finder 
     153    attr_reader   :first_render 
    154154    attr_accessor :base_path, :assigns, :template_extension 
    155     attr_accessor :controller 
     155    attr_accessor :controller, :view_paths 
    156156 
    157157    attr_reader :logger, :response, :headers 
     
    205205    # Count the number of inline templates 
    206206    @@inline_template_count = 0 
     207    # Maps template paths without extension to their file extension returned by pick_template_extension. 
     208    # If for a given path, path.ext1 and path.ext2 exist on the file system, the order of extensions 
     209    # used by pick_template_extension determines whether ext1 or ext2 will be stored. 
     210    @@cached_template_extension = {} 
     211    # Maps template paths / extensions to  
     212    @@cached_base_paths = {} 
    207213 
    208214    # Cache public asset paths 
     
    236242    def self.register_template_handler(extension, klass) 
    237243      @@template_handlers[extension.to_sym] = klass 
    238       TemplateFinder.update_extension_cache_for(extension.to_s) 
    239244    end 
    240245 
    241246    def self.template_handler_extensions 
    242       @@template_handlers.keys.map(&:to_s).sort 
     247      @@template_handler_extensions ||= @@template_handlers.keys.map(&:to_s).sort 
    243248    end 
    244249 
     
    261266 
    262267    def initialize(view_paths = [], assigns_for_first_render = {}, controller = nil)#:nodoc: 
     268      @view_paths = view_paths.respond_to?(:find) ? view_paths.dup : [*view_paths].compact 
    263269      @assigns = assigns_for_first_render 
    264270      @assigns_added = nil 
    265271      @controller = controller 
    266       @logger = controller && controller.logger 
    267       @finder = TemplateFinder.new(self, view_paths) 
     272      @logger = controller && controller.logger  
    268273    end 
    269274 
     
    286291       
    287292      @first_render ||= template_path 
    288       template_path_without_extension, template_extension = @finder.path_and_extension(template_path) 
     293      template_path_without_extension, template_extension = path_and_extension(template_path) 
    289294      if use_full_path 
    290295        if template_extension 
    291           template_file_name = @finder.pick_template(template_path_without_extension, template_extension) 
     296          template_file_name = full_template_path(template_path_without_extension, template_extension) 
    292297        else 
    293           template_extension = @finder.pick_template_extension(template_path).to_s 
     298          template_extension = pick_template_extension(template_path).to_s 
    294299          unless template_extension 
    295             raise ActionViewError, "No template found for #{template_path} in #{@finder.view_paths.inspect}" 
     300            raise ActionViewError, "No template found for #{template_path} in #{view_paths.inspect}" 
    296301          end 
    297           template_file_name = @finder.pick_template(template_path, template_extension) 
     302          template_file_name = full_template_path(template_path, template_extension) 
    298303          template_extension = template_extension.gsub(/^.+\./, '') # strip off any formats 
    299304        end 
     
    305310 
    306311      if template_file_name.blank? 
    307         raise ActionViewError, "Couldn't find template file for #{template_path} in #{@finder.view_paths.inspect}" 
     312        raise ActionViewError, "Couldn't find template file for #{template_path} in #{view_paths.inspect}" 
    308313      end 
    309314 
     
    315320          raise e 
    316321        else 
    317           raise TemplateError.new(@finder.find_base_path_for("#{template_path_without_extension}.#{template_extension}") || 
    318                 @finder.view_paths.first, template_file_name, @assigns, template_source, e) 
     322          raise TemplateError.new(find_base_path_for("#{template_path_without_extension}.#{template_extension}") || view_paths.first, template_file_name, @assigns, template_source, e) 
    319323        end 
    320324      end 
     
    368372    end 
    369373 
     374    # Gets the full template path with base path for the given template_path and extension. 
     375    # 
     376    #   full_template_path('users/show', 'html.erb') 
     377    #   # => '~/rails/app/views/users/show.html.erb 
     378    # 
     379    def full_template_path(template_path, extension) 
     380      if @@cache_template_extensions 
     381        (@@cached_base_paths[template_path] ||= {})[extension.to_s] ||= find_full_template_path(template_path, extension) 
     382      else 
     383        find_full_template_path(template_path, extension) 
     384      end 
     385    end 
     386 
     387    # Gets the extension for an existing template with the given template_path. 
     388    # Returns the format with the extension if that template exists. 
     389    # 
     390    #   pick_template_extension('users/show') 
     391    #   # => 'html.erb' 
     392    # 
     393    #   pick_template_extension('users/legacy') 
     394    #   # => "rhtml" 
     395    # 
     396    def pick_template_extension(template_path)#:nodoc: 
     397      if @@cache_template_extensions 
     398        (@@cached_template_extension[template_path] ||= {})[template_format] ||= find_template_extension_for(template_path) 
     399      else 
     400        find_template_extension_for(template_path) 
     401      end 
     402    end 
     403 
     404    def file_exists?(template_path)#:nodoc: 
     405      template_file_name, template_file_extension = path_and_extension(template_path) 
     406      if template_file_extension 
     407        template_exists?(template_file_name, template_file_extension) 
     408      else 
     409        template_exists?(template_file_name, pick_template_extension(template_path)) 
     410      end 
     411    end 
     412 
    370413    # Returns true is the file may be rendered implicitly. 
    371414    def file_public?(template_path)#:nodoc: 
     
    380423    end 
    381424 
     425    # Adds a view_path to the front of the view_paths array. 
     426    # This change affects the current request only. 
     427    # 
     428    #   @template.prepend_view_path("views/default") 
     429    #   @template.prepend_view_path(["views/default", "views/custom"]) 
     430    # 
     431    def prepend_view_path(path) 
     432      @view_paths.unshift(*path) 
     433    end 
     434     
     435    # Adds a view_path to the end of the view_paths array. 
     436    # This change affects the current request only. 
     437    # 
     438    #   @template.append_view_path("views/default") 
     439    #   @template.append_view_path(["views/default", "views/custom"]) 
     440    # 
     441    def append_view_path(path) 
     442      @view_paths.push(*path) 
     443    end 
     444 
    382445    private 
    383446      def wrap_content_for_layout(content) 
     
    385448        @content_for_layout = content 
    386449        returning(yield) { @content_for_layout = original_content_for_layout } 
     450      end 
     451   
     452      def find_full_template_path(template_path, extension) 
     453        file_name = "#{template_path}.#{extension}" 
     454        base_path = find_base_path_for(file_name) 
     455        base_path.blank? ? "" : "#{base_path}/#{file_name}" 
     456      end 
     457 
     458      # Asserts the existence of a template. 
     459      def template_exists?(template_path, extension) 
     460        file_path = full_template_path(template_path, extension) 
     461        !file_path.blank? && @@method_names.has_key?(file_path) || File.exist?(file_path) 
     462      end 
     463 
     464      # Splits the path and extension from the given template_path and returns as an array. 
     465      def path_and_extension(template_path) 
     466        template_path_without_extension = template_path.sub(/\.(\w+)$/, '') 
     467        [ template_path_without_extension, $1 ] 
     468      end 
     469       
     470      # Returns the view path that contains the given relative template path. 
     471      def find_base_path_for(template_file_name) 
     472        view_paths.find { |p| File.file?(File.join(p, template_file_name)) } 
     473      end 
     474 
     475      # Returns the view path that the full path resides in. 
     476      def extract_base_path_from(full_path) 
     477        view_paths.find { |p| full_path[0..p.size - 1] == p } 
     478      end 
     479 
     480      # Determines the template's file extension, such as rhtml, rxml, or rjs. 
     481      def find_template_extension_for(template_path) 
     482        find_template_extension_from_handler(template_path, true) || 
     483        find_template_extension_from_handler(template_path) || 
     484        find_template_extension_from_first_render() 
     485      end 
     486 
     487      def find_template_extension_from_handler(template_path, formatted = nil) 
     488        checked_template_path = formatted ? "#{template_path}.#{template_format}" : template_path 
     489 
     490        self.class.template_handler_extensions.each do |extension| 
     491          if template_exists?(checked_template_path, extension) 
     492            return formatted ? "#{template_format}.#{extension}" : extension.to_s 
     493          end 
     494        end 
     495        nil 
     496      end 
     497       
     498      # Determine the template extension from the <tt>@first_render</tt> filename 
     499      def find_template_extension_from_first_render 
     500        File.basename(@first_render.to_s)[/^[^.]+\.(.+)$/, 1] 
    387501      end 
    388502 
     
    490604          end 
    491605 
    492           raise TemplateError.new(@finder.extract_base_path_from(file_name) || 
    493                 @finder.view_paths.first, file_name || template, @assigns, template, e) 
     606          raise TemplateError.new(extract_base_path_from(file_name) || view_paths.first, file_name || template, @assigns, template, e) 
    494607        end 
    495608 
  • trunk/actionpack/lib/action_view/helpers/cache_helper.rb

    r8669 r8676  
    3333      #    <% end %> 
    3434      def cache(name = {}, options = nil, &block) 
    35         template_extension = @finder.pick_template_extension(first_render)[/\.?(\w+)$/, 1].to_sym 
     35        template_extension = find_template_extension_for(first_render)[/\.?(\w+)$/, 1].to_sym 
    3636        handler = Base.handler_class_for_extension(template_extension) 
    3737        handler.new(@controller).cache_fragment(block, name, options) 
  • trunk/actionpack/test/controller/mime_responds_test.rb

    r8669 r8676  
    438438 
    439439class AbstractPostController < ActionController::Base 
    440   self.view_paths = File.dirname(__FILE__) + "/../fixtures/post_test/" 
     440  class << self 
     441    def view_paths 
     442      [ File.dirname(__FILE__) + "/../fixtures/post_test/" ] 
     443    end 
     444  end 
    441445end 
    442446 
  • trunk/actionpack/test/controller/new_render_test.rb

    r8669 r8676  
    7878    @secret = 'in the sauce' 
    7979    render :file => 'test/render_file_with_ivar', :use_full_path => true 
     80  end 
     81  
     82  def render_file_not_using_full_path_with_relative_path 
     83    @secret = 'in the sauce' 
     84    render :file => 'test/../test/render_file_with_ivar', :use_full_path => true 
    8085  end 
    8186   
     
    484489  end 
    485490 
     491  def test_render_file_not_using_full_path_with_relative_path 
     492    get :render_file_not_using_full_path_with_relative_path 
     493    assert_equal "The secret is in the sauce\n", @response.body 
     494  end 
     495 
    486496  def test_render_file_not_using_full_path_with_dot_in_path 
    487497    get :render_file_not_using_full_path_with_dot_in_path 
  • trunk/actionpack/test/controller/view_paths_test.rb

    r8669 r8676  
    1717    private 
    1818    def add_view_path 
    19       prepend_view_path "#{LOAD_PATH_ROOT}/override" 
     19      self.class.view_paths.unshift "#{LOAD_PATH_ROOT}/override" 
    2020    end 
    2121  end 
     
    2828  def setup 
    2929    TestController.view_paths = nil 
     30    ActionView::Base.cache_template_extensions = false 
    3031 
    3132    @request  = ActionController::TestRequest.new 
     
    4546  def teardown 
    4647    ActiveSupport::Deprecation.behavior = @old_behavior 
     48    ActionView::Base.cache_template_extensions = true 
    4749  end 
    4850   
     
    98100   
    99101  def test_view_paths_override 
    100     TestController.prepend_view_path "#{LOAD_PATH_ROOT}/override" 
     102    TestController.view_paths.unshift "#{LOAD_PATH_ROOT}/override" 
    101103    get :hello_world 
    102104    assert_response :success