Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

root/trunk/actionpack/lib/action_view/partial_template.rb

Revision 9177, 1.9 kB (checked in by bitsweat, 6 months ago)

Support render :partial => collection of heterogeneous elements. Closes #11491.

Line 
1 module ActionView #:nodoc:
2   class PartialTemplate < Template #:nodoc:
3    
4     attr_reader :variable_name, :object
5    
6     def initialize(view, partial_path, object = nil, locals = {})
7       @path, @variable_name = extract_partial_name_and_path(view, partial_path)
8       super(view, @path, true, locals)
9       add_object_to_local_assigns!(object)
10
11       # This is needed here in order to compile template with knowledge of 'counter'
12       initialize_counter
13      
14       # Prepare early. This is a performance optimization for partial collections
15       prepare!
16     end
17    
18     def render
19       ActionController::Base.benchmark("Rendered #{@path}", Logger::DEBUG, false) do
20         @handler.render(self)
21       end
22     end
23    
24     def render_member(object)
25       @locals[@counter_name] += 1
26       @locals[:object] = @locals[@variable_name] = object
27       returning render do
28         @locals.delete(@variable_name)
29         @locals.delete(:object)
30       end
31     end
32    
33     def counter=(num)
34       @locals[@counter_name] = num
35     end
36
37     private
38
39     def add_object_to_local_assigns!(object)
40       @locals[:object] ||=
41         @locals[@variable_name] ||=
42           if object.is_a?(ActionView::Base::ObjectWrapper)
43             object.value
44           else
45             object
46           end || @view.controller.instance_variable_get("@#{variable_name}")
47     end
48    
49     def extract_partial_name_and_path(view, partial_path)
50       path, partial_name = partial_pieces(view, partial_path)
51       [File.join(path, "_#{partial_name}"), partial_name.split('/').last.split('.').first.to_sym]
52     end
53    
54     def partial_pieces(view, partial_path)
55       if partial_path.include?('/')
56         return File.dirname(partial_path), File.basename(partial_path)
57       else
58         return view.controller.class.controller_path, partial_path
59       end
60     end
61    
62     def initialize_counter
63       @counter_name ||= "#{@variable_name}_counter".to_sym
64       @locals[@counter_name] = 0
65     end
66    
67   end
68 end
Note: See TracBrowser for help on using the browser.