1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
module ActionView
class Template
# Abstract super class
class Path
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 Path guarentees that the arguments are present and
# normalized.
def find_templates(name, details, prefix, partial)
raise NotImplementedError
end
# TODO: Refactor this to abstract out the file system
def initialize_template(file)
t = Template.new(file.split("#{self}/").last, self)
t.load!
t
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.join(',')
".{#{e}}"
end
def formats_glob
@formats_glob ||= begin
formats = Mime::SET.map { |m| m.symbol }
'{' + formats.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 FileSystemPath < Path
def initialize(path, options = {})
raise ArgumentError, "path already is a Path class" if path.is_a?(Path)
super(options)
@path = path
end
# TODO: This is the currently needed API. Make this suck less
# ==== <suck>
attr_reader :path
def to_s
if defined?(RAILS_ROOT)
path.to_s.sub(/^#{Regexp.escape(File.expand_path(RAILS_ROOT))}\//, '')
else
path.to_s
end
end
def to_str
path.to_str
end
def ==(path)
to_str == path.to_str
end
def eql?(path)
to_str == path.to_str
end
# ==== </suck>
def find_templates(name, details, prefix, partial)
if glob = parts_to_glob(name, details, prefix, partial)
cached(glob) do
Dir[glob].map do |path|
initialize_template(path) unless File.directory?(path)
end.compact
end
end
end
private
def parts_to_glob(name, details, prefix, partial)
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
"#{@path}/#{path}#{extensions}#{handler_glob}"
end
end
end
end
|