From 251a6e492c72d8aea713b7dabd245d68301e455d Mon Sep 17 00:00:00 2001 From: Yehuda Katz + Carl Lerche Date: Wed, 17 Jun 2009 15:39:41 -0700 Subject: Rename path.rb to resolver.rb --- actionpack/lib/action_view/template/resolver.rb | 150 ++++++++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 actionpack/lib/action_view/template/resolver.rb (limited to 'actionpack/lib/action_view/template/resolver.rb') diff --git a/actionpack/lib/action_view/template/resolver.rb b/actionpack/lib/action_view/template/resolver.rb new file mode 100644 index 0000000000..d15f53a11b --- /dev/null +++ b/actionpack/lib/action_view/template/resolver.rb @@ -0,0 +1,150 @@ +require "pathname" +require "action_view/template/template" + +module ActionView + # Abstract superclass + class Resolver + def initialize(options) + @cache = options[:cache] + @cached = {} + end + + # Normalizes the arguments and passes it on to find_template + def find_by_parts(*args) + find_all_by_parts(*args).first + end + + def find_all_by_parts(name, details = {}, prefix = nil, partial = nil) + details[:locales] = [I18n.locale] + name = name.to_s.gsub(handler_matcher, '').split("/") + find_templates(name.pop, details, [prefix, *name].compact.join("/"), partial) + end + + private + + # This is what child classes implement. No defaults are needed + # because Resolver guarantees that the arguments are present and + # normalized. + def find_templates(name, details, prefix, partial) + raise NotImplementedError + end + + def valid_handlers + @valid_handlers ||= TemplateHandlers.extensions + end + + def handler_matcher + @handler_matcher ||= begin + e = valid_handlers.join('|') + /\.(?:#{e})$/ + end + end + + def handler_glob + e = TemplateHandlers.extensions.map{|h| ".#{h},"}.join + "{#{e}}" + end + + def formats_glob + @formats_glob ||= begin + '{' + Mime::SET.symbols.map { |l| ".#{l}," }.join + '}' + end + end + + def cached(key) + return yield unless @cache + return @cached[key] if @cached.key?(key) + @cached[key] = yield + end + end + + class FileSystemResolver < Resolver + + def initialize(path, options = {}) + raise ArgumentError, "path already is a Resolver class" if path.is_a?(Resolver) + super(options) + @path = Pathname.new(path).expand_path + end + + # TODO: This is the currently needed API. Make this suck less + # ==== + attr_reader :path + + def to_s + path.to_s + end + + def to_str + path.to_s + end + + def ==(path) + to_str == path.to_str + end + + def eql?(path) + to_str == path.to_str + end + # ==== + + def find_templates(name, details, prefix, partial, root = "#{@path}/") + if glob = details_to_glob(name, details, prefix, partial, root) + cached(glob) do + Dir[glob].map do |path| + next if File.directory?(path) + source = File.read(path) + identifier = Pathname.new(path).expand_path.to_s + + Template.new(source, identifier, *path_to_details(path)) + end.compact + end + end + end + + private + + # :api: plugin + def details_to_glob(name, details, prefix, partial, root) + path = "" + path << "#{prefix}/" unless prefix.empty? + path << (partial ? "_#{name}" : name) + + extensions = "" + [:locales, :formats].each do |k| + extensions << if exts = details[k] + '{' + exts.map {|e| ".#{e},"}.join + '}' + else + k == :formats ? formats_glob : '' + end + end + + "#{root}#{path}#{extensions}#{handler_glob}" + end + + # TODO: fix me + # :api: plugin + def path_to_details(path) + # [:erb, :format => :html, :locale => :en, :partial => true/false] + if m = path.match(%r'/(_)?[\w-]+(\.[\w-]+)*\.(\w+)$') + partial = m[1] == '_' + details = (m[2]||"").split('.').reject { |e| e.empty? } + handler = Template.handler_class_for_extension(m[3]) + + format = Mime[details.last] && details.pop.to_sym + locale = details.last && details.pop.to_sym + + return handler, :format => format, :locale => locale, :partial => partial + end + end + end + + class FileSystemResolverWithFallback < FileSystemResolver + + def find_templates(name, details, prefix, partial) + templates = super + return super(name, details, prefix, partial, '') if templates.empty? + templates + end + + end +end \ No newline at end of file -- cgit v1.2.3