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

Changeset 6120

Show
Ignore:
Timestamp:
02/04/07 20:47:05 (2 years ago)
Author:
rick
Message:

Allow Controllers to have multiple view_paths instead of a single template_root. Closes #2754 [John Long]

Files:

Legend:

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

    r6117 r6120  
    11*SVN* 
     2 
     3* Allow Controllers to have multiple view_paths instead of a single template_root.  Closes #2754 [John Long] 
    24 
    35* Add much-needed html-scanner tests.  Fixed CDATA parsing bug. [Rick] 
  • trunk/actionpack/examples/address_book_controller.rb

    r4715 r6120  
    4343end 
    4444 
    45 ActionController::Base.template_root = File.dirname(__FILE__) 
     45ActionController::Base.view_paths = [ File.dirname(__FILE__) ] 
    4646# ActionController::Base.logger = Logger.new("debug.log") # Remove first comment to turn on logging in current dir 
    4747 
  • trunk/actionpack/examples/benchmark.rb

    r4 r6120  
    2525end 
    2626 
    27 #ActionController::Base.template_root = File.dirname(__FILE__) 
     27#ActionController::Base.view_paths = [ File.dirname(__FILE__) ] 
    2828 
    2929require "benchmark" 
  • trunk/actionpack/examples/blog_controller.cgi

    r4715 r6120  
    4444end 
    4545 
    46 ActionController::Base.template_root = File.dirname(__FILE__) 
     46ActionController::Base.view_paths = [ File.dirname(__FILE__) ] 
    4747# ActionController::Base.logger = Logger.new("debug.log") # Remove first comment to turn on logging in current dir 
    4848 
  • trunk/actionpack/examples/debate_controller.cgi

    r4715 r6120  
    4848end 
    4949 
    50 ActionController::Base.template_root = File.dirname(__FILE__) 
     50ActionController::Base.view_paths = [ File.dirname(__FILE__) ] 
    5151# ActionController::Base.logger = Logger.new("debug.log") # Remove first comment to turn on logging in current dir 
    5252 
  • trunk/actionpack/lib/action_controller/base.rb

    r5927 r6120  
    278278    @@default_charset = "utf-8" 
    279279    cattr_accessor :default_charset 
    280  
    281     # Template root determines the base from which template references will be made. So a call to render("test/template") 
    282     # will be converted to "#{template_root}/test/template.rhtml". 
    283     class_inheritable_accessor :template_root 
    284  
     280     
    285281    # The logger is used for generating information on the action run-time (including benchmarking) if available. 
    286282    # Can be set to nil for no logging. Compatible with both Ruby's own Logger and Log4r loggers. 
     
    358354        write_inheritable_attribute(:hidden_actions, hidden_actions | names.collect { |n| n.to_s }) 
    359355      end 
    360  
     356       
     357      # Deprecated. Use view_paths instead. 
     358      def template_root=(path) 
     359        view_paths.unshift(path) 
     360      end 
     361      deprecate :template_root= => :view_paths 
     362       
     363      # Deprecated. Use view_paths instead. 
     364      def template_root 
     365        view_paths.first 
     366      end 
     367      deprecate :template_root => :view_paths 
     368       
     369      @@view_paths = {} 
     370       
     371      # View load paths determine the bases from which template references can be made. So a call to 
     372      # render("test/template") will be looked up in the view load paths array and the closest match will be 
     373      # returned. 
     374      def view_paths=(value) 
     375        @@view_paths[name] = value 
     376      end 
     377       
     378      # View load paths for controller. 
     379      def view_paths 
     380        if paths = @@view_paths[name] 
     381          paths 
     382        else 
     383          if superclass.respond_to?(:view_paths) 
     384            superclass.view_paths.dup.freeze 
     385          else 
     386            @@view_paths[name] = [] 
     387          end 
     388        end 
     389      end 
     390       
    361391      # Replace sensitive paramater data from the request log. 
    362392      # Filters paramaters that have any of the arguments as a substring. 
     
    535565        self.class.controller_path 
    536566      end 
    537  
     567       
    538568      def session_enabled? 
    539569        request.session_options[:disabled] != false 
     570      end 
     571       
     572      # View load paths for controller. 
     573      def view_paths 
     574        self.class.view_paths 
    540575      end 
    541576 
     
    10311066      end 
    10321067 
    1033       def self.view_root 
    1034         @view_root ||= template_root 
    1035       end 
    1036  
    10371068      def initialize_template_class(response) 
    10381069        raise "You must assign a template class through ActionController.template_class= before processing a request" unless @@template_class 
    10391070 
    1040         response.template = self.class.view_class.new(self.class.view_root, {}, self) 
     1071        response.template = self.class.view_class.new(view_paths, {}, self) 
    10411072        response.redirected_to = nil 
    10421073        @performed_render = @performed_redirect = false 
     
    10571088        assign_deprecated_shortcuts(request, response) 
    10581089      end 
    1059  
    10601090 
    10611091      # TODO: assigns cookies headers params request response template 
     
    11521182 
    11531183      def add_class_variables_to_assigns 
    1154         %w(template_root logger template_class ignore_missing_templates).each do |cvar| 
     1184        %w(view_paths logger template_class ignore_missing_templates).each do |cvar| 
    11551185          @assigns[cvar] = self.send(cvar) 
    11561186        end 
  • trunk/actionpack/lib/action_controller/layout.rb

    r5813 r6120  
    180180        @default_layout ||= read_inheritable_attribute("layout") 
    181181      end 
    182  
     182       
     183      def layout_list #:nodoc: 
     184        view_paths.collect do |path| 
     185          Dir["#{path}/layouts/**/*"] 
     186        end.flatten 
     187      end 
     188       
    183189      private 
    184190        def inherited_with_layout(child) 
    185191          inherited_without_layout(child) 
    186192          layout_match = child.name.underscore.sub(/_controller$/, '').sub(/^controllers\//, '') 
    187           child.layout(layout_match) unless layout_list.grep(%r{layouts/#{layout_match}\.[a-z][0-9a-z]*$}).empty? 
    188         end 
    189  
    190         def layout_list 
    191           Dir.glob("#{template_root}/layouts/**/*") 
     193          child.layout(layout_match) unless child.layout_list.grep(%r{layouts/#{layout_match}\.[a-z][0-9a-z]*$}).empty? 
    192194        end 
    193195 
     
    306308      # we cache this info in a class level hash 
    307309      def layout_directory?(layout_name) 
    308         template_path = File.join(self.class.view_root, 'layouts', layout_name) 
     310        view_paths.find do |path| 
     311          File.file?(File.join(path, 'layouts', layout_name)) 
     312        end 
     313        template_path ||= File.join(view_paths.first, 'layouts', layout_name) 
    309314        dirname = File.dirname(template_path) 
    310315        self.class.send(:layout_directory_exists_cache)[dirname] 
  • trunk/actionpack/lib/action_view/base.rb

    r6057 r6120  
    233233    end 
    234234 
    235     def initialize(base_path = nil, assigns_for_first_render = {}, controller = nil)#:nodoc: 
    236       @base_path, @assigns = base_path, assigns_for_first_render 
     235    def initialize(view_paths = [], assigns_for_first_render = {}, controller = nil)#:nodoc: 
     236      @view_paths = [*view_paths].compact 
     237      @assigns = assigns_for_first_render 
    237238      @assigns_added = nil 
    238239      @controller = controller 
     
    241242 
    242243    # Renders the template present at <tt>template_path</tt>. If <tt>use_full_path</tt> is set to true,  
    243     # it's relative to the template_root, otherwise it's absolute. The hash in <tt>local_assigns</tt>  
     244    # it's relative to the view_paths array, otherwise it's absolute. The hash in <tt>local_assigns</tt>  
    244245    # is made available as local variables. 
    245246    def render_file(template_path, use_full_path = true, local_assigns = {}) #:nodoc: 
     
    269270          raise e 
    270271        else 
    271           raise TemplateError.new(@base_path, template_file_name, @assigns, template_source, e) 
    272         end 
    273       end 
    274     end 
    275  
    276     # Renders the template present at <tt>template_path</tt> (relative to the template_root).  
     272          raise TemplateError.new(find_base_path_for(template_file_name), template_file_name, @assigns, template_source, e) 
     273        end 
     274      end 
     275    end 
     276     
     277    # Renders the template present at <tt>template_path</tt> (relative to the view_paths array).  
    277278    # The hash in <tt>local_assigns</tt> is made available as local variables. 
    278279    def render(options = {}, old_local_assigns = {}, &block) #:nodoc: 
     
    359360    def file_exists?(template_path)#:nodoc: 
    360361      template_file_name, template_file_extension = path_and_extension(template_path) 
    361  
    362362      if template_file_extension 
    363363        template_exists?(template_file_name, template_file_extension) 
    364364      else 
    365365        cached_template_extension(template_path) || 
    366            %w(erb builder javascript delegate).any? do |template_type|  
     366           %w(erb builder javascript delegate).any? do |template_type| 
    367367             send("#{template_type}_template_exists?", template_path) 
    368368           end 
     
    377377    private 
    378378      def full_template_path(template_path, extension) 
    379         "#{@base_path}/#{template_path}.#{extension}" 
     379        file_name = "#{template_path}.#{extension}" 
     380        base_path = find_base_path_for(file_name) 
     381        "#{base_path}/#{file_name}" 
    380382      end 
    381383 
     
    393395        @@cache_template_extensions && @@cached_template_extension[template_path] 
    394396      end 
    395  
     397       
     398      def find_base_path_for(template_file_name) 
     399        @view_paths.find { |p| File.file?(File.join(p, template_file_name)) } 
     400      end 
     401       
    396402      def find_template_extension_for(template_path) 
    397403        if match = delegate_template_exists?(template_path) 
     
    401407        elsif javascript_template_exists?(template_path): :rjs 
    402408        else 
    403           raise ActionViewError, "No rhtml, rxml, rjs or delegate template found for #{template_path} in #{@base_path}" 
     409          raise ActionViewError, "No rhtml, rxml, rjs or delegate template found for #{template_path} in #{@view_paths.inspect}" 
    404410        end 
    405411      end 
     
    537543          end 
    538544 
    539           raise TemplateError.new(@base_path, file_name || template, @assigns, template, e) 
     545          raise TemplateError.new(lookup_template_base_path_for(file_name || template), file_name || template, @assigns, template, e) 
    540546        end 
    541547 
  • trunk/actionpack/README

    r4919 r6120  
    383383  end 
    384384 
    385   WeblogController::Base.template_root = File.dirname(__FILE__) 
     385  WeblogController::Base.view_paths = [ File.dirname(__FILE__) ] 
    386386  WeblogController.process_cgi if $0 == __FILE__ 
    387387 
  • trunk/actionpack/test/activerecord/pagination_test.rb

    r4807 r6120  
    55   
    66  class PaginationController < ActionController::Base 
    7     self.template_root = "#{File.dirname(__FILE__)}/../fixtures/" 
     7    self.view_paths = [ "#{File.dirname(__FILE__)}/../fixtures/" ] 
    88     
    99    def simple_paginate 
  • trunk/actionpack/test/controller/action_pack_assertions_test.rb

    r6055 r6120  
    153153# directory of test_request_response to simulate the behaviour of a 
    154154# production environment 
    155 ActionPackAssertionsController.template_root = File.dirname(__FILE__) + "/../fixtures/" 
     155ActionPackAssertionsController.view_paths = [ File.dirname(__FILE__) + "/../fixtures/" ] 
    156156 
    157157# a test case to exercise the new capabilities TestRequest & TestResponse 
  • trunk/actionpack/test/controller/addresses_render_test.rb

    r4973 r6120  
    2323end 
    2424 
    25 AddressesTestController.template_root = File.dirname(__FILE__) + "/../fixtures/" 
     25AddressesTestController.view_paths = [ File.dirname(__FILE__) + "/../fixtures/" ] 
    2626 
    2727class AddressesTest < Test::Unit::TestCase 
  • trunk/actionpack/test/controller/capture_test.rb

    r5501 r6120  
    2424end 
    2525 
    26 CaptureController.template_root = File.dirname(__FILE__) + "/../fixtures/" 
     26CaptureController.view_paths = [ File.dirname(__FILE__) + "/../fixtures/" ] 
    2727 
    2828class CaptureTest < Test::Unit::TestCase 
  • trunk/actionpack/test/controller/content_type_test.rb

    r5143 r6120  
    4646end 
    4747 
    48 ContentTypeController.template_root = File.dirname(__FILE__) + "/../fixtures/" 
     48ContentTypeController.view_paths = [ File.dirname(__FILE__) + "/../fixtures/" ] 
    4949 
    5050class ContentTypeTest < Test::Unit::TestCase 
  • trunk/actionpack/test/controller/deprecation/deprecated_base_methods_test.rb

    r5757 r6120  
    2222  end 
    2323 
    24   Target.template_root = File.dirname(__FILE__) + "/../../fixtures" 
     24  Target.view_paths = [ File.dirname(__FILE__) + "/../../fixtures" ] 
    2525 
    2626  def setup 
  • trunk/actionpack/test/controller/layout_test.rb

    r5927 r6120  
    11require File.dirname(__FILE__) + '/../abstract_unit' 
    22 
    3 # The template_root must be set on Base and not LayoutTest so that LayoutTest's inherited method has access to 
    4 # the template_root when looking for a layout 
    5 ActionController::Base.template_root = File.dirname(__FILE__) + '/../fixtures/layout_tests/' 
     3# The view_paths array must be set on Base and not LayoutTest so that LayoutTest's inherited 
     4# method has access to the view_paths array when looking for a layout to automatically assign. 
     5old_load_paths = ActionController::Base.view_paths 
     6ActionController::Base.view_paths = [ File.dirname(__FILE__) + '/../fixtures/layout_tests/' ] 
    67 
    78class LayoutTest < ActionController::Base 
    89  def self.controller_path; 'views' end 
     10  self.view_paths = ActionController::Base.view_paths.dup 
    911end 
    1012 
    11 # Restore template root to be unset 
    12 ActionController::Base.template_root = nil 
     13# Restore view_paths to previous value 
     14ActionController::Base.view_paths = old_load_paths 
    1315 
    1416class ProductController < LayoutTest 
  • trunk/actionpack/test/controller/mime_responds_test.rb

    r5697 r6120  
    119119end 
    120120 
    121 RespondToController.template_root = File.dirname(__FILE__) + "/../fixtures/" 
     121RespondToController.view_paths = [ File.dirname(__FILE__) + "/../fixtures/" ] 
    122122 
    123123class MimeControllerTest < Test::Unit::TestCase 
  • trunk/actionpack/test/controller/new_render_test.rb

    r5893 r6120  
    351351end 
    352352 
    353 NewRenderTestController.template_root = File.dirname(__FILE__) + "/../fixtures/" 
    354 Fun::GamesController.template_root = File.dirname(__FILE__) + "/../fixtures/" 
     353NewRenderTestController.view_paths = [ File.dirname(__FILE__) + "/../fixtures/" ] 
     354Fun::GamesController.view_paths = [ File.dirname(__FILE__) + "/../fixtures/" ] 
    355355 
    356356class NewRenderTest < Test::Unit::TestCase 
  • trunk/actionpack/test/controller/render_test.rb

    r5746 r6120  
    135135end 
    136136 
    137 TestController.template_root = File.dirname(__FILE__) + "/../fixtures/" 
    138 Fun::GamesController.template_root = File.dirname(__FILE__) + "/../fixtures/" 
     137TestController.view_paths = [ File.dirname(__FILE__) + "/../fixtures/" ] 
     138Fun::GamesController.view_paths = [ File.dirname(__FILE__) + "/../fixtures/" ] 
    139139 
    140140class RenderTest < Test::Unit::TestCase 
  • trunk/actionpack/test/controller/send_file_test.rb

    r5626 r6120  
    2222end 
    2323 
    24 SendFileController.template_root = File.dirname(__FILE__) + "/../fixtures/" 
     24SendFileController.view_paths = [ File.dirname(__FILE__) + "/../fixtures/" ] 
    2525 
    2626class SendFileTest < Test::Unit::TestCase 
  • trunk/actionpack/test/template/deprecated_instance_variables_test.rb

    r6057 r6120  
    33class DeprecatedViewInstanceVariablesTest < Test::Unit::TestCase 
    44  class DeprecatedInstanceVariablesController < ActionController::Base 
    5     self.template_root = "#{File.dirname(__FILE__)}/../fixtures/" 
     5    self.view_paths = [ "#{File.dirname(__FILE__)}/../fixtures/" ] 
    66 
    77    def self.controller_path; 'deprecated_instance_variables' end 
  • trunk/actionpack/test/template/url_helper_test.rb

    r6070 r6120  
    251251class UrlHelperWithControllerTest < Test::Unit::TestCase 
    252252  class UrlHelperController < ActionController::Base 
    253     self.template_root = "#{File.dirname(__FILE__)}/../fixtures/" 
     253    self.view_paths = [ "#{File.dirname(__FILE__)}/../fixtures/" ] 
    254254 
    255255    def self.controller_path; 'url_helper_with_controller' end 
     
    306306class LinkToUnlessCurrentWithControllerTest < Test::Unit::TestCase 
    307307  class TasksController < ActionController::Base 
    308     self.template_root = "#{File.dirname(__FILE__)}/../fixtures/" 
     308    self.view_paths = ["#{File.dirname(__FILE__)}/../fixtures/"] 
    309309 
    310310    def self.controller_path; 'tasks' end