aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib/action_controller/abstract/renderer.rb
blob: 7f7ec7805401fbcbaf2714c2e778ea525320bf58 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
require "action_controller/abstract/logger"

module AbstractController
  module Renderer
    extend ActiveSupport::DependencyModule

    depends_on AbstractController::Logger

    included do
      attr_internal :formats

      extlib_inheritable_accessor :_view_paths

      self._view_paths ||= ActionView::PathSet.new
    end

    def _action_view
      @_action_view ||= ActionView::Base.new(self.class.view_paths, {}, self)      
    end
        
    def render(*args)
      if response_body
        raise AbstractController::DoubleRenderError, "OMG"
      end
      
      self.response_body = render_to_body(*args)
    end
    
    # Raw rendering of a template to a Rack-compatible body.
    # ====
    # @option _prefix<String> The template's path prefix
    # @option _layout<String> The relative path to the layout template to use
    # 
    # :api: plugin
    def render_to_body(options = {})
      # TODO: Refactor so we can just use the normal template logic for this
      if options[:_partial_object]
        _action_view._render_partial_from_controller(options)
      else
        _determine_template(options)
        _render_template(options)
      end
    end

    # Raw rendering of a template to a string.
    # ====
    # @option _prefix<String> The template's path prefix
    # @option _layout<String> The relative path to the layout template to use
    # 
    # :api: plugin
    def render_to_string(options = {})
      AbstractController::Renderer.body_to_s(render_to_body(options))
    end

    def _render_template(options)
      _action_view._render_template_from_controller(options[:_template], options[:_layout], options, options[:_partial])
    end
    
    def view_paths() _view_paths end

    # Return a string representation of a Rack-compatible response body.
    def self.body_to_s(body)
      if body.respond_to?(:to_str)
        body
      else
        strings = []
        body.each { |part| strings << part.to_s }
        body.close if body.respond_to?(:close)
        strings.join
      end
    end

  private

    def _determine_template(options)
      name = (options[:_template_name] || action_name).to_s

      options[:_template] ||= view_paths.find_by_parts(
        name, { :formats => formats }, options[:_prefix], options[:_partial]
      )
    end

    module ClassMethods
      
      def append_view_path(path)
        self.view_paths << path
      end
      
      def prepend_view_path(path)
        self.view_paths.unshift(path)
      end

      def view_paths
        self._view_paths
      end
      
      def view_paths=(paths)
        self._view_paths = paths.is_a?(ActionView::PathSet) ?
                            paths : ActionView::Base.process_view_paths(paths)
      end
    end
  end
end