mirror of
https://github.com/github/rails.git
synced 2026-01-29 00:08:15 -05:00
Added synonym and custom type handling to respond_to [DHH]
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@3844 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
This commit is contained in:
@@ -26,22 +26,28 @@ module ActionController #:nodoc:
|
||||
@order = []
|
||||
@responses = {}
|
||||
end
|
||||
|
||||
def custom(mime_type, *args, &block)
|
||||
mime_type = mime_type.is_a?(Mime::Type) ? mime_type : Mime::Type.lookup(mime_type.to_s)
|
||||
|
||||
@order << mime_type
|
||||
|
||||
if block_given?
|
||||
@responses[mime_type] = block
|
||||
else
|
||||
if argument = args.first
|
||||
eval("__mime_responder_arg__ = " + (argument.is_a?(String) ? "'" + argument + "'" : argument), @block_binding)
|
||||
@responses[mime_type] = eval(DEFAULT_BLOCKS[(mime_type.to_sym.to_s + "_arg").to_sym], @block_binding)
|
||||
else
|
||||
@responses[mime_type] = eval(DEFAULT_BLOCKS[mime_type.to_sym], @block_binding)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for mime_type in %w( all html js xml rss atom yaml )
|
||||
eval <<-EOT
|
||||
def #{mime_type}(argument = nil, &block)
|
||||
@order << Mime::#{mime_type.upcase}
|
||||
|
||||
if block_given?
|
||||
@responses[Mime::#{mime_type.upcase}] = block
|
||||
else
|
||||
if argument
|
||||
eval("__mime_responder_arg__ = " + (argument.is_a?(String) ? "'" + argument + "'" : argument), @block_binding)
|
||||
@responses[Mime::#{mime_type.upcase}] = eval(DEFAULT_BLOCKS[(Mime::#{mime_type.upcase}.to_sym.to_s + "_arg").to_sym], @block_binding)
|
||||
else
|
||||
@responses[Mime::#{mime_type.upcase}] = eval(DEFAULT_BLOCKS[Mime::#{mime_type.upcase}.to_sym], @block_binding)
|
||||
end
|
||||
end
|
||||
custom(Mime::#{mime_type.upcase}, argument, &block)
|
||||
end
|
||||
EOT
|
||||
end
|
||||
@@ -52,7 +58,7 @@ module ActionController #:nodoc:
|
||||
@responses[@order.first].call
|
||||
return
|
||||
else
|
||||
if @order.include?(priority)
|
||||
if priority === @order
|
||||
@responses[priority].call
|
||||
return # mime type match found, be happy and return
|
||||
end
|
||||
|
||||
@@ -1,44 +1,48 @@
|
||||
module Mime
|
||||
class Type < String
|
||||
def initialize(string, part_of_all = true)
|
||||
@part_of_all = part_of_all
|
||||
def self.lookup(string)
|
||||
LOOKUP[string]
|
||||
end
|
||||
|
||||
def initialize(string, symbol = nil, synonyms = [])
|
||||
@symbol, @synonyms = symbol, synonyms
|
||||
super(string)
|
||||
end
|
||||
|
||||
def to_sym
|
||||
SYMBOLIZED_MIME_TYPES[self] ? SYMBOLIZED_MIME_TYPES[self] : to_sym
|
||||
@symbol || to_sym
|
||||
end
|
||||
|
||||
def ===(list)
|
||||
if list.is_a?(Array)
|
||||
list.include?(self)
|
||||
(@synonyms + [ self ]).any? { |synonym| list.include?(synonym) }
|
||||
else
|
||||
super
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
SYMBOLIZED_MIME_TYPES = {
|
||||
"" => :unspecified,
|
||||
"*/*" => :all,
|
||||
"text/html" => :html,
|
||||
"application/javascript" => :js,
|
||||
"application/x-javascript" => :js,
|
||||
"text/javascript" => :js,
|
||||
"text/xml" => :xml,
|
||||
"application/xml" => :xml,
|
||||
"application/rss+xml" => :rss,
|
||||
"application/rss+atom" => :atom,
|
||||
"application/x-xml" => :xml,
|
||||
"application/x-yaml" => :yaml
|
||||
}
|
||||
ALL = Type.new "*/*", :all
|
||||
HTML = Type.new "text/html", :html
|
||||
JS = Type.new "text/javascript", :js, %w( application/javascript application/x-javascript )
|
||||
XML = Type.new "text/xml", :xml, %w( application/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
|
||||
|
||||
ALL = Type.new "*/*"
|
||||
HTML = Type.new "text/html"
|
||||
JS = Type.new "text/javascript"
|
||||
JAVASCRIPT = Type.new "text/javascript"
|
||||
XML = Type.new "application/xml"
|
||||
RSS = Type.new "application/rss+xml"
|
||||
ATOM = Type.new "application/atom+xml"
|
||||
YAML = Type.new "application/x-yaml"
|
||||
LOOKUP = Hash.new { |h, k| h[k] = Type.new(k) }
|
||||
|
||||
LOOKUP["*/*"] = ALL
|
||||
LOOKUP["text/html"] = HTML
|
||||
LOOKUP["application/rss+xml"] = RSS
|
||||
LOOKUP["application/atom+xml"] = ATOM
|
||||
LOOKUP["application/x-yaml"] = YAML
|
||||
|
||||
LOOKUP["text/javascript"] = JS
|
||||
LOOKUP["application/javascript"] = JS
|
||||
LOOKUP["application/x-javascript"] = JS
|
||||
|
||||
LOOKUP["text/xml"] = XML
|
||||
LOOKUP["application/xml"] = XML
|
||||
LOOKUP["application/x-xml"] = XML
|
||||
end
|
||||
@@ -61,7 +61,7 @@ module ActionController
|
||||
end
|
||||
end
|
||||
|
||||
@content_type = Mime::Type.new(@content_type)
|
||||
@content_type = Mime::Type.lookup(@content_type)
|
||||
end
|
||||
|
||||
def accepts
|
||||
@@ -71,7 +71,7 @@ module ActionController
|
||||
[ content_type, Mime::ALL ]
|
||||
else
|
||||
@env['HTTP_ACCEPT'].split(";").collect! do |mime_type|
|
||||
Mime::Type.new(mime_type.strip)
|
||||
Mime::Type.lookup(mime_type.strip)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -56,6 +56,14 @@ class RespondToController < ActionController::Base
|
||||
end
|
||||
end
|
||||
|
||||
def custom_type_handling
|
||||
respond_to do |type|
|
||||
type.html { render :text => "HTML" }
|
||||
type.custom("application/crazy-xml") { render :text => "Crazy XML" }
|
||||
type.all { render :text => "Nothing" }
|
||||
end
|
||||
end
|
||||
|
||||
def rescue_action(e)
|
||||
raise unless ActionController::MissingTemplate === e
|
||||
end
|
||||
@@ -155,4 +163,24 @@ class MimeControllerTest < Test::Unit::TestCase
|
||||
get :made_for_content_type
|
||||
assert_equal "RSS", @response.body
|
||||
end
|
||||
|
||||
def test_synonyms
|
||||
@request.env["HTTP_ACCEPT"] = "application/javascript"
|
||||
get :js_or_html
|
||||
assert_equal 'JS', @response.body
|
||||
|
||||
@request.env["HTTP_ACCEPT"] = "application/x-xml"
|
||||
get :using_argument_defaults
|
||||
assert_equal "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<person>\n <name>David</name>\n</person>\n", @response.body
|
||||
end
|
||||
|
||||
def test_custom_types
|
||||
@request.env["HTTP_ACCEPT"] = "application/crazy-xml"
|
||||
get :custom_type_handling
|
||||
assert_equal 'Crazy XML', @response.body
|
||||
|
||||
@request.env["HTTP_ACCEPT"] = "text/html"
|
||||
get :custom_type_handling
|
||||
assert_equal 'HTML', @response.body
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user