layouts.rb 2.6 KB
Newer Older
1 2
module AbstractController
  module Layouts
Y
Yehuda Katz and Carl Lerche 已提交
3
    
4 5
    depends_on Renderer
        
Y
Yehuda Katz and Carl Lerche 已提交
6
    module ClassMethods
7 8 9 10 11
      def layout(layout)
        unless [String, Symbol, FalseClass, NilClass].include?(layout.class)
          raise ArgumentError, "Layouts must be specified as a String, Symbol, false, or nil"
        end
        
12 13
        @_layout = layout || false # Converts nil to false
        _write_layout_method
14 15
      end
      
16 17 18 19
      def _implied_layout_name
        name.underscore
      end
      
20 21 22 23 24 25 26 27 28 29
      # 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
      # false::  return nil
      # none::   If a layout is found in the view paths with the controller's
      #          name, return that string. Otherwise, use the superclass'
      #          layout (which might also be implied)
30
      def _write_layout_method
31
        case @_layout
32
        when String
33
          self.class_eval %{def _layout() #{@_layout.inspect} end}
34
        when Symbol
35
          self.class_eval %{def _layout() #{@_layout} end}
36 37 38 39 40
        when false
          self.class_eval %{def _layout() end}
        else
          self.class_eval %{
            def _layout
41
              if view_paths.find_by_parts?("#{_implied_layout_name}", {:formats => formats}, "layouts")
42
                "#{_implied_layout_name}"
43 44 45 46 47 48 49
              else
                super
              end
            end
          }
        end
      end
Y
Yehuda Katz and Carl Lerche 已提交
50 51
    end
    
Y
Yehuda Katz 已提交
52
    def _render_template(template, options)
Y
Yehuda Katz + Carl Lerche 已提交
53
      # layout = options[:_layout].is_a?(ActionView::Template) ? options[:_layout] : _layout_for_name(options[:_layout])
Y
Yehuda Katz 已提交
54
      _action_view._render_template_with_layout(template, options[:_layout])
55
    end
Y
Yehuda Katz and Carl Lerche 已提交
56 57
        
  private
58 59
  
    def _layout() end # This will be overwritten
Y
Yehuda Katz and Carl Lerche 已提交
60 61
    
    def _layout_for_name(name)
62 63 64 65
      unless [String, FalseClass, NilClass].include?(name.class)
        raise ArgumentError, "String, false, or nil expected; you passed #{name.inspect}"
      end
      
66
      name && view_paths.find_by_parts(name, {:formats => formats}, "layouts")
Y
Yehuda Katz and Carl Lerche 已提交
67 68 69
    end
    
    def _default_layout(require_layout = false)
70
      if require_layout && !_layout
Y
Yehuda Katz + Carl Lerche 已提交
71
        raise ArgumentError,
72 73
          "There was no default layout for #{self.class} in #{view_paths.inspect}"
      end
Y
Yehuda Katz + Carl Lerche 已提交
74

75
      begin
76
        layout = _layout_for_name(_layout)
77 78 79 80
      rescue NameError => e
        raise NoMethodError, 
          "You specified #{@_layout.inspect} as the layout, but no such method was found"
      end
Y
Yehuda Katz and Carl Lerche 已提交
81
    end
82 83
  end
end