aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib/abstract_controller/layouts.rb
diff options
context:
space:
mode:
Diffstat (limited to 'actionpack/lib/abstract_controller/layouts.rb')
-rw-r--r--actionpack/lib/abstract_controller/layouts.rb69
1 files changed, 49 insertions, 20 deletions
diff --git a/actionpack/lib/abstract_controller/layouts.rb b/actionpack/lib/abstract_controller/layouts.rb
index 0063d54149..ac2154dffc 100644
--- a/actionpack/lib/abstract_controller/layouts.rb
+++ b/actionpack/lib/abstract_controller/layouts.rb
@@ -6,13 +6,51 @@ module AbstractController
included do
extlib_inheritable_accessor(:_layout_conditions) { Hash.new }
+ extlib_inheritable_accessor(:_action_has_layout) { Hash.new }
_write_layout_method
end
module ClassMethods
def inherited(klass)
super
- klass._write_layout_method
+ klass.class_eval do
+ _write_layout_method
+ @found_layouts = {}
+ end
+ 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
+
+ # This module is mixed in if layout conditions are provided. This means
+ # that if no layout conditions are used, this method is not used
+ module LayoutConditions
+ # Determines whether the current action has a layout by checking the
+ # action name against the :only and :except conditions set on the
+ # layout.
+ #
+ # ==== Returns
+ # Boolean:: True if the action has a layout, false otherwise.
+ def _action_has_layout?
+ conditions = _layout_conditions
+
+ if only = conditions[:only]
+ only.include?(action_name)
+ elsif except = conditions[:except]
+ !except.include?(action_name)
+ else
+ true
+ end
+ end
end
# Specify the layout to use for this class.
@@ -31,6 +69,8 @@ module AbstractController
# :only<#to_s, Array[#to_s]>:: A list of actions to apply this layout to.
# :except<#to_s, Array[#to_s]>:: Apply this layout to all actions but this one
def layout(layout, conditions = {})
+ include LayoutConditions unless conditions.empty?
+
conditions.each {|k, v| conditions[k] = Array(v).map {|a| a.to_s} }
self._layout_conditions = conditions
@@ -76,10 +116,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
@@ -136,7 +178,7 @@ module AbstractController
view_paths.find(name, details, prefix)
end
- # Returns the default layout for this controller and a given set of details.
+ # Returns the default layout for this controller and a given set of details.
# Optionally raises an exception if the layout could not be found.
#
# ==== Parameters
@@ -162,21 +204,8 @@ module AbstractController
end
end
- # Determines whether the current action has a layout by checking the
- # action name against the :only and :except conditions set on the
- # layout.
- #
- # ==== Returns
- # Boolean:: True if the action has a layout, false otherwise.
def _action_has_layout?
- conditions = _layout_conditions
- if only = conditions[:only]
- only.include?(action_name)
- elsif except = conditions[:except]
- !except.include?(action_name)
- else
- true
- end
+ true
end
end
end