diff options
Diffstat (limited to 'actionpack/lib/action_view/template/resolver.rb')
-rw-r--r-- | actionpack/lib/action_view/template/resolver.rb | 88 |
1 files changed, 26 insertions, 62 deletions
diff --git a/actionpack/lib/action_view/template/resolver.rb b/actionpack/lib/action_view/template/resolver.rb index 8c81914aac..9a011f7638 100644 --- a/actionpack/lib/action_view/template/resolver.rb +++ b/actionpack/lib/action_view/template/resolver.rb @@ -4,45 +4,31 @@ require "active_support/core_ext/array/wrap" require "action_view/template" module ActionView - # Abstract superclass class Resolver - - class_inheritable_accessor(:registered_details) - self.registered_details = {} - - def self.register_detail(name, options = {}) - registered_details[name] = lambda do |val| - val = Array.wrap(val || yield) - val |= [nil] unless options[:allow_nil] == false - val - end - end - - register_detail(:locale) { [I18n.locale] } - register_detail(:formats) { Mime::SET.symbols } - register_detail(:handlers) { Template::Handlers.extensions } - - def initialize(options = {}) - @cache = options[:cache] - @cached = {} + def initialize + @cached = Hash.new { |h1,k1| h1[k1] = + Hash.new { |h2,k2| h2[k2] = Hash.new { |h3, k3| h3[k3] = {} } } } end def find(*args) find_all(*args).first end - # Normalizes the arguments and passes it on to find_template - def find_all(name, details = {}, prefix = nil, partial = nil) - details = normalize_details(details) + # Normalizes the arguments and passes it on to find_template. + def find_all(name, details = {}, prefix = nil, partial = nil, key=nil) name, prefix = normalize_name(name, prefix) - cached([name, details, prefix, partial]) do + cached(key, prefix, name, partial) do find_templates(name, details, prefix, partial) end end private + def caching? + @caching ||= !defined?(Rails.application) || Rails.application.config.cache_classes + end + # This is what child classes implement. No defaults are needed # because Resolver guarantees that the arguments are present and # normalized. @@ -50,16 +36,6 @@ module ActionView raise NotImplementedError end - def normalize_details(details) - details = details.dup - # TODO: Refactor this concern out of the resolver - details.delete(:formats) if details[:formats] == [:"*/*"] - registered_details.each do |k, v| - details[k] = v.call(details[k]) - end - details - end - # Support legacy foo.erb names even though we now ignore .erb # as well as incorrectly putting part of the path in the template # name instead of the prefix. @@ -71,29 +47,32 @@ module ActionView return parts.pop, [prefix, *parts].compact.join("/") end - def cached(key) - return yield unless @cache - return @cached[key] if @cached.key?(key) - @cached[key] = yield + def cached(key, prefix, name, partial) + return yield unless key && caching? + scope = @cached[key][prefix][name] + if scope.key?(partial) + scope[partial] + else + scope[partial] = yield + end end end class PathResolver < Resolver - EXTENSION_ORDER = [:locale, :formats, :handlers] def to_s @path.to_s end - alias to_path to_s + alias :to_path :to_s + + private def find_templates(name, details, prefix, partial) path = build_path(name, details, prefix, partial) query(path, EXTENSION_ORDER.map { |ext| details[ext] }) end - private - def build_path(name, details, prefix, partial) path = "" path << "#{prefix}/" unless prefix.empty? @@ -133,30 +112,15 @@ module ActionView end class FileSystemResolver < PathResolver - def initialize(path, options = {}) + def initialize(path) raise ArgumentError, "path already is a Resolver class" if path.is_a?(Resolver) - super(options) + super() @path = Pathname.new(path).expand_path end - end - - # TODO: remove hack - class FileSystemResolverWithFallback < Resolver - def initialize(path, options = {}) - super(options) - @paths = [FileSystemResolver.new(path, options), FileSystemResolver.new("", options), FileSystemResolver.new("/", options)] - end - - def find_templates(*args) - @paths.each do |p| - template = p.find_templates(*args) - return template unless template.empty? - end - [] - end - def to_s - @paths.first.to_s + def eql?(resolver) + self.class.equal?(resolver.class) && to_path == resolver.to_path end + alias :== :eql? end end |