Changeset 8669
- Timestamp:
- 01/19/08 03:20:39 (10 months ago)
- Files:
-
- trunk/actionpack/CHANGELOG (modified) (1 diff)
- trunk/actionpack/lib/action_controller/base.rb (modified) (9 diffs)
- trunk/actionpack/lib/action_controller/dispatcher.rb (modified) (1 diff)
- trunk/actionpack/lib/action_controller/layout.rb (modified) (2 diffs)
- trunk/actionpack/lib/action_view.rb (modified) (1 diff)
- trunk/actionpack/lib/action_view/base.rb (modified) (11 diffs)
- trunk/actionpack/lib/action_view/helpers/cache_helper.rb (modified) (1 diff)
- trunk/actionpack/lib/action_view/template_finder.rb (added)
- trunk/actionpack/test/controller/mime_responds_test.rb (modified) (1 diff)
- trunk/actionpack/test/controller/new_render_test.rb (modified) (2 diffs)
- trunk/actionpack/test/controller/view_paths_test.rb (modified) (4 diffs)
- trunk/actionpack/test/template/template_finder_test.rb (added)
- trunk/railties/environments/development.rb (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/actionpack/CHANGELOG
r8646 r8669 1 1 *SVN* 2 3 * Introduce TemplateFinder to handle view paths and lookups. #10800 [Pratik Naik] 2 4 3 5 * Make render :partial recognise form builders and use the _form partial. #10814 [djanowski] trunk/actionpack/lib/action_controller/base.rb
r8645 r8669 6 6 require 'action_controller/url_rewriter' 7 7 require 'action_controller/status_codes' 8 require 'action_view/template_finder' 8 9 require 'drb' 9 10 require 'set' … … 429 430 def view_paths=(value) 430 431 @view_paths = value 432 ActionView::TemplateFinder.process_view_paths(value) 431 433 end 432 434 … … 441 443 @view_paths = superclass.view_paths.dup if @view_paths.nil? 442 444 view_paths.unshift(*path) 445 ActionView::TemplateFinder.process_view_paths(path) 443 446 end 444 447 … … 453 456 @view_paths = superclass.view_paths.dup if @view_paths.nil? 454 457 view_paths.push(*path) 458 ActionView::TemplateFinder.process_view_paths(path) 455 459 end 456 460 … … 643 647 # View load paths for controller. 644 648 def view_paths 645 @template. view_paths649 @template.finder.view_paths 646 650 end 647 651 648 652 def view_paths=(value) 649 @template. view_paths = value653 @template.finder.view_paths = value # Mutex needed 650 654 end 651 655 … … 657 661 # 658 662 def prepend_view_path(path) 659 @template. prepend_view_path(path)663 @template.finder.prepend_view_path(path) # Mutex needed 660 664 end 661 665 … … 667 671 # 668 672 def append_view_path(path) 669 @template.append_view_path(path)673 @template.finder.append_view_path(path) # Mutex needed 670 674 end 671 675 … … 1250 1254 1251 1255 def template_exists?(template_name = default_template_name) 1252 @template.fi le_exists?(template_name)1256 @template.finder.file_exists?(template_name) 1253 1257 end 1254 1258 … … 1258 1262 1259 1263 def template_exempt_from_layout?(template_name = default_template_name) 1260 extension = @template && @template. pick_template_extension(template_name)1264 extension = @template && @template.finder.pick_template_extension(template_name) 1261 1265 name_with_extension = !template_name.include?('.') && extension ? "#{template_name}.#{extension}" : template_name 1262 1266 @@exempt_from_layout.any? { |ext| name_with_extension =~ ext } trunk/actionpack/lib/action_controller/dispatcher.rb
r8664 r8669 140 140 if unprepared || force 141 141 run_callbacks :prepare_dispatch 142 ActionView::TemplateFinder.reload! unless ActionView::Base.cache_template_loading 142 143 self.unprepared = false 143 144 end trunk/actionpack/lib/action_controller/layout.rb
r8471 r8669 207 207 def normalize_conditions(conditions) 208 208 conditions.inject({}) {|hash, (key, value)| hash.merge(key => [value].flatten.map {|action| action.to_s})} 209 end210 211 def layout_directory_exists_cache212 @@layout_directory_exists_cache ||= Hash.new do |h, dirname|213 h[dirname] = File.directory? dirname214 end215 209 end 216 210 … … 314 308 end 315 309 316 # Does a layout directory for this class exist?317 # we cache this info in a class level hash318 310 def layout_directory?(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 311 @template.finder.find_template_extension_from_handler(File.join('layouts', layout_name)) 323 312 end 324 313 end trunk/actionpack/lib/action_view.rb
r8341 r8669 27 27 require 'action_view/template_handlers/rjs' 28 28 29 require 'action_view/template_finder' 30 29 31 require 'action_view/base' 30 32 require 'action_view/partials' trunk/actionpack/lib/action_view/base.rb
r8624 r8669 151 151 include ERB::Util 152 152 153 attr_reader :first_render 153 attr_reader :first_render, :finder 154 154 attr_accessor :base_path, :assigns, :template_extension 155 attr_accessor :controller , :view_paths155 attr_accessor :controller 156 156 157 157 attr_reader :logger, :response, :headers … … 205 205 # Count the number of inline templates 206 206 @@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 extensions209 # used by pick_template_extension determines whether ext1 or ext2 will be stored.210 @@cached_template_extension = {}211 # Maps template paths / extensions to212 @@cached_base_paths = {}213 207 214 208 # Cache public asset paths … … 242 236 def self.register_template_handler(extension, klass) 243 237 @@template_handlers[extension.to_sym] = klass 238 TemplateFinder.update_extension_cache_for(extension.to_s) 244 239 end 245 240 246 241 def self.template_handler_extensions 247 @@template_handler _extensions ||= @@template_handlers.keys.map(&:to_s).sort242 @@template_handlers.keys.map(&:to_s).sort 248 243 end 249 244 … … 266 261 267 262 def initialize(view_paths = [], assigns_for_first_render = {}, controller = nil)#:nodoc: 268 @view_paths = view_paths.respond_to?(:find) ? view_paths.dup : [*view_paths].compact269 263 @assigns = assigns_for_first_render 270 264 @assigns_added = nil 271 265 @controller = controller 272 @logger = controller && controller.logger 266 @logger = controller && controller.logger 267 @finder = TemplateFinder.new(self, view_paths) 273 268 end 274 269 … … 291 286 292 287 @first_render ||= template_path 293 template_path_without_extension, template_extension = path_and_extension(template_path)288 template_path_without_extension, template_extension = @finder.path_and_extension(template_path) 294 289 if use_full_path 295 290 if template_extension 296 template_file_name = full_template_path(template_path_without_extension, template_extension)291 template_file_name = @finder.pick_template(template_path_without_extension, template_extension) 297 292 else 298 template_extension = pick_template_extension(template_path).to_s293 template_extension = @finder.pick_template_extension(template_path).to_s 299 294 unless template_extension 300 raise ActionViewError, "No template found for #{template_path} in #{ view_paths.inspect}"295 raise ActionViewError, "No template found for #{template_path} in #{@finder.view_paths.inspect}" 301 296 end 302 template_file_name = full_template_path(template_path, template_extension)297 template_file_name = @finder.pick_template(template_path, template_extension) 303 298 template_extension = template_extension.gsub(/^.+\./, '') # strip off any formats 304 299 end … … 310 305 311 306 if template_file_name.blank? 312 raise ActionViewError, "Couldn't find template file for #{template_path} in #{ view_paths.inspect}"307 raise ActionViewError, "Couldn't find template file for #{template_path} in #{@finder.view_paths.inspect}" 313 308 end 314 309 … … 320 315 raise e 321 316 else 322 raise TemplateError.new(find_base_path_for("#{template_path_without_extension}.#{template_extension}") || view_paths.first, template_file_name, @assigns, template_source, e) 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) 323 319 end 324 320 end … … 372 368 end 373 369 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.erb378 #379 def full_template_path(template_path, extension)380 if @@cache_template_extensions381 (@@cached_base_paths[template_path] ||= {})[extension.to_s] ||= find_full_template_path(template_path, extension)382 else383 find_full_template_path(template_path, extension)384 end385 end386 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_extensions398 (@@cached_template_extension[template_path] ||= {})[template_format] ||= find_template_extension_for(template_path)399 else400 find_template_extension_for(template_path)401 end402 end403 404 def file_exists?(template_path)#:nodoc:405 template_file_name, template_file_extension = path_and_extension(template_path)406 if template_file_extension407 template_exists?(template_file_name, template_file_extension)408 else409 template_exists?(template_file_name, pick_template_extension(template_path))410 end411 end412 413 370 # Returns true is the file may be rendered implicitly. 414 371 def file_public?(template_path)#:nodoc: … … 423 380 end 424 381 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 end434 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 end444 445 382 private 446 383 def wrap_content_for_layout(content) … … 448 385 @content_for_layout = content 449 386 returning(yield) { @content_for_layout = original_content_for_layout } 450 end451 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 end457 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 end463 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 end469 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 end474 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 end479 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 end486 487 def find_template_extension_from_handler(template_path, formatted = nil)488 checked_template_path = formatted ? "#{template_path}.#{template_format}" : template_path489 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_s493 end494 end495 nil496 end497 498 # Determine the template extension from the <tt>@first_render</tt> filename499 def find_template_extension_from_first_render500 File.basename(@first_render.to_s)[/^[^.]+\.(.+)$/, 1]501 387 end 502 388 … … 604 490 end 605 491 606 raise TemplateError.new(extract_base_path_from(file_name) || view_paths.first, file_name || template, @assigns, template, e) 492 raise TemplateError.new(@finder.extract_base_path_from(file_name) || 493 @finder.view_paths.first, file_name || template, @assigns, template, e) 607 494 end 608 495 trunk/actionpack/lib/action_view/helpers/cache_helper.rb
r8630 r8669 33 33 # <% end %> 34 34 def cache(name = {}, options = nil, &block) 35 template_extension = find_template_extension_for(first_render)[/\.?(\w+)$/, 1].to_sym35 template_extension = @finder.pick_template_extension(first_render)[/\.?(\w+)$/, 1].to_sym 36 36 handler = Base.handler_class_for_extension(template_extension) 37 37 handler.new(@controller).cache_fragment(block, name, options) trunk/actionpack/test/controller/mime_responds_test.rb
r8564 r8669 438 438 439 439 class AbstractPostController < ActionController::Base 440 class << self 441 def view_paths 442 [ File.dirname(__FILE__) + "/../fixtures/post_test/" ] 443 end 444 end 440 self.view_paths = File.dirname(__FILE__) + "/../fixtures/post_test/" 445 441 end 446 442 trunk/actionpack/test/controller/new_render_test.rb
r8646 r8669 78 78 @secret = 'in the sauce' 79 79 render :file => 'test/render_file_with_ivar', :use_full_path => true 80 end81 82 def render_file_not_using_full_path_with_relative_path83 @secret = 'in the sauce'84 render :file => 'test/../test/render_file_with_ivar', :use_full_path => true85 80 end 86 81 … … 489 484 end 490 485 491 def test_render_file_not_using_full_path_with_relative_path492 get :render_file_not_using_full_path_with_relative_path493 assert_equal "The secret is in the sauce\n", @response.body494 end495 496 486 def test_render_file_not_using_full_path_with_dot_in_path 497 487 get :render_file_not_using_full_path_with_dot_in_path trunk/actionpack/test/controller/view_paths_test.rb
r8645 r8669 17 17 private 18 18 def add_view_path 19 self.class.view_paths.unshift"#{LOAD_PATH_ROOT}/override"19 prepend_view_path "#{LOAD_PATH_ROOT}/override" 20 20 end 21 21 end … … 28 28 def setup 29 29 TestController.view_paths = nil 30 ActionView::Base.cache_template_extensions = false31 30 32 31 @request = ActionController::TestRequest.new … … 46 45 def teardown 47 46 ActiveSupport::Deprecation.behavior = @old_behavior 48 ActionView::Base.cache_template_extensions = true49 47 end 50 48 … … 100 98 101 99 def test_view_paths_override 102 TestController. view_paths.unshift"#{LOAD_PATH_ROOT}/override"100 TestController.prepend_view_path "#{LOAD_PATH_ROOT}/override" 103 101 get :hello_world 104 102 assert_response :success trunk/railties/environments/development.rb
r8183 r8669 13 13 config.action_view.debug_rjs = true 14 14 config.action_controller.perform_caching = false 15 config.action_view.cache_template_extensions = false16 15 17 16 # Don't care if the mailer can't send