Skip to content
This repository
Browse code

Fixed the layout defaults (closes #9564) [lifo]

git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@7661 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
  • Loading branch information...
commit 3c695356ae261c0f49a52094804498b51435dfe3 1 parent 5f4d121
David Heinemeier Hansson authored September 28, 2007
33  actionpack/lib/action_controller/layout.rb
@@ -167,17 +167,22 @@ module ClassMethods
167 167
       # If a layout is specified, all rendered actions will have their result rendered  
168 168
       # when the layout<tt>yield</tt>'s. This layout can itself depend on instance variables assigned during action
169 169
       # performance and have access to them as any normal template would.
170  
-      def layout(template_name, conditions = {})
  170
+      def layout(template_name, conditions = {}, auto = false)
171 171
         add_layout_conditions(conditions)
172 172
         write_inheritable_attribute "layout", template_name
  173
+        write_inheritable_attribute "auto_layout", auto
173 174
       end
174 175
 
175 176
       def layout_conditions #:nodoc:
176 177
         @layout_conditions ||= read_inheritable_attribute("layout_conditions")
177 178
       end
178 179
       
179  
-      def default_layout #:nodoc:
180  
-        @default_layout ||= read_inheritable_attribute("layout")
  180
+      def default_layout(format) #:nodoc:
  181
+        layout = read_inheritable_attribute("layout")                 
  182
+        return layout unless read_inheritable_attribute("auto_layout")
  183
+        @default_layout ||= {}
  184
+        @default_layout[format] ||= default_layout_with_format(format, layout)
  185
+        @default_layout[format]
181 186
       end
182 187
       
183 188
       def layout_list #:nodoc:
@@ -190,7 +195,7 @@ def layout_list #:nodoc:
190 195
         def inherited_with_layout(child)
191 196
           inherited_without_layout(child)
192 197
           layout_match = child.name.underscore.sub(/_controller$/, '').sub(/^controllers\//, '')
193  
-          child.layout(layout_match) unless child.layout_list.grep(%r{layouts/#{layout_match}(\.[a-z][0-9a-z]*)+$}).empty?
  198
+          child.layout(layout_match, {}, true) unless child.layout_list.grep(%r{layouts/#{layout_match}(\.[a-z][0-9a-z]*)+$}).empty?
194 199
         end
195 200
 
196 201
         def add_layout_conditions(conditions)
@@ -206,6 +211,15 @@ def layout_directory_exists_cache
206 211
             h[dirname] = File.directory? dirname
207 212
           end
208 213
         end
  214
+        
  215
+        def default_layout_with_format(format, layout)
  216
+          list = layout_list
  217
+          if list.grep(%r{layouts/#{layout}\.#{format}(\.[a-z][0-9a-z]*)+$}).empty?
  218
+            (!list.grep(%r{layouts/#{layout}\.([a-z][0-9a-z]*)+$}).empty? && format == :html) ? layout : nil
  219
+          else
  220
+            layout
  221
+          end
  222
+        end
209 223
     end
210 224
 
211 225
     # Returns the name of the active layout. If the layout was specified as a method reference (through a symbol), this method
@@ -213,7 +227,7 @@ def layout_directory_exists_cache
213 227
     # object). If the layout was defined without a directory, layouts is assumed. So <tt>layout "weblog/standard"</tt> will return
214 228
     # weblog/standard, but <tt>layout "standard"</tt> will return layouts/standard.
215 229
     def active_layout(passed_layout = nil)
216  
-      layout = passed_layout || self.class.default_layout
  230
+      layout = passed_layout || self.class.default_layout(response.template.template_format)
217 231
       active_layout = case layout
218 232
         when String then layout
219 233
         when Symbol then send(layout)
@@ -235,7 +249,6 @@ def active_layout(passed_layout = nil)
235 249
     protected
236 250
       def render_with_a_layout(options = nil, &block) #:nodoc:
237 251
         template_with_options = options.is_a?(Hash)
238  
-        set_template_format(options)
239 252
         
240 253
         if apply_layout?(template_with_options, options) && (layout = pick_layout(template_with_options, options))
241 254
           assert_existence_of_template_file(layout)
@@ -306,13 +319,5 @@ def layout_directory?(layout_name)
306 319
           self.class.send(:layout_directory_exists_cache)[File.dirname(template_path)]
307 320
         end
308 321
       end
309  
-      
310  
-      def set_template_format(options)
311  
-        if options.is_a?(Hash) && options[:content_type]
312  
-          response.template.template_format = options[:content_type].to_sym 
313  
-        elsif params[:format]
314  
-          response.template.template_format = Mime::Type.lookup(Mime::Type.lookup_by_extension(params[:format]).to_s).to_sym
315  
-        end
316  
-      end
317 322
   end
318 323
 end
74  actionpack/test/controller/mime_responds_test.rb
@@ -429,8 +429,76 @@ def test_format_with_custom_response_type_and_request_headers_with_only_one_layo
429 429
     assert_equal '<html><div id="html_missing">Hello future from Firefox!</div></html>', @response.body 
430 430
 
431 431
     @request.env["HTTP_ACCEPT"] = "text/iphone"
432  
-    get :iphone_with_html_response_type_without_layout
433  
-    assert_equal 'Hello iPhone future from iPhone!', @response.body
434  
-    assert_equal "text/html", @response.content_type
  432
+    assert_raises(ActionController::MissingTemplate) { get :iphone_with_html_response_type_without_layout }
435 433
   end 
436 434
 end
  435
+
  436
+class AbstractPostController < ActionController::Base
  437
+  class << self
  438
+    def view_paths
  439
+      [ File.dirname(__FILE__) + "/../fixtures/post_test/" ]
  440
+    end
  441
+  end
  442
+end
  443
+
  444
+# For testing layouts which are set automatically
  445
+class PostController < AbstractPostController
  446
+  around_filter :with_iphone
  447
+  
  448
+  def index
  449
+    respond_to do |type|
  450
+      type.html
  451
+      type.iphone
  452
+    end
  453
+  end
  454
+  
  455
+  protected
  456
+  
  457
+  def with_iphone
  458
+    Mime::Type.register_alias("text/html", :iphone)
  459
+    request.format = "iphone" if request.env["HTTP_ACCEPT"] == "text/iphone"
  460
+    yield
  461
+    Mime.send :remove_const, :IPHONE    
  462
+  end
  463
+  
  464
+end                                               
  465
+
  466
+class SuperPostController < PostController  
  467
+  def index
  468
+    respond_to do |type|
  469
+      type.html
  470
+      type.iphone
  471
+    end
  472
+  end
  473
+end
  474
+
  475
+class MimeControllerLayoutsTest < Test::Unit::TestCase
  476
+  def setup
  477
+    @request    = ActionController::TestRequest.new
  478
+    @response   = ActionController::TestResponse.new
  479
+
  480
+    @controller   = PostController.new
  481
+    @request.host = "www.example.com"
  482
+  end
  483
+  
  484
+  def test_missing_layout_renders_properly
  485
+    get :index
  486
+    assert_equal '<html><div id="html">Hello Firefox</div></html>', @response.body 
  487
+
  488
+    @request.env["HTTP_ACCEPT"] = "text/iphone"
  489
+    get :index
  490
+    assert_equal 'Hello iPhone', @response.body
  491
+  end
  492
+  
  493
+  def test_format_with_inherited_layouts
  494
+    @controller = SuperPostController.new
  495
+    
  496
+    get :index
  497
+    assert_equal 'Super Firefox', @response.body
  498
+    
  499
+    @request.env["HTTP_ACCEPT"] = "text/iphone"
  500
+    get :index
  501
+    assert_equal '<html><div id="super_iphone">Super iPhone</div></html>', @response.body
  502
+  end
  503
+end
  504
+  
1  actionpack/test/fixtures/post_test/layouts/post.html.erb
... ...
@@ -0,0 +1 @@
  1
+<html><div id="html"><%= yield %></div></html>
1  actionpack/test/fixtures/post_test/layouts/super_post.iphone.erb
... ...
@@ -0,0 +1 @@
  1
+<html><div id="super_iphone"><%= yield %></div></html>
1  actionpack/test/fixtures/post_test/post/index.html.erb
... ...
@@ -0,0 +1 @@
  1
+Hello Firefox
1  actionpack/test/fixtures/post_test/post/index.iphone.erb
... ...
@@ -0,0 +1 @@
  1
+Hello iPhone
1  actionpack/test/fixtures/post_test/super_post/index.html.erb
... ...
@@ -0,0 +1 @@
  1
+Super Firefox
1  actionpack/test/fixtures/post_test/super_post/index.iphone.erb
... ...
@@ -0,0 +1 @@
  1
+Super iPhone

0 notes on commit 3c69535

Please sign in to comment.
Something went wrong with that request. Please try again.