diff options
Diffstat (limited to 'actionpack/lib/action_controller/abstract/layouts.rb')
-rw-r--r-- | actionpack/lib/action_controller/abstract/layouts.rb | 87 |
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 |