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:
Rick Olson 2007-04-12 20:25:32 +00:00
parent f5b8fc0335
commit 6351e0a541
8 changed files with 98 additions and 64 deletions

View File

@ -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]

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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