diff options
author | Prem Sichanugrist <s@sikachu.com> | 2011-12-06 21:05:56 -0500 |
---|---|---|
committer | Prem Sichanugrist <s@sikachu.com> | 2011-12-06 21:16:29 -0500 |
commit | 18ceed201b37d91ad6598d0f8b3c010e6cc48b15 (patch) | |
tree | f232fc3f9d82410bd87e2982c5fe7a7923491f6e /actionpack/lib/abstract_controller | |
parent | 0460b3a46920ccf7d70d6699a3da06ca9663c1f6 (diff) | |
download | rails-18ceed201b37d91ad6598d0f8b3c010e6cc48b15.tar.gz rails-18ceed201b37d91ad6598d0f8b3c010e6cc48b15.tar.bz2 rails-18ceed201b37d91ad6598d0f8b3c010e6cc48b15.zip |
Allow layout fallback when using `layout` method
Rails will now use your default layout (such as "layouts/application") when you specify a layout with `:only` and `:except` condition, and those conditions fail.
For example, consider this snippet:
class CarsController
layout 'single_car', :only => :show
end
Rails will use 'layouts/single_car' when a request comes in `:show` action, and use 'layouts/application' (or 'layouts/cars', if exists) when a request comes in for any other actions.
Diffstat (limited to 'actionpack/lib/abstract_controller')
-rw-r--r-- | actionpack/lib/abstract_controller/layouts.rb | 59 |
1 files changed, 34 insertions, 25 deletions
diff --git a/actionpack/lib/abstract_controller/layouts.rb b/actionpack/lib/abstract_controller/layouts.rb index bbf5efe565..79edd5418e 100644 --- a/actionpack/lib/abstract_controller/layouts.rb +++ b/actionpack/lib/abstract_controller/layouts.rb @@ -244,42 +244,51 @@ module AbstractController def _write_layout_method remove_possible_method(:_layout) - case defined?(@_layout) ? @_layout : nil - when String - self.class_eval %{def _layout; #{@_layout.inspect} end}, __FILE__, __LINE__ - when Symbol - self.class_eval <<-ruby_eval, __FILE__, __LINE__ + 1 - def _layout + prefixes = _implied_layout_name =~ /\blayouts/ ? [] : ["layouts"] + layout_definition = case defined?(@_layout) ? @_layout : nil + when String + @_layout.inspect + when Symbol + <<-RUBY #{@_layout}.tap do |layout| unless layout.is_a?(String) || !layout raise ArgumentError, "Your layout method :#{@_layout} returned \#{layout}. It " \ "should have returned a String, false, or nil" end end - end - ruby_eval - when Proc - define_method :_layout_from_proc, &@_layout - self.class_eval %{def _layout; _layout_from_proc(self) end}, __FILE__, __LINE__ - when false - self.class_eval %{def _layout; end}, __FILE__, __LINE__ - when true - raise ArgumentError, "Layouts must be specified as a String, Symbol, false, or nil" - when nil - if name - _prefixes = _implied_layout_name =~ /\blayouts/ ? [] : ["layouts"] - - self.class_eval <<-RUBY, __FILE__, __LINE__ + 1 - def _layout - if template_exists?("#{_implied_layout_name}", #{_prefixes.inspect}) + RUBY + when Proc + define_method :_layout_from_proc, &@_layout + "_layout_from_proc(self)" + when false + nil + when true + raise ArgumentError, "Layouts must be specified as a String, Symbol, false, or nil" + when nil + if name + <<-RUBY + if template_exists?("#{_implied_layout_name}", #{prefixes.inspect}) "#{_implied_layout_name}" else super end + RUBY + end + end + + self.class_eval <<-RUBY, __FILE__, __LINE__ + 1 + def _layout + if action_has_layout? + #{layout_definition} + elsif self.class.name + if template_exists?("#{_implied_layout_name}", #{prefixes.inspect}) + "#{_implied_layout_name}" + else + super end - RUBY + end end - end + RUBY self.class_eval { private :_layout } end end @@ -337,7 +346,7 @@ module AbstractController # * <tt>template</tt> - The template object for the default layout (or nil) def _default_layout(require_layout = false) begin - layout_name = _layout if action_has_layout? + layout_name = _layout rescue NameError => e raise e, "Could not render layout: #{e.message}" end |