Changeset 8676
- Timestamp:
- 01/19/08 06:01:57 (8 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 (deleted)
- 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 (deleted)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/actionpack/CHANGELOG
r8674 r8676 2 2 3 3 * 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]6 4 7 5 * Make render :partial recognise form builders and use the _form partial. #10814 [djanowski] trunk/actionpack/lib/action_controller/base.rb
r8669 r8676 6 6 require 'action_controller/url_rewriter' 7 7 require 'action_controller/status_codes' 8 require 'action_view/template_finder'9 8 require 'drb' 10 9 require 'set' … … 430 429 def view_paths=(value) 431 430 @view_paths = value 432 ActionView::TemplateFinder.process_view_paths(value)433 431 end 434 432 … … 443 441 @view_paths = superclass.view_paths.dup if @view_paths.nil? 444 442 view_paths.unshift(*path) 445 ActionView::TemplateFinder.process_view_paths(path)446 443 end 447 444 … … 456 453 @view_paths = superclass.view_paths.dup if @view_paths.nil? 457 454 view_paths.push(*path) 458 ActionView::TemplateFinder.process_view_paths(path)459 455 end 460 456 … … 647 643 # View load paths for controller. 648 644 def view_paths 649 @template. finder.view_paths645 @template.view_paths 650 646 end 651 647 652 648 def view_paths=(value) 653 @template. finder.view_paths = value # Mutex needed649 @template.view_paths = value 654 650 end 655 651 … … 661 657 # 662 658 def prepend_view_path(path) 663 @template. finder.prepend_view_path(path) # Mutex needed659 @template.prepend_view_path(path) 664 660 end 665 661 … … 671 667 # 672 668 def append_view_path(path) 673 @template.finder.append_view_path(path) # Mutex needed669 @template.append_view_path(path) 674 670 end 675 671 … … 1254 1250 1255 1251 def template_exists?(template_name = default_template_name) 1256 @template.fi nder.file_exists?(template_name)1252 @template.file_exists?(template_name) 1257 1253 end 1258 1254 … … 1262 1258 1263 1259 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) 1265 1261 name_with_extension = !template_name.include?('.') && extension ? "#{template_name}.#{extension}" : template_name 1266 1262 @@exempt_from_layout.any? { |ext| name_with_extension =~ ext } trunk/actionpack/lib/action_controller/dispatcher.rb
r8669 r8676 140 140 if unprepared || force 141 141 run_callbacks :prepare_dispatch 142 ActionView::TemplateFinder.reload! unless ActionView::Base.cache_template_loading143 142 self.unprepared = false 144 143 end trunk/actionpack/lib/action_controller/layout.rb
r8669 r8676 209 209 end 210 210 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 211 217 def default_layout_with_format(format, layout) 212 218 list = layout_list … … 308 314 end 309 315 316 # Does a layout directory for this class exist? 317 # we cache this info in a class level hash 310 318 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 312 323 end 313 324 end trunk/actionpack/lib/action_view.rb
r8669 r8676 27 27 require 'action_view/template_handlers/rjs' 28 28 29 require 'action_view/template_finder'30 31 29 require 'action_view/base' 32 30 require 'action_view/partials' trunk/actionpack/lib/action_view/base.rb
r8669 r8676 151 151 include ERB::Util 152 152 153 attr_reader :first_render , :finder153 attr_reader :first_render 154 154 attr_accessor :base_path, :assigns, :template_extension 155 attr_accessor :controller 155 attr_accessor :controller, :view_paths 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 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 = {} 207 213 208 214 # Cache public asset paths … … 236 242 def self.register_template_handler(extension, klass) 237 243 @@template_handlers[extension.to_sym] = klass 238 TemplateFinder.update_extension_cache_for(extension.to_s)239 244 end 240 245 241 246 def self.template_handler_extensions 242 @@template_handler s.keys.map(&:to_s).sort247 @@template_handler_extensions ||= @@template_handlers.keys.map(&:to_s).sort 243 248 end 244 249 … … 261 266 262 267 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 263 269 @assigns = assigns_for_first_render 264 270 @assigns_added = nil 265 271 @controller = controller 266 @logger = controller && controller.logger 267 @finder = TemplateFinder.new(self, view_paths) 272 @logger = controller && controller.logger 268 273 end 269 274 … … 286 291 287 292 @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) 289 294 if use_full_path 290 295 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) 292 297 else 293 template_extension = @finder.pick_template_extension(template_path).to_s298 template_extension = pick_template_extension(template_path).to_s 294 299 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}" 296 301 end 297 template_file_name = @finder.pick_template(template_path, template_extension)302 template_file_name = full_template_path(template_path, template_extension) 298 303 template_extension = template_extension.gsub(/^.+\./, '') # strip off any formats 299 304 end … … 305 310 306 311 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}" 308 313 end 309 314 … … 315 320 raise e 316 321 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) 319 323 end 320 324 end … … 368 372 end 369 373 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 370 413 # Returns true is the file may be rendered implicitly. 371 414 def file_public?(template_path)#:nodoc: … … 380 423 end 381 424 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 382 445 private 383 446 def wrap_content_for_layout(content) … … 385 448 @content_for_layout = content 386 449 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] 387 501 end 388 502 … … 490 604 end 491 605 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) 494 607 end 495 608 trunk/actionpack/lib/action_view/helpers/cache_helper.rb
r8669 r8676 33 33 # <% end %> 34 34 def cache(name = {}, options = nil, &block) 35 template_extension = @finder.pick_template_extension(first_render)[/\.?(\w+)$/, 1].to_sym35 template_extension = find_template_extension_for(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
r8669 r8676 438 438 439 439 class 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 441 445 end 442 446 trunk/actionpack/test/controller/new_render_test.rb
r8669 r8676 78 78 @secret = 'in the sauce' 79 79 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 80 85 end 81 86 … … 484 489 end 485 490 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 486 496 def test_render_file_not_using_full_path_with_dot_in_path 487 497 get :render_file_not_using_full_path_with_dot_in_path trunk/actionpack/test/controller/view_paths_test.rb
r8669 r8676 17 17 private 18 18 def add_view_path 19 prepend_view_path"#{LOAD_PATH_ROOT}/override"19 self.class.view_paths.unshift "#{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 = false 30 31 31 32 @request = ActionController::TestRequest.new … … 45 46 def teardown 46 47 ActiveSupport::Deprecation.behavior = @old_behavior 48 ActionView::Base.cache_template_extensions = true 47 49 end 48 50 … … 98 100 99 101 def test_view_paths_override 100 TestController. prepend_view_path"#{LOAD_PATH_ROOT}/override"102 TestController.view_paths.unshift "#{LOAD_PATH_ROOT}/override" 101 103 get :hello_world 102 104 assert_response :success