aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib
diff options
context:
space:
mode:
Diffstat (limited to 'actionpack/lib')
-rw-r--r--actionpack/lib/action_controller/base.rb5
-rw-r--r--actionpack/lib/action_controller/dispatcher.rb1
-rw-r--r--actionpack/lib/action_controller/integration.rb1
-rw-r--r--actionpack/lib/action_controller/layout.rb38
-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
7 files changed, 66 insertions, 52 deletions
diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb
index 7e38f95076..dca66ff0a5 100644
--- a/actionpack/lib/action_controller/base.rb
+++ b/actionpack/lib/action_controller/base.rb
@@ -867,8 +867,9 @@ module ActionController #:nodoc:
end
end
- response.layout = layout = pick_layout(options)
- logger.info("Rendering template within #{layout}") if logger && layout
+ layout = pick_layout(options)
+ response.layout = layout.path_without_format_and_extension if layout
+ logger.info("Rendering template within #{layout.path_without_format_and_extension}") if logger && layout
if content_type = options[:content_type]
response.content_type = content_type.to_s
diff --git a/actionpack/lib/action_controller/dispatcher.rb b/actionpack/lib/action_controller/dispatcher.rb
index 1c7a4b0545..6e4aba2280 100644
--- a/actionpack/lib/action_controller/dispatcher.rb
+++ b/actionpack/lib/action_controller/dispatcher.rb
@@ -137,7 +137,6 @@ module ActionController
run_callbacks :prepare_dispatch
Routing::Routes.reload
- ActionController::Base.view_paths.reload!
ActionView::Helpers::AssetTagHelper::AssetTag::Cache.clear
end
diff --git a/actionpack/lib/action_controller/integration.rb b/actionpack/lib/action_controller/integration.rb
index 333fb742e4..65e3eed678 100644
--- a/actionpack/lib/action_controller/integration.rb
+++ b/actionpack/lib/action_controller/integration.rb
@@ -1,5 +1,6 @@
require 'stringio'
require 'uri'
+require 'active_support/test_case'
module ActionController
module Integration #:nodoc:
diff --git a/actionpack/lib/action_controller/layout.rb b/actionpack/lib/action_controller/layout.rb
index 3631ce86af..54108df06d 100644
--- a/actionpack/lib/action_controller/layout.rb
+++ b/actionpack/lib/action_controller/layout.rb
@@ -175,13 +175,12 @@ module ActionController #:nodoc:
def default_layout(format) #:nodoc:
layout = read_inheritable_attribute(:layout)
return layout unless read_inheritable_attribute(:auto_layout)
- @default_layout ||= {}
- @default_layout[format] ||= default_layout_with_format(format, layout)
- @default_layout[format]
+ find_layout(layout, format)
end
- def layout_list #:nodoc:
- Array(view_paths).sum([]) { |path| Dir["#{path}/layouts/**/*"] }
+ def find_layout(layout, *formats) #:nodoc:
+ return layout if layout.respond_to?(:render)
+ view_paths.find_template(layout.to_s =~ /layouts\// ? layout : "layouts/#{layout}", *formats)
end
private
@@ -189,7 +188,7 @@ module ActionController #:nodoc:
inherited_without_layout(child)
unless child.name.blank?
layout_match = child.name.underscore.sub(/_controller$/, '').sub(/^controllers\//, '')
- child.layout(layout_match, {}, true) unless child.layout_list.grep(%r{layouts/#{layout_match}(\.[a-z][0-9a-z]*)+$}).empty?
+ child.layout(layout_match, {}, true) if child.find_layout(layout_match, :all)
end
end
@@ -200,15 +199,6 @@ module ActionController #:nodoc:
def normalize_conditions(conditions)
conditions.inject({}) {|hash, (key, value)| hash.merge(key => [value].flatten.map {|action| action.to_s})}
end
-
- def default_layout_with_format(format, layout)
- list = layout_list
- if list.grep(%r{layouts/#{layout}\.#{format}(\.[a-z][0-9a-z]*)+$}).empty?
- (!list.grep(%r{layouts/#{layout}\.([a-z][0-9a-z]*)+$}).empty? && format == :html) ? layout : nil
- else
- layout
- end
- end
end
# Returns the name of the active layout. If the layout was specified as a method reference (through a symbol), this method
@@ -217,20 +207,18 @@ module ActionController #:nodoc:
# weblog/standard, but <tt>layout "standard"</tt> will return layouts/standard.
def active_layout(passed_layout = nil)
layout = passed_layout || self.class.default_layout(default_template_format)
+
active_layout = case layout
- when String then layout
when Symbol then __send__(layout)
when Proc then layout.call(self)
+ else layout
end
- # Explicitly passed layout names with slashes are looked up relative to the template root,
- # but auto-discovered layouts derived from a nested controller will contain a slash, though be relative
- # to the 'layouts' directory so we have to check the file system to infer which case the layout name came from.
if active_layout
- if active_layout.include?('/') && ! layout_directory?(active_layout)
- active_layout
+ if layout = self.class.find_layout(active_layout, @template.template_format)
+ layout
else
- "layouts/#{active_layout}"
+ raise ActionView::MissingTemplate.new(self.class.view_paths, active_layout)
end
end
end
@@ -271,12 +259,6 @@ module ActionController #:nodoc:
end
end
- def layout_directory?(layout_name)
- @template.__send__(:_pick_template, "#{File.join('layouts', layout_name)}.#{@template.template_format}") ? true : false
- rescue ActionView::MissingTemplate
- false
- end
-
def default_template_format
response.template.template_format
end
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