Redesign your site in place using Rails custom mime types
by Wynn Netherland
Sat, 28 Jun 2008 19:12:00 GMT was interesting enough to generate 4 comments so far
After reading Ben Smith’s classic iPhone on Rails 2 article and implementing our own iPhone site after the jump to Rails 2, I was struck at how easy it is to create you own custom mime types to serve up different content to different devices.
When the time came to redesign the main MindBites site, I didn’t look forward to a lot of branching and merging, no matter how easy Git makes it. Then it hit me. Why not create a custom mime type and serve up a new layout and views for beta users? Let’s take a look at how we’re doing just that.
Step 1: Register your custom mime type
The first thing we need to do is tell Rails we’ve got a new format type to serve up:
# config/environment.rb
Mime::Type.register_alias "text/html", :iphone
Mime::Type.register_alias "text/html", :beta
We used beta, but you could use any value here not already in use.
Step 2: Detect a beta request
In order to let only the cool folks into our new beta site, we’ll need a big burly bouncer at the door keeping out the riff-raff:
# application.rb
before_filter :adjust_format_for_beta
...
def adjust_format_for_beta
request.format = :beta if beta_request?
end
def beta_request?
return (request.subdomains.first == "beta" || params[:format] == "beta")
end
The before_filter executes before each request and if ‘beta’ is the first subdomain or passed in as a format param, Rails will set the format to :beta.
Step 3: We’re in da club, now what?
Once we’ve identified our beta users, we now need to give them the new eye candy. We do this simply by dropping in a new view named xxxxxx.beta.erb. The bulk of the changes for our redesign are in a new application layout which serves up a new basic layout and CSS.
application.html.erb → application.beta.rb
Other views (even partials) are swapped out in a similar manner:
show.html.erb → show.beta.erb
_lesson.html.erb → _lesson.beta.erb
See update 2 below
A gotcha to watch out for
In a few cases, we had respond_to blocks in our controllers to handle differences between the iPhone and regular versions of the site. Anywhere that you have these, you’ll need to add the beta mime type as well:
respond_to do |format|
format.html
format.beta # <= You'll get a 406 Unprocessable entity error without this line
format.iphone do
render :layout => false if request.xhr?
end
end
If an action does not already have a respond_to block, you’re OK. No changes are required in your controller.
UPDATE
Thanks, Ryan Heneise, for reminding me about the last step:
Step 4: What is new is old again
When you’re ready to launch, you’ll want to fold all those beta views back into your project as the default .html.erb views. Simply rename them from .beta.erb to .html.erb. For us, it’s a bit easier since we don’t have to overwrite any .html.erb files. We’re still using .rhtml!
Thanks, Ryan!
UPDATE 2
Paul Canavese turns in some excellent QA work and informs me that Rails will not fall back to .html.erb. Our templates are still .rhtml. So it would appear you will have to touch each template or use .rhtml. Sorry!
- Tags rails
Comments
1 day later:
wow, thanks for this. very cool
1 day later:
The only thing is that eventually you’re going to want to go through and rename all those *.beta.erb files to *.html.erb.
11 days later:
You say, “You don’t have to do every view in the site because Rails will fall back to .html.erb for any views without a .beta.erb version.” I am using Rails 2.1 and I am not seeing this behavior. I get a “Template is missing” error if a template does not exist for the specified format.
I’m using register_alias in my mime_types.rb, and I see that getting picked up.
What Rails version are you using?
11 days later:
@Paul, You caught me! After you comment, I tested and it appears that it only works if your html templates are still .rhtml (as ours still are).
Sorry for that. I’ll update the article. Thanks!
Have a take?