Changeset 8683
- Timestamp:
- 01/21/08 20:45:04 (1 year ago)
- Files:
-
- trunk/actionmailer/lib/action_mailer/base.rb (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/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)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/actionmailer/lib/action_mailer/base.rb
r8212 r8683 393 393 def register_template_extension(extension) 394 394 template_extensions << extension 395 end 396 397 def template_root=(root) 398 write_inheritable_attribute(:template_root, root) 399 ActionView::TemplateFinder.process_view_paths(root) 395 400 end 396 401 end trunk/actionpack/lib/action_controller/base.rb
r8676 r8683 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
r8676 r8683 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
r8676 r8683 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
r8676 r8683 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
r8676 r8683 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 … … 290 285 end 291 286 287 # Clear the forward slash at the beginning if exists 288 template_path = template_path.sub(/^\//, '') if use_full_path 289 292 290 @first_render ||= template_path 293 template_path_without_extension, template_extension = path_and_extension(template_path)291 template_path_without_extension, template_extension = @finder.path_and_extension(template_path) 294 292 if use_full_path 295 293 if template_extension 296 template_file_name = full_template_path(template_path_without_extension, template_extension)294 template_file_name = @finder.pick_template(template_path_without_extension, template_extension) 297 295 else 298 template_extension = pick_template_extension(template_path).to_s296 template_extension = @finder.pick_template_extension(template_path).to_s 299 297 unless template_extension 300 raise ActionViewError, "No template found for #{template_path} in #{ view_paths.inspect}"298 raise ActionViewError, "No template found for #{template_path} in #{@finder.view_paths.inspect}" 301 299 end 302 template_file_name = full_template_path(template_path, template_extension)300 template_file_name = @finder.pick_template(template_path, template_extension) 303 301 template_extension = template_extension.gsub(/^.+\./, '') # strip off any formats 304 302 end … … 310 308 311 309 if template_file_name.blank? 312 raise ActionViewError, "Couldn't find template file for #{template_path} in #{ view_paths.inspect}"310 raise ActionViewError, "Couldn't find template file for #{template_path} in #{@finder.view_paths.inspect}" 313 311 end 314 312 … … 320 318 raise e 321 319 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) 320 raise TemplateError.new(@finder.find_base_path_for("#{template_path_without_extension}.#{template_extension}") || 321 @finder.view_paths.first, template_file_name, @assigns, template_source, e) 323 322 end 324 323 end … … 372 371 end 373 372 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 373 # Returns true is the file may be rendered implicitly. 414 374 def file_public?(template_path)#:nodoc: … … 423 383 end 424 384 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 385 private 446 386 def wrap_content_for_layout(content) … … 448 388 @content_for_layout = content 449 389 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 390 end 502 391 … … 604 493 end 605 494 606 raise TemplateError.new(extract_base_path_from(file_name) || view_paths.first, file_name || template, @assigns, template, e) 495 raise TemplateError.new(@finder.extract_base_path_from(file_name) || 496 @finder.view_paths.first, file_name || template, @assigns, template, e) 607 497 end 608 498 trunk/actionpack/lib/action_view/helpers/cache_helper.rb
r8676 r8683 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
r8676 r8683 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
r8676 r8683 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/render_test.rb
r8577 r8683 19 19 def render_hello_world 20 20 render :template => "test/hello_world" 21 end 22 23 def render_hello_world_with_forward_slash 24 render :template => "/test/hello_world" 21 25 end 22 26 … … 222 226 end 223 227 228 def test_render_with_forward_slash 229 get :render_hello_world_with_forward_slash 230 assert_template "test/hello_world" 231 end 232 224 233 def test_render_from_variable 225 234 get :render_hello_world_from_variable trunk/actionpack/test/controller/view_paths_test.rb
r8676 r8683 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