Thursday, July 16, 2009

DRYing Up Views Between Browser and Mobile Versions (across MIME types)

I was working on an app and decided that in order for it to be truly usable on mobile devices (iPhone, Blackberry, etc), it needed to have views that were tailored for small screens.

I started by registering a new MIME type 'mobile' so I could detect it, and respond_to mobile requests appropriately.
#config/initializers/mime_types.rb


Mime::Type.register_alias "text/html", :mobile


However, I quickly ran into a problem. I was duplicating a lot of code between my abc.html.erb views and my new abc.mobile.erb views. The obvious solution was to use partials. However, the *.mobile.erb views were failing to load the partials I already had.

What I realized after a little playing around was that if you have a view with a declared MIME type (new.mobile.erb) and you try to render a partial


<%= render :partial => 'posts' %>

Rails will look for partials with the same MIME type (_posts.mobile.erb), but it will not find partials with other MIME types (_posts.html.erb). However, the solution is to take the MIME type out of the partial (_posts.erb), then the partial will be found when called from either an HTML or a Mobile view.