diff options
Diffstat (limited to 'actionpack')
-rw-r--r-- | actionpack/lib/action_view/path_set.rb | 2 | ||||
-rw-r--r-- | actionpack/lib/action_view/template/resolver.rb | 62 | ||||
-rw-r--r-- | actionpack/test/template/render_test.rb | 2 |
3 files changed, 39 insertions, 27 deletions
diff --git a/actionpack/lib/action_view/path_set.rb b/actionpack/lib/action_view/path_set.rb index 8b840a6463..e0cb5d6a70 100644 --- a/actionpack/lib/action_view/path_set.rb +++ b/actionpack/lib/action_view/path_set.rb @@ -35,7 +35,7 @@ module ActionView #:nodoc: each_with_index do |path, i| path = path.to_s if path.is_a?(Pathname) next unless path.is_a?(String) - self[i] = FileSystemResolver.new(path) + self[i] = OptimizedFileSystemResolver.new(path) end end end diff --git a/actionpack/lib/action_view/template/resolver.rb b/actionpack/lib/action_view/template/resolver.rb index 870897958a..2b9427ace5 100644 --- a/actionpack/lib/action_view/template/resolver.rb +++ b/actionpack/lib/action_view/template/resolver.rb @@ -10,17 +10,16 @@ module ActionView attr_reader :name, :prefix, :partial, :virtual alias_method :partial?, :partial - def initialize(name, prefix, partial) - @name, @prefix, @partial = name, prefix, partial - rebuild(@name, @prefix, @partial) + def self.build(name, prefix, partial) + virtual = "" + virtual << "#{prefix}/" unless prefix.empty? + virtual << (partial ? "_#{name}" : name) + new name, prefix, partial, virtual end - def rebuild(name, prefix, partial) - @virtual = "" - @virtual << "#{prefix}/" unless prefix.empty? - @virtual << (partial ? "_#{name}" : name) - - self.replace(@virtual) + def initialize(name, prefix, partial, virtual) + @name, @prefix, @partial = name, prefix, partial + super(virtual) end end @@ -60,7 +59,7 @@ module ActionView # Helpers that builds a path. Useful for building virtual paths. def build_path(name, prefix, partial) - Path.new(name, prefix, partial) + Path.build(name, prefix, partial) end # Handles templates caching. If a key is given and caching is on @@ -112,7 +111,8 @@ module ActionView end end - class PathResolver < Resolver + # An abstract class that implements a Resolver with path semantics. + class PathResolver < Resolver #:nodoc: EXTENSIONS = [:locale, :formats, :handlers] DEFAULT_PATTERN = ":prefix/:action{.:locale,}{.:formats,}{.:handlers,}" @@ -124,13 +124,12 @@ module ActionView private def find_templates(name, prefix, partial, details) - path = build_path(name, prefix, partial) - extensions = Hash[EXTENSIONS.map { |ext| [ext, details[ext]] }.flatten(0)] - query(path, extensions, details[:formats]) + path = Path.build(name, prefix, partial) + query(path, details, details[:formats]) end - def query(path, exts, formats) - query = build_query(path, exts) + def query(path, details, formats) + query = build_query(path, details) templates = [] sanitizer = Hash.new { |h,k| h[k] = Dir["#{File.dirname(k)}/*"] } @@ -138,7 +137,7 @@ module ActionView next if File.directory?(p) || !sanitizer[p].include?(p) handler, format = extract_handler_and_format(p, formats) - contents = File.open(p, "rb") {|io| io.read } + contents = File.open(p, "rb") { |io| io.read } templates << Template.new(contents, File.expand_path(p), handler, :virtual_path => path.virtual, :format => format, :updated_at => mtime(p)) @@ -147,18 +146,15 @@ module ActionView templates end - # Helper for building query glob string based on resolver's pattern. - def build_query(path, exts) + # Helper for building query glob string based on resolver's pattern. + def build_query(path, details) query = @pattern.dup query.gsub!(/\:prefix(\/)?/, path.prefix.empty? ? "" : "#{path.prefix}\\1") # prefix can be empty... query.gsub!(/\:action/, path.partial? ? "_#{path.name}" : path.name) - exts.each { |ext, variants| + details.each do |ext, variants| query.gsub!(/\:#{ext}/, "{#{variants.compact.uniq.join(',')}}") - } - - query.gsub!('.{html,', '.{html,text.html,') - query.gsub!('.{text,', '.{text,text.plain,') + end File.expand_path(query, @path) end @@ -235,9 +231,25 @@ module ActionView alias :== :eql? end + # An Optimized resolver for Rails' most common case. + class OptimizedFileSystemResolver < FileSystemResolver #:nodoc: + def build_query(path, details) + exts = EXTENSIONS.map { |ext| details[ext] } + query = File.join(@path, path) + + exts.each do |ext| + query << "{" + ext.compact.each { |e| query << ".#{e}," } + query << "}" + end + + query + end + end + # The same as FileSystemResolver but does not allow templates to store # a virtual path since it is invalid for such resolvers. - class FallbackFileSystemResolver < FileSystemResolver + class FallbackFileSystemResolver < FileSystemResolver #:nodoc: def self.instances [new(""), new("/")] end diff --git a/actionpack/test/template/render_test.rb b/actionpack/test/template/render_test.rb index d4e912c410..86d08a43a5 100644 --- a/actionpack/test/template/render_test.rb +++ b/actionpack/test/template/render_test.rb @@ -325,7 +325,7 @@ class CachedViewRenderTest < ActiveSupport::TestCase # Ensure view path cache is primed def setup view_paths = ActionController::Base.view_paths - assert_equal ActionView::FileSystemResolver, view_paths.first.class + assert_equal ActionView::OptimizedFileSystemResolver, view_paths.first.class setup_view(view_paths) end |