Permalink
Browse files

initial version

  • Loading branch information...
1 parent acd6715 commit 7eff97ca1177c42c6857140d114c20cc125787fd @kristianmandrup committed Apr 5, 2012
View
@@ -28,7 +28,7 @@ pkg
#
# For MacOS:
#
-#.DS_Store
+.DS_Store
# For TextMate
#*.tmproj
View
15 Gemfile
@@ -1,14 +1,11 @@
-source "http://rubygems.org"
-# Add dependencies required to use your gem here.
-# Example:
-# gem "activesupport", ">= 2.3.5"
+source :rubygems
# Add dependencies to develop your gem here.
# Include everything needed to run rake, tests, features, etc.
group :development do
- gem "rspec", "~> 2.8.0"
- gem "rdoc", "~> 3.12"
- gem "bundler", "~> 1.0.0"
- gem "jeweler", "~> 1.8.3"
- gem "rcov", ">= 0"
+ gem "rspec", "~> 2.9.0"
+ gem "rdoc", "~> 3.12"
+ gem "bundler", "~> 1.1.0"
+ gem "jeweler", ">= 1.8.3"
+ gem "simplecov",">= 0.5"
end
View
@@ -0,0 +1,37 @@
+GEM
+ remote: http://rubygems.org/
+ specs:
+ diff-lcs (1.1.3)
+ git (1.2.5)
+ jeweler (1.8.3)
+ bundler (~> 1.0)
+ git (>= 1.2.5)
+ rake
+ rdoc
+ json (1.6.6)
+ multi_json (1.2.0)
+ rake (0.9.2.2)
+ rdoc (3.12)
+ json (~> 1.4)
+ rspec (2.9.0)
+ rspec-core (~> 2.9.0)
+ rspec-expectations (~> 2.9.0)
+ rspec-mocks (~> 2.9.0)
+ rspec-core (2.9.0)
+ rspec-expectations (2.9.1)
+ diff-lcs (~> 1.1.3)
+ rspec-mocks (2.9.0)
+ simplecov (0.6.1)
+ multi_json (~> 1.0)
+ simplecov-html (~> 0.5.3)
+ simplecov-html (0.5.3)
+
+PLATFORMS
+ ruby
+
+DEPENDENCIES
+ bundler (~> 1.1.0)
+ jeweler (>= 1.8.3)
+ rdoc (~> 3.12)
+ rspec (~> 2.9.0)
+ simplecov (>= 0.5)
View
@@ -1,6 +1,39 @@
-= mobile_view_paths
+= Mobile view paths for Rails
-Description goes here.
+Based on http://erniemiller.org/2011/01/05/mobile-devices-and-rails-maintaining-your-sanity/
+
+First, let’s set up our mobile app at m.mydomain.com. Requests made to the “m” subdomain will use our mobile templates, if they exist. Once we have that working, we’ll handle user agent detection and allow toggling between the mobile and full version of our app (because sites that don’t allow you to get at the full version even when your device is capable of rendering it are downright rude).
+
+=== View Paths
+
+When Rails sets out to render one of our templates it looks for them in our controller’s array of view paths. Normally, this is going to contain app/views. View paths work much like the $PATH environment variable in your shell. If you type a command into your shell, your system goes through the directories listed in your $PATH, in order, and runs the first executable of the given name that it finds. Similarly, if Rails wants to render the action for widgets/index, it goes through your view paths in order, looking for a suitable candidate. If it finds app/views/widgets/index.html.erb, it will stop looking and render this file.
+
+This means that if we prepend app/mobile_views to the array of view paths, we can place our custom mobile view for our widget index into app/mobile_views/widgets/index.html.erb. When Rails finds this file, it won’t bother looking in app/views for our default template. However, if we don’t bother creating an app/mobile_views/widgets/show.html.erb file, we can fall back to using the one in app/views. Laziness satisfied!
+
+=== Prepending our Mobile View Path
+
+We can connect to m.mydomain.com (assuming our server is properly configured — I’d suggest ghosting m.[yourhostname].local if you’re testing locally on OS X) and our app will render from app/mobile_views before falling back to the standard app/views.
+
+We’re going to check if a user has specifically requested the mobile or full site in set_mobile_preferences, and if the user’s asked for the full site, we’ll store a “permanent” cookie that says so — this way the next time they visit our application from this device, they’ll immediately be in their preferred viewing format, because the next filter, redirect_to_mobile_if_applicable, only redirects if the request isn’t already being made to m.mydomain.com, the user hasn’t previously stored a cookie that says they’d like the full site, and the user agent appears to be a browser we’d like to redirect to the mobile site. You may want to season your mobile_browser? method to taste. The one I used here works well for my needs.
+
+The only thing that remains is to place a link allowing the mobile user to toggle between sites.
+
+=== View helpers
+
+The following view helpers are made available for switching site
+
+To insert link to the full site
+
+ <%= link_to_mobile_site %>
+
+And to link to the full site (only from mobile)
+
+ <%= link_to_full_site %>
+
+Translation keys: "app.view_mobile_site" and "app.view_full_site" respectively (for localization)
+Or you can explicitly set the label to use (takes any html).
+
+ <%= link_to_full_site 'Link to the big site' %>
== Contributing to mobile_view_paths
View
@@ -1 +1 @@
-0.0.0
+0.1.0
View
@@ -0,0 +1,3 @@
+require 'mobile_view_paths/mobile_view_path_controller'
+require 'mobile_view_paths/view_helper'
+require 'mobile_view_paths/engine' if defined?(::Rails::Engine)
@@ -0,0 +1,9 @@
+module MobileViewPaths
+ module Rails
+ module Engine < ::Rails::Engine
+ initializer 'setup rails' do
+ ActionView::Base.send :include, MobileViewPaths::DeviseSwitchHelper
+ end
+ end
+ end
+end
@@ -0,0 +1,50 @@
+class MobileViewPathController < ActionController::Base
+ before_filter :set_mobile_preferences
+ before_filter :redirect_to_mobile_if_applicable
+ before_filter :prepend_view_path_if_mobile
+
+ private
+
+ def set_mobile_preferences
+ if params[:mobile_site]
+ cookies.delete(:prefer_full_site)
+ elsif params[:full_site]
+ cookies.permanent[:prefer_full_site] = 1
+ redirect_to_full_site if mobile_request?
+ end
+ end
+
+ def prepend_view_path_if_mobile
+ if mobile_request?
+ mobile_path = Rails.root.join("app", "views_mobile")
+ p = Pathname.new(mobile_path)
+ controller_path.split('/').each do |a|
+ p = p + a
+ end
+ p = p.join(action_name + ".html.erb")
+ prepend_view_path(mobile_path) if File.exists?(p)
+ end
+ end
+
+ def redirect_to_full_site
+ redirect_to request.protocol + request.host_with_port.gsub(/^m\./, '') +
+ request.request_uri.gsub(/\?full_site=1/, '') and return
+ end
+
+ def redirect_to_mobile_if_applicable
+ unless mobile_request? || cookies[:prefer_full_site] || !mobile_browser?
+ redirect_to request.protocol + "m." + request.host_with_port.gsub(/^www\./, '') +
+ request.request_uri and return
+ end
+ end
+
+ def mobile_request?
+ request.subdomains.first == 'm'
+ end
+ helper_method :mobile_request?
+
+ def mobile_browser?
+ request.env["HTTP_USER_AGENT"] && request.env["HTTP_USER_AGENT"][/(iPhone|iPod|iPad|Android)/]
+ end
+ helper_method :mobile_browser?
+end
@@ -0,0 +1,13 @@
+module MobileViewPaths
+ module DeviseSwitchHelper
+ def link_to_mobile_site label
+ label = t("app.view_mobile_site") || label.html_safe
+ link_to label, url_for(:mobile_site => 1) if mobile_browser?
+ end
+
+ def link_to_full_site label
+ label = t("app.view_full_site") || label.html_safe
+ link_to label, url_for(:full_site => 1)
+ end
+ end
+end

0 comments on commit 7eff97c

Please sign in to comment.