aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib/action_view
diff options
context:
space:
mode:
Diffstat (limited to 'actionpack/lib/action_view')
-rw-r--r--actionpack/lib/action_view/base.rb4
-rw-r--r--actionpack/lib/action_view/paths.rb67
-rw-r--r--actionpack/lib/action_view/renderable.rb2
3 files changed, 52 insertions, 21 deletions
diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb
index 7697848713..da1f283deb 100644
--- a/actionpack/lib/action_view/base.rb
+++ b/actionpack/lib/action_view/base.rb
@@ -322,9 +322,7 @@ module ActionView #:nodoc:
end
# OPTIMIZE: Checks to lookup template in view path
- if template = self.view_paths["#{template_file_name}.#{template_format}"]
- template
- elsif template = self.view_paths[template_file_name]
+ if template = self.view_paths.find_template(template_file_name, template_format)
template
elsif (first_render = @_render_stack.first) && first_render.respond_to?(:format_and_extension) &&
(template = self.view_paths["#{template_file_name}.#{first_render.format_and_extension}"])
diff --git a/actionpack/lib/action_view/paths.rb b/actionpack/lib/action_view/paths.rb
index d6bf2137af..f01ed9e6e0 100644
--- a/actionpack/lib/action_view/paths.rb
+++ b/actionpack/lib/action_view/paths.rb
@@ -40,18 +40,10 @@ module ActionView #:nodoc:
end
class Path #:nodoc:
- def self.eager_load_templates!
- @eager_load_templates = true
- end
-
- def self.eager_load_templates?
- @eager_load_templates || false
- end
-
attr_reader :path, :paths
delegate :to_s, :to_str, :hash, :inspect, :to => :path
- def initialize(path, load = true)
+ def initialize(path, load = false)
raise ArgumentError, "path already is a Path class" if path.is_a?(Path)
@path = path.freeze
reload! if load
@@ -65,9 +57,35 @@ module ActionView #:nodoc:
to_str == path.to_str
end
+ # Returns a ActionView::Template object for the given path string. The
+ # input path should be relative to the view path directory,
+ # +hello/index.html.erb+. This method also has a special exception to
+ # match partial file names without a handler extension. So
+ # +hello/index.html+ will match the first template it finds with a
+ # known template extension, +hello/index.html.erb+. Template extensions
+ # should not be confused with format extensions +html+, +js+, +xml+,
+ # etc. A format must be supplied to match a formated file. +hello/index+
+ # will never match +hello/index.html.erb+.
+ #
+ # This method also has two different implementations, one that is "lazy"
+ # and makes file system calls every time and the other is cached,
+ # "eager" which looks up the template in an in memory index. The "lazy"
+ # version is designed for development where you want to automatically
+ # find new templates between requests. The "eager" version is designed
+ # for production mode and it is much faster but requires more time
+ # upfront to build the file index.
def [](path)
- raise "Unloaded view path! #{@path}" unless @loaded
- @paths[path]
+ if loaded?
+ @paths[path]
+ else
+ Dir.glob("#{@path}/#{path}*").each do |file|
+ template = create_template(file)
+ if path == template.path_without_extension || path == template.path
+ return template
+ end
+ end
+ nil
+ end
end
def loaded?
@@ -84,9 +102,7 @@ module ActionView #:nodoc:
@paths = {}
templates_in_path do |template|
- # Eager load memoized methods and freeze cached template
- template.freeze if self.class.eager_load_templates?
-
+ template.freeze
@paths[template.path] = template
@paths[template.path_without_extension] ||= template
end
@@ -98,11 +114,13 @@ module ActionView #:nodoc:
private
def templates_in_path
(Dir.glob("#{@path}/**/*/**") | Dir.glob("#{@path}/**")).each do |file|
- unless File.directory?(file)
- yield Template.new(file.split("#{self}/").last, self)
- end
+ yield create_template(file) unless File.directory?(file)
end
end
+
+ def create_template(file)
+ Template.new(file.split("#{self}/").last, self)
+ end
end
def load
@@ -121,5 +139,20 @@ module ActionView #:nodoc:
end
nil
end
+
+ def find_template(path, *formats)
+ if formats && formats.first == :all
+ formats = Mime::EXTENSION_LOOKUP.values.map(&:to_sym)
+ end
+ formats.each do |format|
+ if template = self["#{path}.#{format}"]
+ return template
+ end
+ end
+ if template = self[path]
+ return template
+ end
+ nil
+ end
end
end
diff --git a/actionpack/lib/action_view/renderable.rb b/actionpack/lib/action_view/renderable.rb
index 5ff5569db6..c04399f2c9 100644
--- a/actionpack/lib/action_view/renderable.rb
+++ b/actionpack/lib/action_view/renderable.rb
@@ -96,7 +96,7 @@ module ActionView
# The template will be compiled if the file has not been compiled yet, or
# if local_assigns has a new key, which isn't supported by the compiled code yet.
def recompile?(symbol)
- !(ActionView::PathSet::Path.eager_load_templates? && Base::CompiledTemplates.method_defined?(symbol))
+ !(frozen? && Base::CompiledTemplates.method_defined?(symbol))
end
end
end