提交 8dd731bc 编写于 作者: J José Valim

Move more normalization up to the lookup context, so it does not have to repeat in every resolver.

上级 1f5e2f2b
......@@ -15,12 +15,10 @@ class LookupContext #:nodoc:
def self.register_detail(name, options = {}, &block)
self.registered_details << name
Setters.send :define_method, :"_#{name}_defaults", &block
Setters.module_eval <<-METHOD, __FILE__, __LINE__ + 1
def #{name}=(value)
value = Array(value.presence || _#{name}_defaults)
#{"value << nil unless value.include?(nil)" unless options[:allow_nil] == false}
unless value == @details[:#{name}]
@details_key, @details = nil, @details.merge(:#{name} => value)
......@@ -69,16 +67,16 @@ def view_paths=(paths)
end
def find(name, prefix = nil, partial = false)
@view_paths.find(name, prefix, partial, details, details_key)
@view_paths.find(*args_for_lookup(name, prefix, partial))
end
alias :find_template :find
def find_all(name, prefix = nil, partial = false)
@view_paths.find_all(name, prefix, partial, details, details_key)
@view_paths.find_all(*args_for_lookup(name, prefix, partial))
end
def exists?(name, prefix = nil, partial = false)
@view_paths.exists?(name, prefix, partial, details, details_key)
@view_paths.exists?(*args_for_lookup(name, prefix, partial))
end
alias :template_exists? :exists?
......@@ -94,6 +92,32 @@ def with_fallbacks
ensure
added_resolvers.times { view_paths.pop }
end
protected
def args_for_lookup(name, prefix, partial) #:nodoc:
name, prefix = normalize_name(name, prefix)
details_key = self.details_key
details = self.details.merge(:handlers => default_handlers)
[name, prefix, partial || false, details, details_key]
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.
def normalize_name(name, prefix) #:nodoc:
name = name.to_s.gsub(handlers_regexp, '')
parts = name.split('/')
return parts.pop, [prefix, *parts].compact.join("/")
end
def default_handlers #:nodoc:
@detault_handlers ||= Template::Handlers.extensions
end
def handlers_regexp #:nodoc:
@handlers_regexp ||= /\.(?:#{default_handlers.join('|')})$/
end
end
module Details
......@@ -113,7 +137,7 @@ def formats
end
# Overload formats= to reject [:"*/*"] values.
def formats=(value, freeze=true)
def formats=(value)
value = nil if value == [:"*/*"]
super(value)
end
......
......@@ -14,15 +14,8 @@ def clear_cache
@cached.clear
end
def find(*args)
find_all(*args).first
end
# Normalizes the arguments and passes it on to find_template.
def find_all(name, prefix=nil, partial=false, details={}, key=nil)
name, prefix = normalize_name(name, prefix)
details = details.merge(:handlers => default_handlers)
cached(key, prefix, name, partial) do
find_templates(name, prefix, partial, details)
end
......@@ -34,10 +27,6 @@ def caching?
@caching ||= !defined?(Rails.application) || Rails.application.config.cache_classes
end
def default_handlers
Template::Handlers.extensions + [nil]
end
# This is what child classes implement. No defaults are needed
# because Resolver guarantees that the arguments are present and
# normalized.
......@@ -45,17 +34,6 @@ def find_templates(name, prefix, partial, details)
raise NotImplementedError
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.
def normalize_name(name, prefix)
handlers = Template::Handlers.extensions.join('|')
name = name.to_s.gsub(/\.(?:#{handlers})$/, '')
parts = name.split('/')
return parts.pop, [prefix, *parts].compact.join("/")
end
def cached(key, prefix, name, partial)
return yield unless key && caching?
scope = @cached[key][prefix][name]
......@@ -93,7 +71,7 @@ def query(partial, path, exts)
query = File.join(@path, path)
exts.each do |ext|
query << '{' << ext.map {|e| e && ".#{e}" }.join(',') << '}'
query << '{' << ext.map {|e| e && ".#{e}" }.join(',') << ',}'
end
Dir[query].reject { |p| File.directory?(p) }.map do |p|
......
......@@ -12,7 +12,7 @@ def initialize(hash = {})
def query(partial, path, exts)
query = Regexp.escape(path)
exts.each do |ext|
query << '(' << ext.map {|e| e && Regexp.escape(".#{e}") }.join('|') << ')'
query << '(' << ext.map {|e| e && Regexp.escape(".#{e}") }.join('|') << '|)'
end
templates = []
......
......@@ -22,14 +22,14 @@ def teardown
end
test "normalizes details on initialization" do
formats = Mime::SET + [nil]
locale = [I18n.locale, nil]
formats = Mime::SET
locale = [I18n.locale]
assert_equal Hash[:formats => formats, :locale => locale], @lookup_context.details
end
test "allows me to set details" do
@lookup_context.details = { :formats => [:html], :locale => :pt }
assert_equal Hash[:formats => [:html, nil], :locale => [:pt, nil]], @lookup_context.details
assert_equal Hash[:formats => [:html], :locale => [:pt]], @lookup_context.details
end
test "does not allow details to be modified in place" do
......@@ -39,17 +39,17 @@ def teardown
test "allows me to update an specific detail" do
@lookup_context.update_details(:locale => :pt)
assert_equal :pt, I18n.locale
formats = Mime::SET + [nil]
locale = [I18n.locale, nil]
formats = Mime::SET
locale = [I18n.locale]
assert_equal Hash[:formats => formats, :locale => locale], @lookup_context.details
end
test "allows me to change some details to execute an specific block of code" do
formats = Mime::SET + [nil]
formats = Mime::SET
@lookup_context.update_details(:locale => :pt) do
assert_equal Hash[:formats => formats, :locale => [:pt, nil]], @lookup_context.details
assert_equal Hash[:formats => formats, :locale => [:pt]], @lookup_context.details
end
assert_equal Hash[:formats => formats, :locale => [:en, nil]], @lookup_context.details
assert_equal Hash[:formats => formats, :locale => [:en]], @lookup_context.details
end
test "provides getters and setters for formats" do
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册