public
Description: Ruby on Rails
Homepage: http://rubyonrails.org
Clone URL: git://github.com/rails/rails.git
Changed the default of ActionView#render to assume partials instead of files 
when not given an options hash [DHH]
dhh (author)
Wed Nov 19 05:00:16 -0800 2008
commit  130fe74d17404e5c06353526c7b20beb4019cb69
tree    ad15653d1f1ab20151d4bdc934106e8f857d08f7
parent  0c9f677e7861ef2aae36d91811d72794e4709f58
...
1
2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
4
5
...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
0
@@ -1,5 +1,21 @@
0
 *2.3.0/3.0*
0
 
0
+* Changed the default of ActionView#render to assume partials instead of files when not given an options hash [DHH]. Examples:
0
+
0
+    # Instead of <%= render :partial => "account" %>
0
+    <%= render "account" %>
0
+    
0
+    # Instead of <%= render :partial => "account", :locals => { :account => @buyer } %>
0
+    <%= render "account", :account => @buyer %>
0
+    
0
+    # @account is an Account instance, so it uses the RecordIdentifier to replace
0
+    # <%= render :partial => "accounts/account", :locals => { :account => @account } %>
0
+    <%= render(@account) %>
0
+    
0
+    # @posts is an array of Post instances, so it uses the RecordIdentifier to replace
0
+    # <%= render :partial => "posts/post", :collection => @posts %>
0
+    <%= render(@posts) %>
0
+
0
 * Fixed RedCloth and BlueCloth shouldn't preload. Instead just assume that they're available if you want to use textilize and markdown and let autoload require them [DHH]
0
 
0
 
...
234
235
236
237
238
 
 
 
 
 
 
 
 
 
 
239
240
241
242
243
244
245
246
 
 
247
248
249
...
256
257
258
 
 
 
 
259
260
261
...
234
235
236
 
 
237
238
239
240
241
242
243
244
245
246
247
248
249
 
 
 
 
 
250
251
252
253
254
...
261
262
263
264
265
266
267
268
269
270
0
@@ -234,16 +234,21 @@ module ActionView #:nodoc:
0
       @view_paths = self.class.process_view_paths(paths)
0
     end
0
 
0
-    # Renders the template present at <tt>template_path</tt> (relative to the view_paths array).
0
-    # The hash in <tt>local_assigns</tt> is made available as local variables.
0
+    # Returns the result of a render that's dictated by the options hash. The primary options are:
0
+    # 
0
+    # * <tt>:partial</tt> - See ActionView::Partials.
0
+    # * <tt>:update</tt> - Calls update_page with the block given.
0
+    # * <tt>:file</tt> - Renders an explicit template file (this used to be the old default), add :locals to pass in those.
0
+    # * <tt>:inline</tt> - Renders an inline template similar to how it's done in the controller.
0
+    # * <tt>:text</tt> - Renders the text passed in out.
0
+    #
0
+    # If no options hash is passed or :update specified, the default is to render a partial and use the second parameter
0
+    # as the locals hash.
0
     def render(options = {}, local_assigns = {}, &block) #:nodoc:
0
       local_assigns ||= {}
0
 
0
-      if options.is_a?(String)
0
-        render(:file => options, :locals => local_assigns)
0
-      elsif options == :update
0
-        update_page(&block)
0
-      elsif options.is_a?(Hash)
0
+      case options
0
+      when Hash
0
         options = options.reverse_merge(:locals => {})
0
         if options[:layout]
0
           _render_with_layout(options, local_assigns, &block)
0
@@ -256,6 +261,10 @@ module ActionView #:nodoc:
0
         elsif options[:text]
0
           options[:text]
0
         end
0
+      when :update
0
+        update_page(&block)
0
+      else
0
+        render_partial(:partial => options, :locals => local_assigns)
0
       end
0
     end
0
 
...
46
47
48
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
49
50
51
...
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
0
@@ -46,6 +46,38 @@ module ActionView
0
   #
0
   # This will render the partial "advertisement/_ad.erb" regardless of which controller this is being called from.
0
   #
0
+  # == Rendering objects with the RecordIdentifier
0
+  #
0
+  # Instead of explicitly naming the location of a partial, you can also let the RecordIdentifier do the work if
0
+  # you're following its conventions for RecordIdentifier#partial_path. Examples:
0
+  #
0
+  #  # @account is an Account instance, so it uses the RecordIdentifier to replace
0
+  #  # <%= render :partial => "accounts/account", :locals => { :account => @buyer } %>
0
+  #  <%= render :partial => @account %>
0
+  #
0
+  #  # @posts is an array of Post instances, so it uses the RecordIdentifier to replace
0
+  #  # <%= render :partial => "posts/post", :collection => @posts %>
0
+  #  <%= render :partial => @posts %>
0
+  #
0
+  # == Rendering the default case
0
+  #
0
+  # If you're not going to be using any of the options like collections or layouts, you can also use the short-hand
0
+  # defaults of render to render partials. Examples:
0
+  #
0
+  #  # Instead of <%= render :partial => "account" %>
0
+  #  <%= render "account" %>
0
+  #
0
+  #  # Instead of <%= render :partial => "account", :locals => { :account => @buyer } %>
0
+  #  <%= render "account", :account => @buyer %>
0
+  #
0
+  #  # @account is an Account instance, so it uses the RecordIdentifier to replace
0
+  #  # <%= render :partial => "accounts/account", :locals => { :account => @account } %>
0
+  #  <%= render(@account) %>
0
+  #
0
+  #  # @posts is an array of Post instances, so it uses the RecordIdentifier to replace
0
+  #  # <%= render :partial => "posts/post", :collection => @posts %>
0
+  #  <%= render(@posts) %>
0
+  #
0
   # == Rendering partials with layouts
0
   #
0
   # Partials can have their own layouts applied to them. These layouts are different than the ones that are
...
1
2
3
 
4
5
...
1
2
 
3
4
5
0
@@ -1,4 +1,4 @@
0
 xml.html do
0
   xml.p "Hello #{@name}"
0
-  xml << render("test/greeting")
0
+  xml << render(:file => "test/greeting")
0
 end
0
\ No newline at end of file
...
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
...
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
0
@@ -12,30 +12,30 @@ uses_mocha 'TestTemplateRecompilation' do
0
 
0
     def test_template_gets_compiled
0
       assert_equal 0, @compiled_templates.instance_methods.size
0
-      assert_equal "Hello world!", render("test/hello_world.erb")
0
+      assert_equal "Hello world!", render(:file => "test/hello_world.erb")
0
       assert_equal 1, @compiled_templates.instance_methods.size
0
     end
0
 
0
     def test_template_gets_recompiled_when_using_different_keys_in_local_assigns
0
       assert_equal 0, @compiled_templates.instance_methods.size
0
-      assert_equal "Hello world!", render("test/hello_world.erb")
0
-      assert_equal "Hello world!", render("test/hello_world.erb", {:foo => "bar"})
0
+      assert_equal "Hello world!", render(:file => "test/hello_world.erb")
0
+      assert_equal "Hello world!", render(:file => "test/hello_world.erb", :locals => {:foo => "bar"})
0
       assert_equal 2, @compiled_templates.instance_methods.size
0
     end
0
 
0
     def test_compiled_template_will_not_be_recompiled_when_rendered_with_identical_local_assigns
0
       assert_equal 0, @compiled_templates.instance_methods.size
0
-      assert_equal "Hello world!", render("test/hello_world.erb")
0
+      assert_equal "Hello world!", render(:file => "test/hello_world.erb")
0
       ActionView::Template.any_instance.expects(:compile!).never
0
-      assert_equal "Hello world!", render("test/hello_world.erb")
0
+      assert_equal "Hello world!", render(:file => "test/hello_world.erb")
0
     end
0
 
0
     def test_compiled_template_will_always_be_recompiled_when_eager_loaded_templates_is_off
0
       ActionView::PathSet::Path.expects(:eager_load_templates?).times(4).returns(false)
0
       assert_equal 0, @compiled_templates.instance_methods.size
0
-      assert_equal "Hello world!", render("#{FIXTURE_LOAD_PATH}/test/hello_world.erb")
0
+      assert_equal "Hello world!", render(:file => "#{FIXTURE_LOAD_PATH}/test/hello_world.erb")
0
       ActionView::Template.any_instance.expects(:compile!).times(3)
0
-      3.times { assert_equal "Hello world!", render("#{FIXTURE_LOAD_PATH}/test/hello_world.erb") }
0
+      3.times { assert_equal "Hello world!", render(:file => "#{FIXTURE_LOAD_PATH}/test/hello_world.erb") }
0
       assert_equal 1, @compiled_templates.instance_methods.size
0
     end
0
 
...
8
9
10
11
 
12
13
14
...
16
17
18
19
 
20
21
22
23
 
24
25
26
...
29
30
31
32
 
33
34
35
36
37
 
38
39
40
41
 
42
43
44
45
 
46
47
48
...
51
52
53
 
 
 
 
54
55
56
...
73
74
75
 
 
 
 
76
77
78
...
8
9
10
 
11
12
13
14
...
16
17
18
 
19
20
21
22
 
23
24
25
26
...
29
30
31
 
32
33
34
35
36
 
37
38
39
40
 
41
42
43
44
 
45
46
47
48
...
51
52
53
54
55
56
57
58
59
60
...
77
78
79
80
81
82
83
84
85
86
0
@@ -8,7 +8,7 @@ class ViewRenderTest < Test::Unit::TestCase
0
   end
0
 
0
   def test_render_file
0
-    assert_equal "Hello world!", @view.render("test/hello_world.erb")
0
+    assert_equal "Hello world!", @view.render(:file => "test/hello_world.erb")
0
   end
0
 
0
   def test_render_file_not_using_full_path
0
@@ -16,11 +16,11 @@ class ViewRenderTest < Test::Unit::TestCase
0
   end
0
 
0
   def test_render_file_without_specific_extension
0
-    assert_equal "Hello world!", @view.render("test/hello_world")
0
+    assert_equal "Hello world!", @view.render(:file => "test/hello_world")
0
   end
0
 
0
   def test_render_file_at_top_level
0
-    assert_equal 'Elastica', @view.render('/shared')
0
+    assert_equal 'Elastica', @view.render(:file => '/shared')
0
   end
0
 
0
   def test_render_file_with_full_path
0
@@ -29,20 +29,20 @@ class ViewRenderTest < Test::Unit::TestCase
0
   end
0
 
0
   def test_render_file_with_instance_variables
0
-    assert_equal "The secret is in the sauce\n", @view.render("test/render_file_with_ivar.erb")
0
+    assert_equal "The secret is in the sauce\n", @view.render(:file => "test/render_file_with_ivar.erb")
0
   end
0
 
0
   def test_render_file_with_locals
0
     locals = { :secret => 'in the sauce' }
0
-    assert_equal "The secret is in the sauce\n", @view.render("test/render_file_with_locals.erb", locals)
0
+    assert_equal "The secret is in the sauce\n", @view.render(:file => "test/render_file_with_locals.erb", :locals => locals)
0
   end
0
 
0
   def test_render_file_not_using_full_path_with_dot_in_path
0
-    assert_equal "The secret is in the sauce\n", @view.render("test/dot.directory/render_file_with_ivar")
0
+    assert_equal "The secret is in the sauce\n", @view.render(:file => "test/dot.directory/render_file_with_ivar")
0
   end
0
 
0
   def test_render_has_access_current_template
0
-    assert_equal "test/template.erb", @view.render("test/template.erb")
0
+    assert_equal "test/template.erb", @view.render(:file => "test/template.erb")
0
   end
0
 
0
   def test_render_update
0
@@ -51,6 +51,10 @@ class ViewRenderTest < Test::Unit::TestCase
0
     assert_equal 'alert("Hello, World!");', @view.render(:update) { |page| page.alert('Hello, World!') }
0
   end
0
 
0
+  def test_render_partial_from_default
0
+    assert_equal "only partial", @view.render("test/partial_only")
0
+  end
0
+
0
   def test_render_partial
0
     assert_equal "only partial", @view.render(:partial => "test/partial_only")
0
   end
0
@@ -73,6 +77,10 @@ class ViewRenderTest < Test::Unit::TestCase
0
     assert_equal "5", @view.render(:partial => "test/counter", :locals => { :counter_counter => 5 })
0
   end
0
 
0
+  def test_render_partial_with_locals_from_default
0
+    assert_equal "only partial", @view.render("test/partial_only", :counter_counter => 5)
0
+  end
0
+
0
   def test_render_partial_with_errors
0
     @view.render(:partial => "test/raise")
0
     flunk "Render did not raise TemplateError"

Comments

mdarby Wed Nov 19 11:39:40 -0800 2008

Nice commit!

alloy Wed Nov 19 12:22:17 -0800 2008

Very nice indeed.

darraghcurran Wed Nov 19 13:22:40 -0800 2008

nice change

looks like a small typo in docs

line 55 of partials.rb – @buyer should be @account

visnup Wed Nov 19 17:46:43 -0800 2008

hah, that breaks a line i wrote just last night to do template (non-partial) based rendering. hopefully i’ll remember to change it later. ;)

somebox Mon Nov 24 05:39:34 -0800 2008

Awesome! I always hated being forces to use :locals => {}, even though everything else was clean and named correctly. Now it just feels right.