Permalink
Browse files

Handle mobile site redirection and caching

* Support mobile and full site cache directories (based on subdomain)
* Define helpers for toggling between full/mobile site
* Allow cmsadmins to view pages using mobile templates (?template=mobile)
  • Loading branch information...
1 parent f3f20ac commit 5402aea7e514c2ee2a1be183ff45a1dac9ca2ea6 @peakpg peakpg committed Feb 8, 2012
View
@@ -1,3 +1,4 @@
+.powder
.idea
coverage/**/*
.DS_Store
View
@@ -3,35 +3,30 @@
## Features (Completed)
* Developers can define a mobile template for any existing .html.erb template on a project. These template are named the same as the existing templates, but are placed in a separate layouts/mobile directory.
-* Editors always see the desktop template
+* Editors always see the desktop template, unless they add a ?template=mobile parameter to the URL of the page they are viewing.
* Mobile assumes a m. subdomain will exist. It will return the mobile template for all requests to pages on that domain.
* If page uses a template which has no mobile counterpart, it will display using its normal template.
+* Agent Redirection: Users on mobile devices can be automatically redirected to the m. site. (Handled via Apache User Agent detection.)
+* Mobile Site Opt Out: Users on mobile device can opt to be redirected to the desktop site if they want. (Handled via a cookie)
+* Mobile caching: The mobile and full sites have their own separate page cache, mean both can be served quickly by Apache.
-Caveats:
-* Doesn't work with cached pages.
-* We are no longer relying on Agent Detection. Visitors on mobile device, who request a page that has a mobile template on the main site will see the full content of the page.
## Issues
-* Not 100% sure why admins ALWAYS see the desktop template (even when viewing as mobile). Probably related to how ContentController stack changes.
+* Can developers toggle between m. and www. locally without setting up POW?
+* Is two weeks long enough for the full site preference?
+* Can they test mobile remotely?
-## Features (Possible)
-1. Extract cucumber-browsercms project (to reduce required setup)
-1. On m.domain.com
-1. Allow user to set a preference for mobile vs full site.
+## Things to improve
+* The Apache conf file has way too much logic in it. Specifically, the device types and matching rules really can't be tested, at all. We also have to have a 3rd virtual host for the m. site which isn't so hot.
-Implementation Details
-
-* If there is no .mobile view, it will use the .html layout even if there is a .mobile template. The view itself needs to be defined as .mobile.
-* If templatename.mobile exists, it should use that. Otherwise, fall back to .html without complaining.
-
-## m.subdomain
-* Rails application would have to handle redirecting to m. based on user preference or User Agent
-* Redirection within Rails will not work due to caching (Request would cache HTML and never make it to Rails)
-* User preferences could be handled via a permanent cookie.
+## Installation
+* Add a MOBILE_SITE_DOMAIN to your development and production environments.
+* Add Full and Mobile links to templates. Sometimes mobile users really want to see the full site, so make sure they are conveniently placed on both mobile and full templates.
+* Configure the mobile and full site cache locations
# Resources
@@ -45,10 +40,22 @@ http://ryanbigg.com/2009/04/how-rails-works-2-mime-types-respond_to/
http://blog.bigbinary.com/2010/11/23/mime-type-resolution-in-rails.html
Verify if views exist - http://stackoverflow.com/questions/2853355/check-if-a-layout-exists-in-rails
+Excellent Cookie Setting solution for Apache: http://www.phillipadsmith.com/2011/11/note-to-self-a-simple-way-to-accomplish-mobile-site-redirection-using-mod-rewrite.html
+Modern Mobile Detection - http://ohryan.ca/blog/2011/01/21/modern-mobile-redirect-using-htaccess/
+Using Apache for User Agent/Detection - http://mobiledrupal.com/simple-apache-configuration-file-mobile-device-detection
+http://ohryan.ca/blog/2011/01/21/modern-mobile-redirect-using-htaccess/
+
## Development
To really test this, you will need to setup POW or some other solution that can handle the multiple subdomains, i.e.
m.bcms-mobile.dev
www.bcms-mobile.dev
-cms.bcms-mobile.dev
+cms.bcms-mobile.dev
+
+## Alternative Plan - Use Passenger/Apache
+
+To get configuration right, need Apache/Passenger so you can fool around with Apache specific rewrite rules. See these instructions for setting up Passenger on OSX.
+
+- http://www.robbyonrails.com/articles/2009/02/11/switch-to-passenger-mod_rails-in-development-on-osx-in-less-than-7-minutes-or-your-money-back
+- http://www.fngtps.com/2008/using-passenger-on-osx-for-rails-development/
@@ -8,7 +8,7 @@
<body style="margin: 0; padding: 0; text-align: center;">
<%= cms_toolbar %>
<div id="wrapper" style="width: 700px; margin: 0 auto; text-align: left; padding: 30px">
- I am a stripped down MOBILE template.
+ I am a stripped down MOBILE template. I want to see the <%= link_to " 'Full Site'", full_site_url %>
<h1><%= page_title %></h1>
<%= container :main %>
</div>
@@ -8,7 +8,8 @@
<body style="margin: 0; padding: 0; text-align: center;">
<%= cms_toolbar %>
<div id="wrapper" style="width: 700px; margin: 0 auto; text-align: left; padding: 30px">
- I am the desktop TEMPLATE.
+ I am the desktop TEMPLATE. I want to see the <%= link_to " 'Mobile Site'", mobile_site_url %>
+
User Agent '<%= request.user_agent %>'
<%= render_menu %>
<h1><%= page_title %></h1>
@@ -1,4 +1,7 @@
-SITE_DOMAIN="localhost:3000"
+SITE_DOMAIN="www.mobile.local"
+MOBILE_SITE_DOMAIN="m.mobile.local"
+
+
BcmsMobile::Application.configure do
# Settings specified here will take precedence over those in config/application.rb
@@ -1,4 +1,6 @@
-SITE_DOMAIN="localhost:3000"
+SITE_DOMAIN="www.mobile.local"
+MOBILE_SITE_DOMAIN="m.mobile.local"
+
BcmsMobile::Application.configure do
config.action_controller.page_cache_directory = File.join(Rails.root, 'public', 'cache')
# Settings specified here will take precedence over those in config/application.rb
@@ -0,0 +1,12 @@
+# TODO: Can be removed after updating to rack 1.3.0
+# Avoids: http://stackoverflow.com/questions/3622394/ruby-1-9-2-strange-warning-when-running-cucumber-specs
+module Rack
+ module Utils
+ def escape(s)
+ CGI.escape(s.to_s)
+ end
+ def unescape(s)
+ CGI.unescape(s)
+ end
+ end
+end
View
@@ -1,10 +1,4 @@
BcmsMobile::Application.routes.draw do
- resources :widgets
-
- resources :desktop_products
-
- resources :products
-
routes_for_bcms_mobile
routes_for_browser_cms
@@ -26,5 +26,15 @@ Feature:
When they request /not-mobile
Then they should see the desktop content
+ Scenario: Editors can see mobile version of page
+ Given a cms editor is logged in
+ When they request /mobile-page
+ Then they should see the desktop content
+ When they request /mobile-page?template=mobile
+ Then they should see the mobile template
+ Scenario: Guests can't request mobile versions of page
+ Given a user is browsing the desktop site
+ When they request /mobile-page?template=mobile
+ Then they should see the desktop content
@@ -50,3 +50,10 @@
When /^they are using an iPhone$/ do
request_as_iphone
end
+
+Given /^a cms editor is logged in$/ do
+ visit '/cms/login'
+ fill_in 'login', :with=>'cmsadmin'
+ fill_in 'password', :with=>'cmsadmin'
+ click_button 'LOGIN'
+end
View
@@ -7,10 +7,15 @@ class Engine < Rails::Engine
include Cms::Module
config.to_prepare do
+ ApplicationHelper.class_eval do
+ include BcmsMobile::MobileHelpers
+ end
+
Cms::ContentController.class_eval do
include BcmsMobile::MobileAware
before_filter :print_request_info
+ before_filter :configure_cache_directory
def print_request_info
w "*" * 20
@@ -27,10 +32,19 @@ def print_request_info
w "Mime::Type: :#{mime_type.symbol}" if mime_type
end
+ def configure_cache_directory
+ if respond_as_mobile?
+ self.class.page_cache_directory = File.join(Rails.root, 'public', 'mobile_cache')
+ else
+ self.class.page_cache_directory = File.join(Rails.root, 'public', 'cache')
+ end
+ end
+
# Because of caching, CMS pages should only return mobile content on a separate subdomain.
+ # or if a CMS editor wants to see the mobile version of the page.
def respond_as_mobile?
w "Checking the subdomain for #{request.domain} is #{request.subdomain}"
- request.subdomain == "m"
+ request.subdomain == "m" || (params[:template] =='mobile' && current_user.able_to?(:edit_content))
end
private
@@ -40,9 +54,7 @@ def render_page
@_page_route.execute(self) if @_page_route
prepare_connectables_for_render
-
template = determine_page_template
-
render :layout => template, :action => 'show'
end
@@ -1,4 +1,16 @@
module BcmsMobile
+
+ module MobileHelpers
+
+ def full_site_url
+ url_for(:host=>SITE_DOMAIN, :prefer_full_site=>true)
+ end
+
+ def mobile_site_url
+ url_for(:host=>SITE_DOMAIN, :prefer_mobile_site=>true)
+ end
+ end
+
module MobileAware
def w(m)

0 comments on commit 5402aea

Please sign in to comment.