diff options
Diffstat (limited to 'actionpack')
8 files changed, 96 insertions, 17 deletions
diff --git a/actionpack/lib/action_controller/layout.rb b/actionpack/lib/action_controller/layout.rb index 9cd7d0e8cf..c41e14736c 100644 --- a/actionpack/lib/action_controller/layout.rb +++ b/actionpack/lib/action_controller/layout.rb @@ -167,17 +167,22 @@ module ActionController #:nodoc: # If a layout is specified, all rendered actions will have their result rendered # when the layout<tt>yield</tt>'s. This layout can itself depend on instance variables assigned during action # performance and have access to them as any normal template would. - def layout(template_name, conditions = {}) + def layout(template_name, conditions = {}, auto = false) add_layout_conditions(conditions) write_inheritable_attribute "layout", template_name + write_inheritable_attribute "auto_layout", auto end def layout_conditions #:nodoc: @layout_conditions ||= read_inheritable_attribute("layout_conditions") end - def default_layout #:nodoc: - @default_layout ||= read_inheritable_attribute("layout") + def default_layout(format) #:nodoc: + layout = read_inheritable_attribute("layout") + return layout unless read_inheritable_attribute("auto_layout") + @default_layout ||= {} + @default_layout[format] ||= default_layout_with_format(format, layout) + @default_layout[format] end def layout_list #:nodoc: @@ -190,7 +195,7 @@ module ActionController #:nodoc: def inherited_with_layout(child) inherited_without_layout(child) layout_match = child.name.underscore.sub(/_controller$/, '').sub(/^controllers\//, '') - child.layout(layout_match) unless child.layout_list.grep(%r{layouts/#{layout_match}(\.[a-z][0-9a-z]*)+$}).empty? + child.layout(layout_match, {}, true) unless child.layout_list.grep(%r{layouts/#{layout_match}(\.[a-z][0-9a-z]*)+$}).empty? end def add_layout_conditions(conditions) @@ -206,6 +211,15 @@ module ActionController #:nodoc: h[dirname] = File.directory? dirname end end + + def default_layout_with_format(format, layout) + list = layout_list + if list.grep(%r{layouts/#{layout}\.#{format}(\.[a-z][0-9a-z]*)+$}).empty? + (!list.grep(%r{layouts/#{layout}\.([a-z][0-9a-z]*)+$}).empty? && format == :html) ? layout : nil + else + layout + end + end end # 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 @@ module ActionController #:nodoc: # object). If the layout was defined without a directory, layouts is assumed. So <tt>layout "weblog/standard"</tt> will return # weblog/standard, but <tt>layout "standard"</tt> will return layouts/standard. def active_layout(passed_layout = nil) - layout = passed_layout || self.class.default_layout + layout = passed_layout || self.class.default_layout(response.template.template_format) active_layout = case layout when String then layout when Symbol then send(layout) @@ -235,7 +249,6 @@ module ActionController #:nodoc: protected def render_with_a_layout(options = nil, &block) #:nodoc: template_with_options = options.is_a?(Hash) - set_template_format(options) if apply_layout?(template_with_options, options) && (layout = pick_layout(template_with_options, options)) assert_existence_of_template_file(layout) @@ -306,13 +319,5 @@ module ActionController #:nodoc: self.class.send(:layout_directory_exists_cache)[File.dirname(template_path)] end end - - def set_template_format(options) - if options.is_a?(Hash) && options[:content_type] - response.template.template_format = options[:content_type].to_sym - elsif params[:format] - response.template.template_format = Mime::Type.lookup(Mime::Type.lookup_by_extension(params[:format]).to_s).to_sym - end - end end end
\ No newline at end of file diff --git a/actionpack/test/controller/mime_responds_test.rb b/actionpack/test/controller/mime_responds_test.rb index 0dc063a451..e0c0d1613a 100644 --- a/actionpack/test/controller/mime_responds_test.rb +++ b/actionpack/test/controller/mime_responds_test.rb @@ -429,8 +429,76 @@ class MimeControllerTest < Test::Unit::TestCase assert_equal '<html><div id="html_missing">Hello future from Firefox!</div></html>', @response.body @request.env["HTTP_ACCEPT"] = "text/iphone" - get :iphone_with_html_response_type_without_layout - assert_equal 'Hello iPhone future from iPhone!', @response.body - assert_equal "text/html", @response.content_type + assert_raises(ActionController::MissingTemplate) { get :iphone_with_html_response_type_without_layout } end end + +class AbstractPostController < ActionController::Base + class << self + def view_paths + [ File.dirname(__FILE__) + "/../fixtures/post_test/" ] + end + end +end + +# For testing layouts which are set automatically +class PostController < AbstractPostController + around_filter :with_iphone + + def index + respond_to do |type| + type.html + type.iphone + end + end + + protected + + def with_iphone + Mime::Type.register_alias("text/html", :iphone) + request.format = "iphone" if request.env["HTTP_ACCEPT"] == "text/iphone" + yield + Mime.send :remove_const, :IPHONE + end + +end + +class SuperPostController < PostController + def index + respond_to do |type| + type.html + type.iphone + end + end +end + +class MimeControllerLayoutsTest < Test::Unit::TestCase + def setup + @request = ActionController::TestRequest.new + @response = ActionController::TestResponse.new + + @controller = PostController.new + @request.host = "www.example.com" + end + + def test_missing_layout_renders_properly + get :index + assert_equal '<html><div id="html">Hello Firefox</div></html>', @response.body + + @request.env["HTTP_ACCEPT"] = "text/iphone" + get :index + assert_equal 'Hello iPhone', @response.body + end + + def test_format_with_inherited_layouts + @controller = SuperPostController.new + + get :index + assert_equal 'Super Firefox', @response.body + + @request.env["HTTP_ACCEPT"] = "text/iphone" + get :index + assert_equal '<html><div id="super_iphone">Super iPhone</div></html>', @response.body + end +end +
\ No newline at end of file diff --git a/actionpack/test/fixtures/post_test/layouts/post.html.erb b/actionpack/test/fixtures/post_test/layouts/post.html.erb new file mode 100644 index 0000000000..c6c1a586dd --- /dev/null +++ b/actionpack/test/fixtures/post_test/layouts/post.html.erb @@ -0,0 +1 @@ +<html><div id="html"><%= yield %></div></html>
\ No newline at end of file diff --git a/actionpack/test/fixtures/post_test/layouts/super_post.iphone.erb b/actionpack/test/fixtures/post_test/layouts/super_post.iphone.erb new file mode 100644 index 0000000000..db0e43694d --- /dev/null +++ b/actionpack/test/fixtures/post_test/layouts/super_post.iphone.erb @@ -0,0 +1 @@ +<html><div id="super_iphone"><%= yield %></div></html>
\ No newline at end of file diff --git a/actionpack/test/fixtures/post_test/post/index.html.erb b/actionpack/test/fixtures/post_test/post/index.html.erb new file mode 100644 index 0000000000..b349b25618 --- /dev/null +++ b/actionpack/test/fixtures/post_test/post/index.html.erb @@ -0,0 +1 @@ +Hello Firefox
\ No newline at end of file diff --git a/actionpack/test/fixtures/post_test/post/index.iphone.erb b/actionpack/test/fixtures/post_test/post/index.iphone.erb new file mode 100644 index 0000000000..d741e44351 --- /dev/null +++ b/actionpack/test/fixtures/post_test/post/index.iphone.erb @@ -0,0 +1 @@ +Hello iPhone
\ No newline at end of file diff --git a/actionpack/test/fixtures/post_test/super_post/index.html.erb b/actionpack/test/fixtures/post_test/super_post/index.html.erb new file mode 100644 index 0000000000..7fc2eb190a --- /dev/null +++ b/actionpack/test/fixtures/post_test/super_post/index.html.erb @@ -0,0 +1 @@ +Super Firefox
\ No newline at end of file diff --git a/actionpack/test/fixtures/post_test/super_post/index.iphone.erb b/actionpack/test/fixtures/post_test/super_post/index.iphone.erb new file mode 100644 index 0000000000..99063a8d8c --- /dev/null +++ b/actionpack/test/fixtures/post_test/super_post/index.iphone.erb @@ -0,0 +1 @@ +Super iPhone
\ No newline at end of file |