Search code examples
rubylayoutsinatraiphonebefore-filter

In Sinatra, best way to serve iPhone layout vs. normal layout?


I'm writing a Sinatra app which needs to render different layouts based on whether the user is using an iPhone or a regular browser. I can detect the browser type using Rack-Mobile-Detect but I'm not sure of the best way to tell Sinatra which layout to use.

Also, I have a feeling that how I choose to do this may also break page caching. Is that true?

Example code:

require 'sinatra/base'
require 'haml'
require 'rack/mobile-detect'

class Orca < Sinatra::Base

  use Rack::MobileDetect

  helpers do
    def choose_layout
      if request.env['X_MOBILE_DEVICE'] == :iPhone
        # use iPhone layout
      else
        # use normal layout
      end
    end
  end

  before do
    # should I use a before filter?
    choose_layout()  
  end

  get '/' do
    haml :home # with proper layout
  end

end #Class Orca

Solution

  • This is what I ended up doing:

    require 'sinatra/base'
    require 'haml'
    require 'rack/mobile-detect'
    
    class Orca < Sinatra::Base
    
      use Rack::MobileDetect
    
      # HAML template options
      # Use HTML5 doctype
      set :haml, {:format => :html5 }
    
      helpers do
    
        def get_layout
          # For AJAX (XMLHttpRequest) requests, don't use a layout
          if request.xhr? then 
            @layout = false
            exit
          end
    
          # For non-AJAX (XMLHttpRequest) requests, choose correct layout
          # For each mobile device, you will need a layout_<device>.haml file
          # in the Views directory
          @layout = case request.env['X_MOBILE_DEVICE']
                    when /iPhone|iPod/ then :layout_iphone
    
                  # when "Android" then :layout_android
    
                    else true # use default Sinatra layout
                    end
        end
    
      end # helpers
    
      before do
        get_layout() 
      end # before filter
    
      get '/' do
        # Will use iPhone layout for iPhone|iPod, 
        # Sinatra default layout for desktop browsers
        haml :home, :layout => @layout
      end
    
    end # Class