From c5ec9de6ef19e48a66917d8f6f3a59771295765b Mon Sep 17 00:00:00 2001 From: "Brendan G. Lim" Date: Fri, 18 Jul 2008 00:59:36 -0400 Subject: [PATCH] Releasing Mobile Fu to the world --- MIT-LICENSE | 20 +++++++++ README.rdoc | 77 +++++++++++++++++++++++++++++++++++ Rakefile | 22 ++++++++++ init.rb | 5 +++ install.rb | 0 lib/mobile_fu.rb | 89 +++++++++++++++++++++++++++++++++++++++++ lib/mobilized_styles.rb | 45 +++++++++++++++++++++ uninstall.rb | 0 8 files changed, 258 insertions(+) create mode 100644 MIT-LICENSE create mode 100644 README.rdoc create mode 100644 Rakefile create mode 100644 init.rb create mode 100644 install.rb create mode 100644 lib/mobile_fu.rb create mode 100644 lib/mobilized_styles.rb create mode 100644 uninstall.rb diff --git a/MIT-LICENSE b/MIT-LICENSE new file mode 100644 index 0000000..d0ac82e --- /dev/null +++ b/MIT-LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 2008 Brendan G. Lim, Intridea, Inc. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.rdoc b/README.rdoc new file mode 100644 index 0000000..5eb20b4 --- /dev/null +++ b/README.rdoc @@ -0,0 +1,77 @@ += 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, Nokia, etc. and it will automatically adjust the format of +the request from :html to :mobile. + +== Usage + +Add this this one line to the controller. + + class ApplicationController < ActionController::Base + has_mobile_fu + end + +Once this is in place, any request that comes from a mobile device will be be +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. + +I recommend that you setup a before_filter that will redirect to certain page +depending on whether it is a mobile request or not. How can you check this? + + is_mobile_device? # => Returns true or false depending on the device + +You can also determine which format it is currently in by calling the following: + + is_mobile_view? # => Returns true or false depending on current req. format + +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 +in a custom controller action. + + session[:mobile_view] # => Set to true if request format is :mobile and false + if set to :html + +So, different devices need different styling. Don't worry, we've got this +baked in to Mobile Fu. + +If you are including a css or sass file via stylesheet_link_tag, all you have +to do is add _device to the name of one of your files to override your styling +for a certain device. The stylesheet that is loaded is dependant on which device +is making the request. + + e.g., Accessing a page from a Blackberry. + + <%= stylesheet_link_tag 'mobile.css' %> + + This loads mobile.css, and mobile_blackberry.css if the file exists. + +Supported stylesheet override device extensions at the moment are: + + blackberry + iphone + mobileexplorer + nokia + palm + +The stylesheet awesomeness was derived from Michael Bleigh's browserized styles: +http://www.intridea.com/2007/12/9/announcing-browserized-styles + +Inspiration for Mobile Fu came from Noel Rappin's rails_iui: +http://blogs.pathf.com/agileajax/2008/05/rails-developme.html + +Hopefully this should help you create some awesome mobile applications. + +== Testing Mobile Interface + +If you want to force the mobile interface for testing, you can either use a +mobile device emulator, or you can pass 'true' to has_mobile_fu. + + class ApplicationController < ActionController::Base + has_mobile_fu(true) + end + + +Copyright (c) 2008 Brendan G. Lim, Intridea, Inc., released under the MIT license diff --git a/Rakefile b/Rakefile new file mode 100644 index 0000000..de861dd --- /dev/null +++ b/Rakefile @@ -0,0 +1,22 @@ +require 'rake' +require 'rake/testtask' +require 'rake/rdoctask' + +desc 'Default: run unit tests.' +task :default => :test + +desc 'Test the sms_fu plugin.' +Rake::TestTask.new(:test) do |t| + t.libs << 'lib' + t.pattern = 'test/**/*_test.rb' + t.verbose = true +end + +desc 'Generate documentation for the sms_fu plugin.' +Rake::RDocTask.new(:rdoc) do |rdoc| + rdoc.rdoc_dir = 'rdoc' + rdoc.title = 'SmsFu' + rdoc.options << '--line-numbers' << '--inline-source' + rdoc.rdoc_files.include('README') + rdoc.rdoc_files.include('lib/**/*.rb') +end diff --git a/init.rb b/init.rb new file mode 100644 index 0000000..e049a35 --- /dev/null +++ b/init.rb @@ -0,0 +1,5 @@ +require File.dirname(__FILE__) + '/lib/mobilized_styles' +require File.dirname(__FILE__) + '/lib/mobile_fu' + +ActionView::Base.send(:include, MobilizedStyles) +ActionView::Base.send(:alias_method_chain, :stylesheet_link_tag, :mobilization) \ No newline at end of file diff --git a/install.rb b/install.rb new file mode 100644 index 0000000..e69de29 diff --git a/lib/mobile_fu.rb b/lib/mobile_fu.rb new file mode 100644 index 0000000..a24991e --- /dev/null +++ b/lib/mobile_fu.rb @@ -0,0 +1,89 @@ +module ActionController + module MobileFu + + # These are various strings that can be found in mobile devices. Please feel free + # to add on to this list. + + MOBILE_USER_AGENTS = 'palm|palmos|palmsource|iphone|blackberry|nokia|phone|midp|mobi|pda|' + + 'wap|java|nokia|hand|symbian|chtml|wml|ericsson|lg|audiovox|motorola|' + + 'samsung|sanyo|sharp|telit|tsm|mobile|mini|windows ce|smartphone|' + + '240x320|320x320|mobileexplorer|j2me|sgh|portable|sprint|vodafone' + + def self.included(base) + base.extend(ClassMethods) + end + + module ClassMethods + + # Add this to one of your controllers to use MobileFu. + # + # class ApplicationController < ActionController::Base + # has_mobile_fu + # end + # + # You can also force mobile mode by passing in 'true' + # + # class ApplicationController < ActionController::Base + # has_mobile_fu(true) + # end + + def has_mobile_fu(test_mode = false) + include ActionController::MobileFu::InstanceMethods + + if test_mode + before_filter :force_mobile_format + else + before_filter :set_mobile_format + end + + helper_method :is_mobile_device? + end + + def is_mobile_device? + @@is_mobile_device + end + + def in_mobile_view? + @@in_mobile_view + end + end + + module InstanceMethods + + # Forces the request format to be :mobile + + def force_mobile_format + request.format = :mobile + session[:mobile_view] = true if session[:mobile_view].nil? + 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. + + def set_mobile_format + if is_mobile_device? + request.format = session[:mobile_view] == false ? :html : :mobile + session[:mobile_view] = true if session[:mobile_view].nil? + end + end + + # Returns either true or false depending on whether or not the format of the + # request is either :mobile or not. + + def in_mobile_view? + request.format.to_sym == :mobile + 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. + + def is_mobile_device? + request.user_agent.to_s.downcase =~ Regexp.new(ActionController::MobileFu::MOBILE_USER_AGENTS) + end + end + + end + +end + +ActionController::Base.send(:include, ActionController::MobileFu) \ No newline at end of file diff --git a/lib/mobilized_styles.rb b/lib/mobilized_styles.rb new file mode 100644 index 0000000..a29ad15 --- /dev/null +++ b/lib/mobilized_styles.rb @@ -0,0 +1,45 @@ +module MobilizedStyles + + # This logic was taken from Michael Bleigh's browserized styles + # with modification to work for mobile browsers. + + def user_agent_device_name + @user_agent_device_name ||= begin + + ua = request.user_agent + return nil if ua.nil? + ua.downcase! + + if ua.index('mobileexplorer') || ua.index('windows ce') + 'mobileexplorer' + elsif ua.index('blackberry') + 'blackberry' + elsif ua.index('iphone') + 'iphone' + elsif ua.index('nokia') + 'nokia' + elsif ua.index('palm') + 'palm' + end + end + end + + def stylesheet_link_tag_with_mobilization(*sources) + mobilized_sources = Array.new + sources.each do |source| + subbed_source = source.to_s.gsub(".css","") + + possible_sources = ["#{subbed_source.to_s}_#{user_agent_device_name}"] + + mobilized_sources << source + + for possible_source in possible_sources + path = File.join(ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR,"#{possible_source}.css") + sass_path = File.join(ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR,"sass","#{possible_source}.sass") + mobilized_sources << possible_source if File.exist?(path) || File.exist?(sass_path) + end + end + + stylesheet_link_tag_without_mobilization(*mobilized_sources) + end +end \ No newline at end of file diff --git a/uninstall.rb b/uninstall.rb new file mode 100644 index 0000000..e69de29