diff --git a/actionpack/lib/abstract_controller/layouts.rb b/actionpack/lib/abstract_controller/layouts.rb index 0063d54149..d7317b415c 100644 --- a/actionpack/lib/abstract_controller/layouts.rb +++ b/actionpack/lib/abstract_controller/layouts.rb @@ -15,6 +15,18 @@ module AbstractController klass._write_layout_method end + def cache_layout(details) + layout = @found_layouts ||= {} + values = details.values_at(:formats, :locale) + + # Cache nil + if layout.key?(values) + return layout[values] + else + layout[values] = yield + end + end + # Specify the layout to use for this class. # # If the specified layout is a: @@ -76,10 +88,12 @@ module AbstractController when nil self.class_eval <<-ruby_eval, __FILE__, __LINE__ + 1 def _layout(details) - if view_paths.exists?("#{_implied_layout_name}", details, "layouts") - "#{_implied_layout_name}" - else - super + self.class.cache_layout(details) do + if view_paths.exists?("#{_implied_layout_name}", details, "layouts") + "#{_implied_layout_name}" + else + super + end end end ruby_eval diff --git a/actionpack/lib/action_view/template/resolver.rb b/actionpack/lib/action_view/template/resolver.rb index 3bd2acae7a..10f664736f 100644 --- a/actionpack/lib/action_view/template/resolver.rb +++ b/actionpack/lib/action_view/template/resolver.rb @@ -62,6 +62,10 @@ module ActionView class FileSystemResolver < Resolver + def self.cached_glob + @@cached_glob ||= {} + end + def initialize(path, options = {}) raise ArgumentError, "path already is a Resolver class" if path.is_a?(Resolver) super(options) @@ -107,20 +111,22 @@ module ActionView # :api: plugin def details_to_glob(name, details, prefix, partial, root) - path = "" - path << "#{prefix}/" unless prefix.empty? - path << (partial ? "_#{name}" : name) + self.class.cached_glob[[name, prefix, partial, details, root]] ||= begin + 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 : '' + extensions = "" + [:locales, :formats].each do |k| + extensions << if exts = details[k] + '{' + exts.map {|e| ".#{e},"}.join + '}' + else + k == :formats ? formats_glob : '' + end end - end - "#{root}#{path}#{extensions}#{handler_glob}" + "#{root}#{path}#{extensions}#{handler_glob}" + end end # TODO: fix me diff --git a/actionpack/test/dispatch/request_test.rb b/actionpack/test/dispatch/request_test.rb index f3500fca34..b626063df4 100644 --- a/actionpack/test/dispatch/request_test.rb +++ b/actionpack/test/dispatch/request_test.rb @@ -427,7 +427,7 @@ class RequestTest < ActiveSupport::TestCase request = stub_request 'CONTENT_TYPE' => 'application/xml; charset=UTF-8' request.expects(:parameters).at_least_once.returns({}) - assert_equal with_set(Mime::XML, Mime::HTML), request.formats + assert_equal with_set(Mime::XML, Mime::HTML, Mime::ALL), request.formats end with_accept_header false do @@ -460,7 +460,7 @@ protected end def with_set(*args) - args + Mime::SET + args end def with_accept_header(value)