- Recent
- Popular
- Tags (0)
- Subscribers (1)
- iPhone Optimization: stylesheet_link_tag cachingJune 29 2007
-
This change to the Rails core is a couple months old, but especially relevant when developing for the iPhone. One of the ways to optimize the performance of apps delivered to iPhones is to reduce the number of requests required for each action. If you like to split up your css files in logical order like I do, then you might find the stylesheet_link_tag caching useful.
Before: stylesheet_link_tag :all # returns => # <link href="/stylesheets/style1.css" media="screen" rel="Stylesheet" type="text/css" /> # <link href="/stylesheets/styleB.css" media="screen" rel="Stylesheet" type="text/css" /> # <link href="/stylesheets/styleX2.css" media="screen" rel="Stylesheet" type="text/css" /> stylesheet_link_tag "shop", "cart", "checkout" # returns => # <link href="/stylesheets/shop.css" media="screen" rel="Stylesheet" type="text/css" /> # <link href="/stylesheets/cart.css" media="screen" rel="Stylesheet" type="text/css" /> # <link href="/stylesheets/checkout.css" media="screen" rel="Stylesheet" type="text/css" /> After: stylesheet_link_tag :all, :cache => true # returns => # <link href="/stylesheets/all.css" media="screen" rel="Stylesheet" type="text/css" /> stylesheet_link_tag "shop", "cart", "checkout", :cache => "payment" # returns => # <link href="/stylesheets/payment.css" media="screen" rel="Stylesheet" type="text/css" />You need to have ActionController::Base.perform_caching =
- respond_to :iPhone in RailsJune 29 2007
-
As promised in my prior article, here is my current solution to quickly and easily tack on an iPhone specific user interface to Rails applications. Our goal is to be able to deliver customized html, js and css for the iPhone. To do so, I’ve decided to hijack our best friend respond_to. respond_to delivers different content to browsers based on their HTTP request and even though its only designed to discriminate based on mime-type, its pretty easy to modify it to also discriminate based on user-agent. The other distinct advantage of using respond_to is that not only can we create different html, javascript and css views, but we can also pass blocks.
If you want to follow along in the core, open up actionpack/lib/action_controller/mime_responds.rb and scroll down to the Responder Class.
The initialize method checks the CGI request for the list of acceptable formats and puts them in an array in order of preference (@mime_type_priority). Later it iterates through this array and returns the first one that matches what’s listed in respond_to. Let’s modify it to automagically add iPhone specific MIME types to the front of that preference array.
alias original_initialize initialize def initialize(controller) original_initialize(controller) # If the user agent is Safari on iPhone, duplicate the acceptable # formats with iphone_ prepe - Development for iPhoneJune 28 2007
-
Normally I wouldn’t advocate developing completely different views for one particular user-agent. It violates the web standards mindset that has been burned into my brain over many years. However, I can’t ignore the fact that the iPhone throws a wrench into some of that mindset. The iPhone’s full web browser will be great for reading news sites & blogs, but for web apps, we should take a couple things into consideration:
- Every kilobyte matters! The EDGE network will have users crawling the web, quite literally. Download speeds will float somewhere between that of a 56kbps modem and an ISDN line when users are away from WiFi. Hiding elements with media-specific stylesheets does us no good because the data is still downloaded (including all those hefty javascript libraries). Which brings me to my next point…
- iPhone will probably use “screen” css media, not “handheld” (pretty clear from the public demonstrations and Apple’s huge emphasis on it having a “FULL web browser” and browsing the web the “way it was meant” to be browsed). After all, what’s the point of having a phone with a full web browser complete with zoom-in, zoom-out capability if the browser loads stripped down versions of web pages by default? Again, great for browsing, not for monitor-sized web apps.
- Using web apps on the iPhone will be cumbersome enough as it is. There’s no way to directl
- Life on Edge RailsJune 1 2007
-
assert_difference & assert_no_difference now accept an array of expressions
The assert_difference and assert_no_difference testing methods now can accept an array of expressions to evaluate. So now instead of doing:
assert_difference 'User.count', +1 do post :create, :article => { :profile => {}, ... } end assert_difference 'Profile.count', +1 do post :create, :article => { :profile => {}, ... } endwe can do:
assert_difference ['User.count', 'Profile.count'], +1 do post :create, :article => { :profile => {}, ... } endThat’s some nice DRY action!
- Life on Edge RailsMay 31 2007
-
Date#change
Date now has #change and works just like Time#change. So now we can do: next_bill_date = Date.today.change( :month => Date.today.month + 1, :day => 15)All controller names pluralized
map.resource will now map to a pluralized controller name by default: map.resource :account # now maps to: AccountsController < ApplicationControllerWhere this makes even more sense to me is in this situation which I brought up in a post on the rubyonrails-core mailing list . Let’s say I have products which each has_one manufacturer. I want to be able to control those manufacturers both within the context of their association with the products and separately on their own. The way it used to be:
map.resources :products, :has_one => :manufacturer #=> ManufacturerController map.resources :manufacturers #=> ManufacturersControllerThe first mapping would look for a ManufacturerController because :has_one generates a singleton resource. But the second mapping would look for a ManufacturersController. Regardless of the context, I’m probably going to control my manufacturers resource the same way. So now all controllers are by default plural, whether its coming from map:resource, map.resources, :has_one, or :has_many.
map.resources :products, :has_on
