diff options
author | Jeremy Kemper <jeremy@bitsweat.net> | 2009-04-22 18:54:55 -0700 |
---|---|---|
committer | Jeremy Kemper <jeremy@bitsweat.net> | 2009-04-22 18:54:55 -0700 |
commit | 85b1a55f6d296f79c81e81c2ec90370504c1b0e1 (patch) | |
tree | 8db3fa551ec61d40048763b8789dac139c9b4f6e /actionpack/lib/action_view | |
parent | f28bd9557c669cd63c31704202a46dd83f0a4102 (diff) | |
parent | 0a132c2fe13fb2b8d5dade9cf6abd70601376287 (diff) | |
download | rails-85b1a55f6d296f79c81e81c2ec90370504c1b0e1.tar.gz rails-85b1a55f6d296f79c81e81c2ec90370504c1b0e1.tar.bz2 rails-85b1a55f6d296f79c81e81c2ec90370504c1b0e1.zip |
Merge branch 'master' of git@github.com:rails/rails
Diffstat (limited to 'actionpack/lib/action_view')
-rw-r--r-- | actionpack/lib/action_view/paths.rb | 6 | ||||
-rw-r--r-- | actionpack/lib/action_view/render/partials.rb | 7 | ||||
-rw-r--r-- | actionpack/lib/action_view/render/rendering.rb | 4 | ||||
-rw-r--r-- | actionpack/lib/action_view/template/handlers.rb | 4 | ||||
-rw-r--r-- | actionpack/lib/action_view/template/path.rb | 151 | ||||
-rw-r--r-- | actionpack/lib/action_view/template/template.rb | 2 |
6 files changed, 111 insertions, 63 deletions
diff --git a/actionpack/lib/action_view/paths.rb b/actionpack/lib/action_view/paths.rb index 1d0279889c..e48088f344 100644 --- a/actionpack/lib/action_view/paths.rb +++ b/actionpack/lib/action_view/paths.rb @@ -33,18 +33,18 @@ module ActionView #:nodoc: super(*objs.map { |obj| self.class.type_cast(obj) }) end - def find_by_parts(path, extension = nil, prefix = nil, partial = false) + def find_by_parts(path, details = {}, prefix = nil, partial = false) template_path = path.sub(/^\//, '') each do |load_path| - if template = load_path.find_by_parts(template_path, extension, prefix, partial) + if template = load_path.find_by_parts(template_path, details, prefix, partial) return template end end Template.new(path, self) rescue ActionView::MissingTemplate => e - extension ||= [] + extension = details[:formats] || [] raise ActionView::MissingTemplate.new(self, "#{prefix}/#{path}.{#{extension.join(",")}}") end diff --git a/actionpack/lib/action_view/render/partials.rb b/actionpack/lib/action_view/render/partials.rb index e337dcb63b..43f8a1edf8 100644 --- a/actionpack/lib/action_view/render/partials.rb +++ b/actionpack/lib/action_view/render/partials.rb @@ -187,6 +187,7 @@ module ActionView path = ActionController::RecordIdentifier.partial_path(object, controller_path) end _, _, prefix, object = parts = partial_parts(path, options) + parts[1] = {:formats => parts[1]} template = find_by_parts(*parts) _render_partial_object(template, options, (object unless object == true)) end @@ -225,7 +226,7 @@ module ActionView def _render_partial_with_layout(layout, options) if layout prefix = controller && !layout.include?("/") ? controller.controller_path : nil - layout = find_by_parts(layout, formats, prefix, true) + layout = find_by_parts(layout, {:formats => formats}, prefix, true) end content = _render_partial(options) return _render_content_with_layout(content, layout, options[:locals]) @@ -253,7 +254,7 @@ module ActionView def _render_partial_with_layout(layout, options) if layout prefix = controller && !layout.include?("/") ? controller.controller_path : nil - layout = find_by_parts(layout, formats, prefix, true) + layout = find_by_parts(layout, {:formats => formats}, prefix, true) end content = _render_partial(options) return _render_content_with_layout(content, layout, options[:locals]) @@ -321,7 +322,7 @@ module ActionView def _pick_partial_template(partial_path) #:nodoc: prefix = controller_path unless partial_path.include?('/') - find_by_parts(partial_path, formats, prefix, true) + find_by_parts(partial_path, {:formats => formats}, prefix, true) end memoize :_pick_partial_template end diff --git a/actionpack/lib/action_view/render/rendering.rb b/actionpack/lib/action_view/render/rendering.rb index a9b2acecd5..4213b09e48 100644 --- a/actionpack/lib/action_view/render/rendering.rb +++ b/actionpack/lib/action_view/render/rendering.rb @@ -23,10 +23,10 @@ module ActionView return _render_partial_with_layout(layout, options) if options.key?(:partial) return _render_partial_with_block(layout, block, options) if block_given? - layout = find_by_parts(layout, formats) if layout + layout = find_by_parts(layout, {:formats => formats}) if layout if file = options[:file] - template = find_by_parts(file, formats) + template = find_by_parts(file, {:formats => formats}) _render_template_with_layout(template, layout, :locals => options[:locals]) elsif inline = options[:inline] _render_inline(inline, layout, options) diff --git a/actionpack/lib/action_view/template/handlers.rb b/actionpack/lib/action_view/template/handlers.rb index fb85f28851..448ab6731b 100644 --- a/actionpack/lib/action_view/template/handlers.rb +++ b/actionpack/lib/action_view/template/handlers.rb @@ -16,6 +16,10 @@ module ActionView #:nodoc: @@template_handlers = {} @@default_template_handlers = nil + + def self.extensions + @@template_handlers.keys + end # Register a class that knows how to handle template files with the given # extension. This can be used to implement new template types. diff --git a/actionpack/lib/action_view/template/path.rb b/actionpack/lib/action_view/template/path.rb index 9709549b70..660a7e91a2 100644 --- a/actionpack/lib/action_view/template/path.rb +++ b/actionpack/lib/action_view/template/path.rb @@ -1,13 +1,81 @@ module ActionView class Template + # Abstract super class class Path - attr_reader :path, :paths - delegate :hash, :inspect, :to => :path - def initialize(options) - @cache = options[:cache] + @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))}\//, '') @@ -27,61 +95,36 @@ module ActionView def eql?(path) to_str == path.to_str end - - def find_by_parts(name, extensions = nil, prefix = nil, partial = nil) - path = prefix ? "#{prefix}/" : "" + # ==== </suck> - name = name.to_s.split("/") - name[-1] = "_#{name[-1]}" if partial - - path << name.join("/") - - template = nil - - Array(extensions).each do |extension| - extensioned_path = extension ? "#{path}.#{extension}" : path - break if (template = find_template(extensioned_path)) + 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 - template || find_template(path) end - - private - def create_template(file) - Template.new(file.split("#{self}/").last, self) - 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, @paths = path, {} - - # **/*/** is a hax for symlinked directories - load_templates("#{@path}/{**/*,**}/**") if @cache - end - - private - - def load_template(template) - template.load! - template.accessible_paths.each do |path| - @paths[path] = template - end - end - - def find_template(path) - load_templates("#{@path}/#{path}{,.*}") unless @cache - @paths[path] - end - def load_templates(glob) - Dir[glob].each do |file| - load_template(create_template(file)) unless File.directory?(file) + 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
\ No newline at end of file diff --git a/actionpack/lib/action_view/template/template.rb b/actionpack/lib/action_view/template/template.rb index b6967a2013..e541336613 100644 --- a/actionpack/lib/action_view/template/template.rb +++ b/actionpack/lib/action_view/template/template.rb @@ -101,7 +101,7 @@ module ActionView #:nodoc: end def content_type - format.gsub('.', '/') + format && format.gsub('.', '/') end private |