Question about Rails 2.x behavior

In Rails 2.x, if you have an XML template, and try to render a template that does not have an XML version, but does have an HTML version, it will be rendered. XML and HTML are just examples; this is true for any two mime types.

Is this behavior important? First of all, I'm not sure this is the right behavior, since it's possible to be explicit about the format you wish to use and rendering a template from a different MIME seems likely to be a mistake. Second of all, it requires us to widen our search criteria when looking for subsidiary templates (like partials), and prevents us from efficiently caching the template for a given format (instead, we need to cache the template for a given Array of formats, which is much less efficient).

I also think that restricting subsidiary templates would be consistent with other (non-breaking) fixes we've done to ensure that layouts match the MIME type of the template they are wrapping (which allowed us to eliminate the exempt_from_layout hacks).

Thanks for your attention,

-- Yehuda

Yeah I definitely agree that this should change. It's actually bitten
me a couple of times where I, when writing my initial tests, would
forget to write the XML view, but the test still passed because it
rendered the HTML template. Bad Rails! Bad!

Would love to see this implemented to be more strict.

--Jeremy

I've always thought this behavior to be strange and would not miss it.
-Luke

Hey,

Yes, it should assume a file of the same type, and raise if there
isn't.

i.e.

index.html.erb renders 'example' , should find example.html.erb or
raise

Same with xml:

index.xml.erb renders 'example' , should find example.xml.erb or
raise

But overwrites should be allowed:

index.html.erb renders 'example.xml.erb' , should work

Regards
Kieran

In Rails 2.x, if you have an XML template, and try to render a template
that does not have an XML version, but does have an HTML version, it
will be rendered. XML and HTML are just examples; this is true for any
two mime types.

Is this behavior important? First of all, I'm not sure this is the right
behavior, since it's possible to be explicit about the format you wish
to use and rendering a template from a different MIME seems likely to be
a mistake. Second of all, it requires us to widen our search criteria
when looking for subsidiary templates (like partials), and prevents us
from efficiently caching the template for a given format (instead, we
need to cache the template for a given Array of formats, which is much
less efficient).

I fully agree.

I also think that restricting subsidiary templates would be consistent
with other (non-breaking) fixes we've done to ensure that layouts match
the MIME type of the template they are wrapping (which allowed us to
eliminate the exempt_from_layout hacks).

Its a change that should happen, we should be explicit of the mime
types and our templates.

In Rails 2.x, if you have an XML template, and try to render a template
that does not have an XML version, but does have an HTML version, it
will be rendered. XML and HTML are just examples; this is true for any
two mime types.

I'm guessing that the historical basis for this behaviour is:

xml.content render :partial=>"post", :object=>post

So long as we support :format=>:html in that call, I think the change
is worth making in 3.0. I'd also suggest that the exception gave a
useful message like:

Template not found: post.xml, found post.html. If that's what you
wanted use render ... :format=>:html

I'd also assume the behavior might be left over from the early days of bare .erb templates - there are still a few of those in the test suite, and I remember it was a headache when sorting out the 'JS responses get wrapped in HTML layouts' mess.

--Matt Jones

Am I the only one that didn’t understand this first sentence?

How can you have an XML template if that template doesn’t have an XML version?

Anyway, I’d like to chip in with a small request (I don’t know if it’s exactly related to the question) — if you defined extra HTML formats (using Mime::Type.register_alias) in your app (like :mobile and :iphone), I’d like that templates render the other HTML format if the current one isn’t available. This is especially useful for partials; index.mobile.erb and index.iphone.erb should both be able to use the _post.html.erb partial.

Kieran P wrote:


Hey,
Yes, it should assume a file of the same type, and raise if there
isn't.
i.e.
index.html.erb renders 'example' , should find example.html.erb or
raise
Same with xml:
index.xml.erb renders 'example' , should find example.xml.erb or
raise
But overwrites should be allowed:
index.html.erb renders 'example.xml.erb' , should work

render “example.xml” would work just fine today on master, even with
the change I’m proposing.

– Yehuda

Mislav Marohnić wrote:

In
Rails 2.x, if you have an XML template, and try to render a template

that does not have an XML version, but does have an HTML version, …

Am I the only one that didn’t understand this first sentence?

How can you have an XML template if that template doesn’t have
an XML version?

Anyway, I’d like to chip in with a small request (I don’t know
if it’s exactly related to the question) — if you defined extra HTML
formats (using Mime::Type.register_alias) in your app (like :mobile and
:iphone), I’d like that templates render the other HTML format if the
current one isn’t available. This is especially useful for partials;
index.mobile.erb and index.iphone.erb should both be able to use the
_post.html.erb partial.

This is actually rather similar to the requirement that RJS templates
also be able to render HTML. Essentially, you want to be able to have
an alias mime that expands out into several acceptable format
extensions. Solution forthcoming :slight_smile: