diff --git a/.gitignore b/.gitignore index 51538ad..b8dec80 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ Gemfile.lock pkg/* vendor/ruby +*.DS_Store \ No newline at end of file diff --git a/README.md b/README.md index a800b08..eb73d8f 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ Mobile Fu Want to automatically detect mobile devices that access your Rails application? Mobile Fu allows you to do just that. People can access your site from a Palm, Blackberry, iPhone, iPad, Nokia, etc. and it will automatically adjust the format -of the request from :html to :mobile. +of the request from :html to :mobile or :tablet. Installation ------------ @@ -25,18 +25,22 @@ set as :mobile format. It is up to you to determine how you want to handle these requests. It is also up to you to create the .mobile.erb versions of your views that are to be requested. -Mobile Fu automatically adds a new `:mobile` to `text/html` mime type alias for -Rails apps. If you already have a custom `:mobile` alias registered in +Mobile Fu automatically adds a new `:mobile` and `:tablet` to `text/html` mime type +alias for Rails apps. If you already have a custom `:mobile` alias registered in `config/initializers/mime_types.rb`, you can remove that. I recommend that you setup a before_filter that will redirect to a specific page depending on whether or not it is a mobile request. How can you check this? - is_mobile_device? # => Returns true or false depending on the device + is_mobile_device? # => Returns true or false depending on the device or + + is_tablet_device? # => Returns true if the device is a tablet You can also determine which format is currently set in by calling the following: - in_mobile_view? # => Returns true or false depending on current req. format + in_mobile_view? # => Returns true or false depending on current req. format or + + in_tablet_view? # => Returns true if the current req. format is for tablet view Also, if you want the ability to allow a user to switch between 'mobile' and 'standard' format (:html), you can just adjust the mobile_view session variable @@ -45,6 +49,9 @@ in a custom controller action. session[:mobile_view] # => Set to true if request format is :mobile and false if set to :html + session[:tablet_view] # => Set to true if request format is :tablet and false + if set to :html + So, different devices need different styling. Don't worry, we've got this baked in to Mobile Fu. @@ -86,5 +93,11 @@ mobile device emulator, or you can call `force_mobile_format` in a before filter before_filter :force_mobile_format end +You can also force the tablet view by calling `force_tablet_format` instead + + class ApplicationController < ActionController::Base + has_mobile_fu + before_filter :force_tablet_format + end Copyright (c) 2008 Brendan G. Lim, Intridea, Inc., released under the MIT license diff --git a/lib/mobile-fu.rb b/lib/mobile-fu.rb index c7408b7..d96a09a 100644 --- a/lib/mobile-fu.rb +++ b/lib/mobile-fu.rb @@ -25,11 +25,16 @@ class Railtie < Rails::Railtie end Mime::Type.register_alias "text/html", :mobile + Mime::Type.register_alias "text/html", :tablet end end module ActionController module MobileFu + # These are various strings that can be found in tablet devices. Please feel free + # to add on to this list. + TABLET_USER_AGENTS = 'ipad|android 3.0|xoom|sch-i800|playbook|tablet|kindle|honeycomb' + def self.included(base) base.extend ClassMethods end @@ -55,11 +60,13 @@ def has_mobile_fu(set_request_format = true) before_filter :set_request_format if set_request_format helper_method :is_mobile_device? + helper_method :is_tablet_device? helper_method :in_mobile_view? + helper_method :in_tablet_view? helper_method :is_device? helper_method :mobile_device end - + # Add this to your controllers to prevent the mobile format from being set for specific actions # class AwesomeController < ApplicationController # has_no_mobile_fu_for :index @@ -91,13 +98,25 @@ def force_mobile_format end end + # Forces the request format to be :tablet + def force_tablet_format + unless request.xhr? + request.format = :tablet + session[:tablet_view] = true if session[:tablet_view].nil? + end + end + # Determines the request format based on whether the device is mobile or if - # the user has opted to use either the 'Standard' view or 'Mobile' view. + # the user has opted to use either the 'Standard' view or 'Mobile' view or + # 'Tablet' view. def set_mobile_format if !mobile_exempt? && is_mobile_device? && !request.xhr? request.format = session[:mobile_view] == false ? :html : :mobile session[:mobile_view] = true if session[:mobile_view].nil? + elsif !mobile_exempt? && is_tablet_device? && !request.xhr? + request.format = session[:tablet_view] == false ? :html : :tablet + session[:tablet_view] = true if session[:tablet_view].nil? end end @@ -109,6 +128,14 @@ def in_mobile_view? request.format.to_sym == :mobile end + # Returns either true or false depending on whether or not the format of the + # request is either :tablet or not. + + def in_tablet_view? + return false unless request.format + request.format.to_sym == :tablet + end + # Returns either true or false depending on whether or not the user agent of # the device making the request is matched to a device in our regex. @@ -116,6 +143,10 @@ def is_mobile_device? !!mobile_device end + def is_tablet_device? + request.user_agent.to_s.downcase =~ Regexp.new(ActionController::MobileFu::TABLET_USER_AGENTS) + end + def mobile_device request.headers['X_MOBILE_DEVICE'] end @@ -126,10 +157,10 @@ def mobile_device def is_device?(type) request.user_agent.to_s.downcase.include? type.to_s.downcase end - + # Returns true if current action isn't supposed to use mobile format # See #has_no_mobile_fu_for - + def mobile_exempt? self.class.instance_variable_get("@mobile_exempt_actions").try(:include?, params[:action].to_sym) end diff --git a/lib/mobile-fu/helper.rb b/lib/mobile-fu/helper.rb index e314454..033ff82 100644 --- a/lib/mobile-fu/helper.rb +++ b/lib/mobile-fu/helper.rb @@ -26,16 +26,16 @@ def stylesheet_link_tag_with_mobilization(*sources) sources.each do |source| mobilized_sources << source - + device_names.compact.each do |device_name| # support ERB and/or SCSS extensions (e.g., mobile.css.erb, mobile.css.scss.erb) possible_source = source.to_s.sub(/\.css.*$/, '') + "_#{device_name}" - + mobilized_files = Dir.glob(File.join(stylesheets_dir, "#{possible_source}.css*")).map { |f| f.sub(stylesheets_dir, '') } mobilized_sources += mobilized_files.map { |f| f.sub(/\.css.*/, '') } end end - + stylesheet_link_tag_without_mobilization *mobilized_sources end end