aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib/action_controller/abstract/layouts.rb
diff options
context:
space:
mode:
Diffstat (limited to 'actionpack/lib/action_controller/abstract/layouts.rb')
-rw-r--r--actionpack/lib/action_controller/abstract/layouts.rb87
1 files changed, 56 insertions, 31 deletions
diff --git a/actionpack/lib/action_controller/abstract/layouts.rb b/actionpack/lib/action_controller/abstract/layouts.rb
index 478b301a26..b3f21f7b22 100644
--- a/actionpack/lib/action_controller/abstract/layouts.rb
+++ b/actionpack/lib/action_controller/abstract/layouts.rb
@@ -1,25 +1,34 @@
module AbstractController
module Layouts
-
+ extend ActiveSupport::Concern
+
depends_on Renderer
-
+
+ included do
+ extlib_inheritable_accessor :_layout_conditions
+ self._layout_conditions = {}
+ end
+
module ClassMethods
- def layout(layout)
+ def layout(layout, conditions = {})
unless [String, Symbol, FalseClass, NilClass].include?(layout.class)
raise ArgumentError, "Layouts must be specified as a String, Symbol, false, or nil"
end
-
+
+ conditions.each {|k, v| conditions[k] = Array(v).map {|a| a.to_s} }
+ self._layout_conditions = conditions
+
@_layout = layout || false # Converts nil to false
_write_layout_method
end
-
+
def _implied_layout_name
name.underscore
end
-
+
# Takes the specified layout and creates a _layout method to be called
# by _default_layout
- #
+ #
# If the specified layout is a:
# String:: return the string
# Symbol:: call the method specified by the symbol
@@ -30,15 +39,15 @@ module AbstractController
def _write_layout_method
case @_layout
when String
- self.class_eval %{def _layout() #{@_layout.inspect} end}
+ self.class_eval %{def _layout(details) #{@_layout.inspect} end}
when Symbol
- self.class_eval %{def _layout() #{@_layout} end}
+ self.class_eval %{def _layout(details) #{@_layout} end}
when false
- self.class_eval %{def _layout() end}
+ self.class_eval %{def _layout(details) end}
else
self.class_eval %{
- def _layout
- if view_paths.find_by_parts?("#{_implied_layout_name}", formats, "layouts")
+ def _layout(details)
+ if view_paths.find_by_parts?("#{_implied_layout_name}", details, "layouts")
"#{_implied_layout_name}"
else
super
@@ -48,35 +57,51 @@ module AbstractController
end
end
end
-
- def _render_template(template, options)
- _action_view._render_template_with_layout(template, options[:_layout])
- end
-
+
private
-
- def _layout() end # This will be overwritten
-
- def _layout_for_name(name)
+ # This will be overwritten
+ def _layout(details)
+ end
+
+ # :api: plugin
+ # ====
+ # Override this to mutate the inbound layout name
+ def _layout_for_name(name, details = {:formats => formats})
unless [String, FalseClass, NilClass].include?(name.class)
raise ArgumentError, "String, false, or nil expected; you passed #{name.inspect}"
end
-
- name && view_paths.find_by_parts(name, formats, "layouts")
+
+ name && view_paths.find_by_parts(name, details, _layout_prefix(name))
end
-
- def _default_layout(require_layout = false)
- if require_layout && !_layout
- raise ArgumentError,
+
+ # TODO: Decide if this is the best hook point for the feature
+ def _layout_prefix(name)
+ "layouts"
+ end
+
+ def _default_layout(require_layout = false, details = {:formats => formats})
+ if require_layout && _action_has_layout? && !_layout(details)
+ raise ArgumentError,
"There was no default layout for #{self.class} in #{view_paths.inspect}"
end
-
+
begin
- layout = _layout_for_name(_layout)
+ _layout_for_name(_layout(details), details) if _action_has_layout?
rescue NameError => e
- raise NoMethodError,
+ raise NoMethodError,
"You specified #{@_layout.inspect} as the layout, but no such method was found"
end
end
+
+ 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
-end \ No newline at end of file
+end