diff --git a/actionpack/CHANGELOG b/actionpack/CHANGELOG index ff2315fc3c7b1d64970b9746174a3367ac7261c2..5924b240da81fe417a1bad743d5a0c0b0989e893 100644 --- a/actionpack/CHANGELOG +++ b/actionpack/CHANGELOG @@ -1,5 +1,9 @@ *SVN* +* Added :content_type option to render, so you can change the content type on the fly [DHH]. Example: render :action => "atom.rxml", :content_type => "application/atom+xml" + +* CHANGED DEFAULT: The default content type for .rxml is now application/xml instead of type/xml, see http://www.xml.com/pub/a/2004/07/21/dive.html for reason [DHH] + * Added option to render action/template/file of a specific extension (and here by template type). This means you can have multiple templates with the same name but a different extension [DHH]. Example: class WeblogController < ActionController::Base diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb index 4663828c966bc555db4f37c1f22855dcce7a7c3a..b0b6069420d01287858b3fd77cb491cee9df2aa1 100755 --- a/actionpack/lib/action_controller/base.rb +++ b/actionpack/lib/action_controller/base.rb @@ -634,6 +634,10 @@ def render(options = nil, deprecated_status = nil, &block) #:doc: end end + if content_type = options[:content_type] + headers["Content-Type"] = content_type + end + if text = options[:text] render_text(text, options[:status]) diff --git a/actionpack/lib/action_controller/layout.rb b/actionpack/lib/action_controller/layout.rb index 0934b8bfdc6363dbbb52ef88d10839e620cc4e11..66438d277eb1193d60421225030451a29cf76789 100644 --- a/actionpack/lib/action_controller/layout.rb +++ b/actionpack/lib/action_controller/layout.rb @@ -245,7 +245,7 @@ def apply_layout?(template_with_options, options) def candidate_for_layout?(options) (options.has_key?(:layout) && options[:layout] != false) || - options.values_at(:text, :file, :inline, :partial, :nothing).compact.empty? && + options.values_at(:text, :xml, :file, :inline, :partial, :nothing).compact.empty? && !template_exempt_from_layout?(default_template_name(options[:action] || options[:template])) end diff --git a/actionpack/lib/action_controller/mime_type.rb b/actionpack/lib/action_controller/mime_type.rb index 54030f75cc1056174034752bf8e3aac3285cb70b..ba46f98aced1fe345b8746403950c604ae9dc32e 100644 --- a/actionpack/lib/action_controller/mime_type.rb +++ b/actionpack/lib/action_controller/mime_type.rb @@ -1,13 +1,31 @@ module Mime class Type - def self.lookup(string) - LOOKUP[string] - end + class << self + def lookup(string) + LOOKUP[string] + end - def self.parse(accept_header) - accept_header.split(",").collect! do |mime_type| - Mime::Type.lookup(mime_type.split(";").first.strip) + def parse(accept_header) + mime_types = accept_header.split(",").collect! do |mime_type| + mime_type.split(";").first.strip + end + + reorder_xml_types!(mime_types) + mime_types.collect! { |mime_type| Mime::Type.lookup(mime_type) } end + + private + def reorder_xml_types!(mime_types) + mime_types.delete("text/xml") if mime_types.include?("application/xml") + + if index_for_generic_xml = mime_types.index("application/xml") + specific_xml_types = mime_types[index_for_generic_xml..-1].grep(/application\/[a-z]*\+xml/) + + for specific_xml_type in specific_xml_types.reverse + mime_types.insert(index_for_generic_xml, mime_types.delete(specific_xml_type)) + end + end + end end def initialize(string, symbol = nil, synonyms = []) @@ -19,6 +37,10 @@ def to_s @string end + def to_str + to_s + end + def to_sym @symbol || to_sym end @@ -39,7 +61,7 @@ def ==(mime_type) ALL = Type.new "*/*", :all HTML = Type.new "text/html", :html, %w( application/xhtml+xml ) JS = Type.new "text/javascript", :js, %w( application/javascript application/x-javascript ) - XML = Type.new "application/xml", :xml, %w( application/x-xml ) + XML = Type.new "application/xml", :xml, %w( text/xml application/x-xml ) RSS = Type.new "application/rss+xml", :rss ATOM = Type.new "application/atom+xml", :atom YAML = Type.new "application/x-yaml", :yaml diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index d2f4764575b6b4cce0b50e721d24966e99e0c5bf..95afff0e8457d858eaace6e4a2c1acd5ec2ca2c6 100644 --- a/actionpack/lib/action_view/base.rb +++ b/actionpack/lib/action_view/base.rb @@ -406,7 +406,7 @@ def create_template_source(extension, template, render_symbol, locals) body = case extension.to_sym when :rxml "xml = Builder::XmlMarkup.new(:indent => 2)\n" + - "@controller.headers['Content-Type'] ||= 'text/xml'\n" + + "@controller.headers['Content-Type'] ||= 'application/xml'\n" + template when :rjs "@controller.headers['Content-Type'] ||= 'text/javascript'\n" + diff --git a/actionpack/lib/action_view/helpers/prototype_helper.rb b/actionpack/lib/action_view/helpers/prototype_helper.rb index 113ddc873952ce948d5eb31678d4b9903abd68a9..1f6aa274dbad322262ef8b391294636ce9630aec 100644 --- a/actionpack/lib/action_view/helpers/prototype_helper.rb +++ b/actionpack/lib/action_view/helpers/prototype_helper.rb @@ -618,29 +618,33 @@ def drop_receiving(id, options = {}) end private - def page - self - end + def page + self + end - def record(line) - returning line = "#{line.to_s.chomp.gsub /\;$/, ''};" do - self << line + def record(line) + returning line = "#{line.to_s.chomp.gsub /\;$/, ''};" do + self << line + end end - end - def render(*options_for_render) - Hash === options_for_render.first ? - @context.render(*options_for_render) : - options_for_render.first.to_s - end + def render(*options_for_render) + Hash === options_for_render.first ? + @context.render(*options_for_render) : + options_for_render.first.to_s + end - def javascript_object_for(object) - object.respond_to?(:to_json) ? object.to_json : object.inspect - end + def javascript_object_for(object) + object.respond_to?(:to_json) ? object.to_json : object.inspect + end - def arguments_for_call(arguments) - arguments.map { |argument| javascript_object_for(argument) }.join ', ' - end + def arguments_for_call(arguments) + arguments.map { |argument| javascript_object_for(argument) }.join ', ' + end + + def method_missing(method, *arguments) + JavaScriptProxy.new(self, method.to_s.camelize) + end end end @@ -718,7 +722,7 @@ def method_missing(method, *arguments) if method.to_s =~ /(.*)=$/ assign($1, arguments.first) else - call("#{method.to_s.first}#{method.to_s.classify[1..-1]}", *arguments) + call("#{method.to_s.first}#{method.to_s.camelize[1..-1]}", *arguments) end end diff --git a/actionpack/test/controller/action_pack_assertions_test.rb b/actionpack/test/controller/action_pack_assertions_test.rb index 9ab0f28f6b59aeb026bd7c8a53ab43a605ff6daf..b359750d168b1322987c747ab8934e38f538a8d8 100644 --- a/actionpack/test/controller/action_pack_assertions_test.rb +++ b/actionpack/test/controller/action_pack_assertions_test.rb @@ -479,10 +479,12 @@ def setup @controller = ActionPackAssertionsController.new @request, @response = ActionController::TestRequest.new, ActionController::TestResponse.new end + def test_rendering_xml_sets_content_type process :hello_xml_world - assert_equal('text/xml', @controller.headers['Content-Type']) + assert_equal('application/xml', @controller.headers['Content-Type']) end + def test_rendering_xml_respects_content_type @response.headers['Content-Type'] = 'application/pdf' process :hello_xml_world diff --git a/actionpack/test/template/prototype_helper_test.rb b/actionpack/test/template/prototype_helper_test.rb index 61cda1158dd6be10f9a06c20e503c44e3dc43ed9..253a8bac1c50d12e0f3d0f8ab8c2fa672bf03ed9 100644 --- a/actionpack/test/template/prototype_helper_test.rb +++ b/actionpack/test/template/prototype_helper_test.rb @@ -380,4 +380,9 @@ def test_collection_proxy_with_zip }); EOS end + + def test_class_proxy + @generator.form.focus('my_field') + assert_equal "Form.focus(\"my_field\");", @generator.to_s + end end \ No newline at end of file