The default respond_to blocks don't set a specific extension anymore, so that both 'show.rjs' and 'show.js.rjs' will work. [Rick]
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@6517 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
This commit is contained in:
parent
f5b8fc0335
commit
6351e0a541
|
@ -1,5 +1,7 @@
|
|||
*SVN*
|
||||
|
||||
* The default respond_to blocks don't set a specific extension anymore, so that both 'show.rjs' and 'show.js.rjs' will work. [Rick]
|
||||
|
||||
* Allow layouts with extension of .html.erb. Closes #8032 [Josh Knowles]
|
||||
|
||||
* Change default respond_to templates for xml and rjs formats. [Rick]
|
||||
|
|
|
@ -1225,7 +1225,7 @@ module ActionController #:nodoc:
|
|||
|
||||
def assert_existence_of_template_file(template_name)
|
||||
unless template_exists?(template_name) || ignore_missing_templates
|
||||
full_template_path = @template.send(:full_template_path, template_name, "#{@template.send(:template_format)}.erb")
|
||||
full_template_path = template_name.include?('.') ? template_name : @template.send(:full_template_path, template_name, "#{@template.send(:template_format)}.erb")
|
||||
template_type = (template_name =~ /layouts/i) ? 'layout' : 'template'
|
||||
raise(MissingTemplate, "Missing #{template_type} #{full_template_path}")
|
||||
end
|
||||
|
|
|
@ -107,11 +107,17 @@ module ActionController #:nodoc:
|
|||
end
|
||||
|
||||
class Responder #:nodoc:
|
||||
default_block_format = %(Proc.new { render :action => "\#{action_name}%s", :content_type => Mime::%s })
|
||||
DEFAULT_BLOCKS = {}
|
||||
DEFAULT_BLOCKS[:html] = default_block_format % ['', 'HTML']
|
||||
DEFAULT_BLOCKS[:js] = default_block_format % ['.js.rjs', 'JS']
|
||||
DEFAULT_BLOCKS[:xml] = default_block_format % ['.xml.builder', 'XML']
|
||||
default_block_format = <<-END
|
||||
Proc.new {
|
||||
@template.template_format = '%s'
|
||||
render :action => "\#{action_name}", :content_type => Mime::%s
|
||||
}
|
||||
END
|
||||
|
||||
DEFAULT_BLOCKS = [:html, :js, :xml].inject({}) do |memo, ext|
|
||||
default_block = default_block_format % [ext, ext.to_s.upcase]
|
||||
memo.update(ext => default_block)
|
||||
end
|
||||
|
||||
def initialize(block_binding)
|
||||
@block_binding = block_binding
|
||||
|
@ -132,7 +138,10 @@ module ActionController #:nodoc:
|
|||
|
||||
if block_given?
|
||||
@responses[mime_type] = Proc.new do
|
||||
eval "response.content_type = '#{mime_type.to_s}'", @block_binding
|
||||
eval <<-END, @block_binding
|
||||
@template.template_format = '#{mime_type.to_sym}'
|
||||
response.content_type = '#{mime_type.to_s}'
|
||||
END
|
||||
block.call
|
||||
end
|
||||
else
|
||||
|
|
|
@ -9,6 +9,8 @@ module ActionController
|
|||
# such as { 'RAILS_ENV' => 'production' }.
|
||||
attr_reader :env
|
||||
|
||||
attr_accessor :format
|
||||
|
||||
# Returns the HTTP request method as a lowercase symbol (:get, for example). Note, HEAD is returned as :get
|
||||
# since the two are supposedly to be functionaly equivilent for all purposes except that HEAD won't return a response
|
||||
# body (which Rails also takes care of elsewhere).
|
||||
|
@ -91,7 +93,7 @@ module ActionController
|
|||
# GET /posts/5.xhtml | request.format => Mime::HTML
|
||||
# GET /posts/5 | request.format => request.accepts.first (usually Mime::HTML for browsers)
|
||||
def format
|
||||
parameters[:format] ? Mime::Type.lookup_by_extension(parameters[:format]) : accepts.first
|
||||
@format ||= parameters[:format] ? Mime::Type.lookup_by_extension(parameters[:format]) : accepts.first
|
||||
end
|
||||
|
||||
# Returns true if the request's "X-Requested-With" header contains
|
||||
|
|
|
@ -159,6 +159,8 @@ module ActionView #:nodoc:
|
|||
attr_reader :logger, :response, :headers, :view_paths
|
||||
attr_internal :cookies, :flash, :headers, :params, :request, :response, :session
|
||||
|
||||
attr_writer :template_format
|
||||
|
||||
# Specify trim mode for the ERB compiler. Defaults to '-'.
|
||||
# See ERb documentation for suitable values.
|
||||
@@erb_trim_mode = '-'
|
||||
|
@ -207,6 +209,14 @@ module ActionView #:nodoc:
|
|||
# used by pick_template_extension determines whether ext1 or ext2 will be stored.
|
||||
@@cached_template_extension = {}
|
||||
|
||||
# Order of template handers checked by #file_exists? depending on the current #template_format
|
||||
DEFAULT_TEMPLATE_HANDLER_PREFERENCE = %w(erb rhtml builder rxml javascript delegate)
|
||||
TEMPLATE_HANDLER_PREFERENCES = {
|
||||
:js => %w(javascript erb rhtml builder rxml delegate),
|
||||
:xml => %w(builder rxml erb rhtml javascript delegate),
|
||||
:delegate => %w(delegate)
|
||||
}
|
||||
|
||||
class ObjectWrapper < Struct.new(:value) #:nodoc:
|
||||
end
|
||||
|
||||
|
@ -229,6 +239,7 @@ module ActionView #:nodoc:
|
|||
# local assigns available to the template. The #render method ought to
|
||||
# return the rendered template as a string.
|
||||
def self.register_template_handler(extension, klass)
|
||||
TEMPLATE_HANDLER_PREFERENCES[extension.to_sym] = TEMPLATE_HANDLER_PREFERENCES[:delegate]
|
||||
@@template_handlers[extension] = klass
|
||||
end
|
||||
|
||||
|
@ -331,55 +342,58 @@ module ActionView #:nodoc:
|
|||
end
|
||||
|
||||
def pick_template_extension(template_path)#:nodoc:
|
||||
formatted_template_path = "#{template_path}.#{template_format}"
|
||||
if @@cache_template_extensions
|
||||
@@cached_template_extension[formatted_template_path] ||= find_template_extension_for(template_path, formatted_template_path)
|
||||
formatted_template_path = "#{template_path}.#{template_format}"
|
||||
@@cached_template_extension[formatted_template_path] ||= find_template_extension_for(template_path)
|
||||
else
|
||||
find_template_extension_for(template_path, formatted_template_path)
|
||||
find_template_extension_for(template_path)
|
||||
end
|
||||
end
|
||||
|
||||
def delegate_template_exists?(template_path)#:nodoc:
|
||||
@@template_handlers.find { |k,| template_exists?(template_path, k) }
|
||||
end
|
||||
|
||||
def one_of(template_path, *extensions)#:nodoc:
|
||||
extensions.detect{|ext| template_exists?(template_path, ext)}
|
||||
delegate = @@template_handlers.find { |k,| template_exists?(template_path, k) }
|
||||
delegate && delegate.first.to_sym
|
||||
end
|
||||
|
||||
def erb_template_exists?(template_path)#:nodoc:
|
||||
one_of(template_path, :erb, :rhtml)
|
||||
template_exists?(template_path, :erb) && :erb
|
||||
end
|
||||
alias :rhtml_template_exists? :erb_template_exists?
|
||||
|
||||
def builder_template_exists?(template_path)#:nodoc:
|
||||
one_of(template_path, :builder, :rxml)
|
||||
template_exists?(template_path, :builder) && :builder
|
||||
end
|
||||
|
||||
def rhtml_template_exists?(template_path)#:nodoc:
|
||||
template_exists?(template_path, :rhtml) && :rhtml
|
||||
end
|
||||
|
||||
def rxml_template_exists?(template_path)#:nodoc:
|
||||
template_exists?(template_path, :rxml) && :rxml
|
||||
end
|
||||
alias :rxml_template_exists? :builder_template_exists?
|
||||
|
||||
def javascript_template_exists?(template_path)#:nodoc:
|
||||
template_exists?(template_path, :rjs)
|
||||
end
|
||||
|
||||
def formatted_template_exists?(formatted_template_exists)
|
||||
[:erb, :builder, :rjs].each do |ext|
|
||||
return ext if template_exists?(formatted_template_exists, ext)
|
||||
end
|
||||
nil
|
||||
template_exists?(template_path, :rjs) && :rjs
|
||||
end
|
||||
|
||||
def file_exists?(template_path)#:nodoc:
|
||||
template_file_name, template_file_extension = path_and_extension(template_path)
|
||||
if template_file_extension
|
||||
template_exists?(template_file_name, template_file_extension)
|
||||
template_exists?(template_file_name, template_file_extension) && template_file_extension
|
||||
else
|
||||
formatted_template_path = "#{template_path}.#{template_format}"
|
||||
cached_template_extension(formatted_template_path) ||
|
||||
formatted_template_exists?(formatted_template_path) ||
|
||||
%w(erb rhtml builder rxml javascript delegate).any? do |template_type|
|
||||
send("#{template_type}_template_exists?", template_path)
|
||||
return true if cached_template_extension(formatted_template_path)
|
||||
template_handler_preferences.each do |template_type|
|
||||
if extension = send("#{template_type}_template_exists?", formatted_template_path)
|
||||
return "#{template_format}.#{extension}"
|
||||
end
|
||||
end
|
||||
template_handler_preferences.each do |template_type|
|
||||
if extension = send("#{template_type}_template_exists?", template_path)
|
||||
return extension
|
||||
end
|
||||
end
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
# Returns true is the file may be rendered implicitly.
|
||||
|
@ -387,15 +401,13 @@ module ActionView #:nodoc:
|
|||
template_path.split('/').last[0,1] != '_'
|
||||
end
|
||||
|
||||
# symbolized version of the :format parameter of the request, or :html by default.
|
||||
def template_format
|
||||
if @template_format != false
|
||||
# check controller.respond_to?(:request) in case its an ActionMailer::Base, or some other sneaky class.
|
||||
@template_format = controller.respond_to?(:request) ? false : :html
|
||||
if controller && controller.respond_to?(:request) && controller.request && controller.request.format
|
||||
@template_format = controller.request.format == Mime::ALL ? :html : controller.request.format.to_sym
|
||||
@template_format ||= controller.request.parameters[:format].to_sym rescue :html
|
||||
end
|
||||
end
|
||||
@template_format
|
||||
|
||||
def template_handler_preferences
|
||||
TEMPLATE_HANDLER_PREFERENCES[template_format] || DEFAULT_TEMPLATE_HANDLER_PREFERENCE
|
||||
end
|
||||
|
||||
private
|
||||
|
@ -434,14 +446,9 @@ module ActionView #:nodoc:
|
|||
end
|
||||
|
||||
# Determines the template's file extension, such as rhtml, rxml, or rjs.
|
||||
def find_template_extension_for(template_path, formatted_template_path = nil)
|
||||
formatted_template_path ||= "#{template_path}.#{template_format}"
|
||||
if match = delegate_template_exists?(template_path)
|
||||
match.first.to_sym
|
||||
elsif extension = formatted_template_exists?(formatted_template_path): "#{template_format}.#{extension}"
|
||||
elsif extension = erb_template_exists?(template_path): extension
|
||||
elsif extension = builder_template_exists?(template_path): extension
|
||||
elsif javascript_template_exists?(template_path): :rjs
|
||||
def find_template_extension_for(template_path)
|
||||
if extension = file_exists?(template_path)
|
||||
return extension
|
||||
else
|
||||
raise ActionViewError, "No erb, builder, rhtml, rxml, rjs or delegate template found for #{template_path} in #{@view_paths.inspect}"
|
||||
end
|
||||
|
|
|
@ -288,11 +288,13 @@ class MimeControllerTest < Test::Unit::TestCase
|
|||
assert_equal 'Either JS or XML', @response.body
|
||||
end
|
||||
|
||||
def test_all_types_with_layout
|
||||
def test_rjs_type_skips_layout
|
||||
@request.env["HTTP_ACCEPT"] = "text/javascript"
|
||||
get :all_types_with_layout
|
||||
assert_equal 'RJS for all_types_with_layout', @response.body
|
||||
end
|
||||
|
||||
def test_html_type_with_layout
|
||||
@request.env["HTTP_ACCEPT"] = "text/html"
|
||||
get :all_types_with_layout
|
||||
assert_equal '<html>HTML for all_types_with_layout</html>', @response.body
|
||||
|
@ -343,14 +345,14 @@ class MimeControllerTest < Test::Unit::TestCase
|
|||
unless args.empty?
|
||||
@action = args.first[:action]
|
||||
end
|
||||
response.body = @action
|
||||
response.body = "#{@action} - #{@template.template_format}"
|
||||
end
|
||||
end
|
||||
|
||||
get :using_defaults
|
||||
assert_equal "using_defaults", @response.body
|
||||
assert_equal "using_defaults - html", @response.body
|
||||
|
||||
get :using_defaults, :format => "xml"
|
||||
assert_equal "using_defaults.xml.builder", @response.body
|
||||
assert_equal "using_defaults - xml", @response.body
|
||||
end
|
||||
end
|
||||
|
|
|
@ -362,6 +362,12 @@ class RenderTest < Test::Unit::TestCase
|
|||
assert_equal '<test>passed formatted html erb</test>', @response.body
|
||||
end
|
||||
|
||||
def test_should_render_formatted_html_erb_template_with_faulty_accepts_header
|
||||
@request.env["HTTP_ACCEPT"] = "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, appliction/x-shockwave-flash, */*"
|
||||
get :formatted_xml_erb
|
||||
assert_equal '<test>passed formatted html erb</test>', @response.body
|
||||
end
|
||||
|
||||
protected
|
||||
def assert_deprecated_render(&block)
|
||||
assert_deprecated(/render/, &block)
|
||||
|
|
|
@ -309,16 +309,22 @@ class RequestTest < Test::Unit::TestCase
|
|||
assert @request.head?
|
||||
end
|
||||
|
||||
def test_format
|
||||
def test_xml_format
|
||||
@request.instance_eval { @parameters = { :format => 'xml' } }
|
||||
assert_equal Mime::XML, @request.format
|
||||
end
|
||||
|
||||
def test_xhtml_format
|
||||
@request.instance_eval { @parameters = { :format => 'xhtml' } }
|
||||
assert_equal Mime::HTML, @request.format
|
||||
end
|
||||
|
||||
def test_txt_format
|
||||
@request.instance_eval { @parameters = { :format => 'txt' } }
|
||||
assert_equal Mime::TEXT, @request.format
|
||||
end
|
||||
|
||||
def test_nil_format
|
||||
@request.instance_eval { @parameters = { :format => nil } }
|
||||
@request.env["HTTP_ACCEPT"] = "text/javascript"
|
||||
assert_equal Mime::JS, @request.format
|
||||
|
|
Loading…
Reference in New Issue