respond_to forces template format

It appears that #8174 on edge broke the ability to render HTML in the JS respond_to block for an ajax request. Line 131 of mime_responds.rb explicitly sets the template_format to that of the mime type. This forces action view to only look for templates of that format (including layouts and partials).

In my case, I have a link_to_remote that I want to return HTML for: http://pastie.caboo.se/76204

I could see other situations where I don't necessarily want to force the template format based on the mime type, such as wanting to render HTML partials inside of an Atom feed.

In my option, it should use the order of the Accepts header to give preference to template formats just like it does with choosing the format for the respond_to block. What are your thoughts?

Brandon

It appears that #8174 on edge broke the ability to render HTML in the
JS respond_to block for an ajax request. Line 131 of
mime_responds.rb explicitly sets the template_format to that of the
mime type. This forces action view to only look for templates of
that format (including layouts and partials).

This definitely sounds like a bug, I've reopened the ticket. Josh,
any comments?

That was so it would know the right format when rendering the
templates. Otherwise it'd try to use html for everything. At any
rate, feel free to add some failing tests for the behavior you think
is correct, or come up with a patch to fix this.

Referring to brandon's example... (http://pastie.caboo.se/76204)

It seems to me like it should act that way. If I wanted to change the
template format, I would do render :action =>
"index.html.erb", :layout => false (Not tested, but I hope works)

I just don't really see it as a bug, although, I've never been in the
exact scenario as described. If I need to render a partial from a js
request, I would do it from within an another rjs template, which
works.

That's a bit of a messy api, perhaps something like:

render :partial=>'something', :format=>:html

Would at least be a little more flexible? However I'm going to
completely punt on actually implementing this...

Referring to brandon's example... (http://pastie.caboo.se/76204)

It seems to me like it should act that way. If I wanted to change the
template format, I would do render :action =>
"index.html.erb", :layout => false (Not tested, but I hope works)

Nope, it doesn't. render :template => 'path/to/template.html.erb' works, but then if there are any HTML partials, or an HTML layout, it can't find them.

I just don't really see it as a bug, although, I've never been in the
exact scenario as described. If I need to render a partial from a js
request, I would do it from within an another rjs template, which
works.

I just don't think that the content type should mandate the template format. It should prefer a specific format, but if that format doesn't exist, I think it should use the Accepts header to determine other template formats.

I'm looking into a patch for this.

Brandon

I just don't think that the content type should mandate the template
format. It should prefer a specific format, but if that format
doesn't exist, I think it should use the Accepts header to determine
other template formats.

There be dragons. The accepts header is a constant source of
shenanigans for those of us who run regularly-crawled public sites.
Browsers send junk, don't rely on it.

The problem that you're seeing is that your ajax request is actually
*asking* for javascript, so it won't do what you want it to.

The best fix is to probably to render the js version of the partial,
but if it doesnt exist, fall back to html or something similar.

Yeah, but could it at least be used for preference? So of the Accepts header has "text/javascript; text/html", it would look for rjs, then html?

Brandon

Nope, it doesn't. render :template => 'path/to/template.html.erb'
works, but then if there are any HTML partials, or an HTML layout, it
can't find them.

I think this is the real problem. Your initial render should set the
mime type for all renders to follow (with the exception that js
renders should look for html as they need for partials).