diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index ae6b284854d99..fe51af62e6607 100644 --- a/actionpack/lib/action_view/base.rb +++ b/actionpack/lib/action_view/base.rb @@ -379,6 +379,12 @@ def assign_variables_from_controller @assigns.each { |key, value| instance_variable_set("@#{key}", value) } end + def set_controller_content_type(content_type) + if controller.respond_to?(:response) + controller.response.content_type ||= content_type + end + end + def execute(method, local_assigns = {}) send(method, local_assigns) do |*names| instance_variable_get "@content_for_#{names.first || 'layout'}" diff --git a/actionpack/lib/action_view/renderable.rb b/actionpack/lib/action_view/renderable.rb index 4f865cbced296..2b825ac4e943d 100644 --- a/actionpack/lib/action_view/renderable.rb +++ b/actionpack/lib/action_view/renderable.rb @@ -24,10 +24,13 @@ def compiled_source memoize :compiled_source def render(view, local_assigns = {}) + compile(local_assigns) + view._first_render ||= self view._last_render = self + view.send(:evaluate_assigns) - compile(local_assigns) + view.send(:set_controller_content_type, mime_type) if respond_to?(:mime_type) view.send(:execute, method(local_assigns), local_assigns) end diff --git a/actionpack/lib/action_view/template.rb b/actionpack/lib/action_view/template.rb index eba42518d7803..1f528dd9009bd 100644 --- a/actionpack/lib/action_view/template.rb +++ b/actionpack/lib/action_view/template.rb @@ -22,6 +22,11 @@ def format_and_extension end memoize :format_and_extension + def mime_type + Mime::Type.lookup_by_extension(format) if format + end + memoize :mime_type + def path [base_path, [name, format, extension].compact.join('.')].compact.join('/') end diff --git a/actionpack/lib/action_view/template_handlers/builder.rb b/actionpack/lib/action_view/template_handlers/builder.rb index 335ec1abb40e1..7d24a5c423a94 100644 --- a/actionpack/lib/action_view/template_handlers/builder.rb +++ b/actionpack/lib/action_view/template_handlers/builder.rb @@ -6,8 +6,7 @@ class Builder < TemplateHandler include Compilable def compile(template) - # ActionMailer does not have a response - "controller.respond_to?(:response) && controller.response.content_type ||= Mime::XML;" + + "set_controller_content_type(Mime::XML);" + "xml = ::Builder::XmlMarkup.new(:indent => 2);" + "self.output_buffer = xml.target!;" + template.source + diff --git a/actionpack/test/controller/render_test.rb b/actionpack/test/controller/render_test.rb index 041c54c7fde38..76832f571335c 100644 --- a/actionpack/test/controller/render_test.rb +++ b/actionpack/test/controller/render_test.rb @@ -197,11 +197,11 @@ def default_render def render_alternate_default # For this test, the method "default_render" is overridden: - @alternate_default_render = lambda { - render :update do |page| - page.replace :foo, :partial => 'partial' - end - } + @alternate_default_render = lambda do + render :update do |page| + page.replace :foo, :partial => 'partial' + end + end end def rescue_action(e) raise end @@ -467,6 +467,11 @@ def test_should_render_xml_but_keep_custom_content_type get :render_xml_with_custom_content_type assert_equal "application/atomsvc+xml", @response.content_type end + + def test_should_use_implicit_content_type + get :implicit_content_type, :format => 'atom' + assert_equal Mime::ATOM, @response.content_type + end end class EtagRenderTest < Test::Unit::TestCase diff --git a/actionpack/test/fixtures/test/implicit_content_type.atom.builder b/actionpack/test/fixtures/test/implicit_content_type.atom.builder new file mode 100644 index 0000000000000..2fcb32d2473a3 --- /dev/null +++ b/actionpack/test/fixtures/test/implicit_content_type.atom.builder @@ -0,0 +1,2 @@ +xml.atom do +end