Default Mime-Type Template

I have added the following to my application controller so that rails sets the content_type header to application/xhtml+xml if the browser accepts that mime-type and defaults to text/html otherwise.

<code> before_filter :adjust_request_format

def adjust_request_format     request.format = :xhtml if browser_accepts_xhtml? end

def browser_accepts_xhtml?     return request.env["HTTP_ACCEPT"].split(',').include?("application/ xhtml+xml") end </code>

I haven't added any "respond_to |format|" blocks for my actions (and I don't want to) but instead I name my view template home.erb rather than home.xhtml.erb and rely on the fact that if a format-specific template cannot be found then rails will resort to using that default template. This way I can use a single template for both the html and xhtml formats without having to write a lick of code.

However, if the format is :html then my layout template, layouts/ application.erb will be included as expected but if the format is :xhtml then the layout is not included for some reason. Does anyone know why not and what I can do to get it included for the :xhtml format without having to write respond_to blocks in all of my actions?

Setting the DOCTYPE or even the content-type meta tag to XHTML does not actually get the browser to treat the code as XML instead of HTML. To get it to do that you have to perform "content negotiation" which I'm trying to do through rails but can also be done by modifying your server settings as well.

Oh I should have also mentioned that I'm on rails 2.0.1 and have added the following line to config/initializers/mime_types.rb:

Mime::Type.register "application/xhtml+xml", :xhtml

You mean why do I want the browser to render XHTML instead of HTML? I dunno, just thought it would be cool to hold myself to a high standard I guess :smiley:

Are you sure about that? The Road to XHTML 2.0: MIME Types

Well you're probably right, I'm just tinkering after all. But whether my motivations are pointless or not I still wouldn't mind knowing the answer to the original question I posed. That is, why does application.erb only get included for the :html format? This could come up in other situations besides my "pointless" one.

Ah I guess that makes sense, rails assumes that only :html will ever need to include a layout. In my case though it needs to come up in my xhtml template too... so can I turn "include layout" on for :xhtml somehow in a filter or something?

I'm sorry I guess my wording is confusing templates with mime-types. In rails 2.0 templates are named according to this pattern: action.format.renderer

Now the "format" is important because it determines what mime-type the page is served with. In my case html and xhtml formats serve templates with different mime-types, text/html and application/xhtml +xml respectively. Now you're right the templates themselves are identical which is exactly the reason why I want to use a common one for both html and xhtml by leaving out the "format" and naming the template as action.erb instead of action.format.erb so that, irregardless of the format, action.erb is the template that gets served.

My problem is that I also want action.erb to "show layout" irregardless of the format but it only shows layout when the format is html. However I think I can live with the fact that this is just a rails "assumption" and a good one at that so I'm content with leaving it be for now.

No need to be so hostile Ryan. Browsers really do ignore the DOCTYPE and serve HTML... I'm observing it with Firefox 2.0 right now... in the year 2007....

Oh and sorry I guess shouldn't be saying that browsers "serve" html but rather they "parse" or "render" HTML unless you explicitly tell them not to by setting the content_type response header to the appropriate xml mime-type.

google "application/xhtml+xml versus text/html" for enlightenment :slight_smile:

A fairly concise summary can be found here, BTW:   <XHTML vs HTML FAQ - HTML & CSS - SitePoint Forums | Web Development & Design Community;

HTH!

I'm sure if you wrote up a whole valid XHTML page and put it on your Ruby On Rails site and ran it through the same validator, it would still be valid.

Except XHTML is not supposed to be served as text/html, but that's another story.

I have nothing more to say about the matter. I believe it's an attempt at doing something irrelevant, or a very good attempt at trolling.

Well, sorry to disappoint, but your believes need some adjustment. While DOCTYPE does not do much more than prompting browsers to use particular rendering mode (standards, quirks, etc.) and informing validators which standard to check code against, MIME types prompt browsers to use different parser. For a starter that means that Internet Explorer will not render the page, but will offer you to download it. Yes, IE does not support proper XHTML (by proper I mean XHTML code served as application/xhtml+xml), even in IE7. The next important point is, that if you have any error in your code your users are likely to get "Yellow page of death" ( Screen of death - Wikipedia ) instead of the page content. And there is more: CSS is interpreted differently (selectors are case sensitive, so if you have uppercase selectors in CSS they will be ignored; html/body is treated differently), comments are interpreted differently, only five entities allowed (so &copy; will give you nice yellow page of death), Javascript may cause more errors, document.write no longer works, you should use different methods for DOM manipulation (e.g. createElementNS vs. createElement), etc.

You can learn more here: http://www.hixie.ch/advocacy/xhtml (old classic) http://lachy.id.au/log/2005/12/xhtml-beginners The perils of using XHTML properly | 456 Berea Street http://wiki.whatwg.org/wiki/HTML_vs._XHTML MIME types matter; DOCTYPEs don't — Anne’s Blog

I prefer HTML 4.01 Strict, but if someone chooses to use XHTML then it is good to know trade offs, gotchas and things Zeldmand did not tell you…

Regards, Rimantas

I have added the following to my application controller so that rails sets the content_type header to application/xhtml+xml if the browser accepts that mime-type and defaults to text/html otherwise.

*snipped example code*

I haven't added any "respond_to |format|" blocks for my actions (and I don't want to) but instead I name my view template home.erb rather than home.xhtml.erb and rely on the fact that if a format-specific template cannot be found then rails will resort to using that default template. This way I can use a single template for both the html and xhtml formats without having to write a lick of code.

However, if the format is :html then my layout template, layouts/ application.erb will be included as expected but if the format is :xhtml then the layout is not included for some reason. Does anyone know why not and what I can do to get it included for the :xhtml format without having to write respond_to blocks in all of my actions?

Hi Adam,   did you make any progress on these issues?

I prefer xhtml too, especially during development. Browser errors on malformed markup is a great way to catch errors quickly.

Regards, Isak

Hi Isak,

I ended up cheating a bit and omitting the format from my view names but specifying it for my layouts and then getting the layouts to render a common partial.

So my views are named "home.erb", "about.erb", and my layout is in "layouts/_application.erb". I have "layouts/application.html.erb" and "layouts/application.xhtml.erb" but those both contain this single line: <%= render partial => 'layouts/application' %>

It's a bit of a workaround, I know, but my controller is very clean as a result of my being able to rely on rails' conventions rather than coding everything explicitly.

Rimantas thanks for clearing things up in your post and linking to those articles. I found them very enlightening. Hopefully Ryan did too :wink:

Adam