radiant-mobile-extension 0.1.5 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -12,6 +12,29 @@ This very simple extension allows you to offer a cache-friendly mobile version o
12
12
 
13
13
  4. Use the radius tags `<r:if_mobile_>` and `<r:unless_mobile>` to make layout or content decisions based on whether this is a request for the mobile site.
14
14
 
15
+ ## Web views
16
+
17
+ Any request that whose address begins 'app.', or which matches the configured 'app.host' is considered to be a request from a smartphone app for a web view. Such requests will set the mobile flag and will also set an app flag, so you can use an additional `<r:if_app>` radius tag to distinguish such requests from normal mobile phone usage.
18
+
19
+ ## Configuration
20
+
21
+ You can set configuration entries to determine site addresses:
22
+
23
+ * `mobile.host` -> fully-specified mobile host name, eg m.spanner.org
24
+ * `app.host` -> fully-specified app host name
25
+
26
+ and to define the user-agent fragments that identify mobile (and non-mobile) devices:
27
+
28
+ * `mobile.ua.positives` -> comma-separated list of mobile UA markers like 'iphone,android,etc'
29
+ * `mobile.ua.negatives` -> comma-separated list of non-mobile UA markers like 'ipad'
30
+ * `mobile.ua.required` -> comma-separated list of UA markers that must be present to confirm mobileness
31
+
32
+ The logic of mobile device detection is this:
33
+
34
+ match any positive && not match any negatives && match any required
35
+
36
+ which allows us to pick a path through the messy and regrettable business of browser-sniffing with reasonable accuracy.
37
+
15
38
  ## Possibly AQ
16
39
 
17
40
  ### Why not just set :format (or use mobile-fu)?
@@ -77,7 +100,7 @@ With the `layouts` or `nested_layouts` extension you could create a simple layou
77
100
 
78
101
  ## Status
79
102
 
80
- Brand new and not well tested, but there's not much to it.
103
+ This has been in use for a couple of years without problems. The app-view part is new but ordinary: you should be able to use this extension with confidence.
81
104
 
82
105
  ## Bugs and comments
83
106
 
@@ -1,6 +1,8 @@
1
1
  Radiant.config do |config|
2
- config.namespace('mobile') do |mob|
3
- mob.define 'host', :allow_blank => true
4
- mob.define 'redirect?', :default => true
5
- end
2
+ config.define 'app.host', :allow_blank => true
3
+ config.define 'mobile.host', :allow_blank => true
4
+ config.define 'mobile.redirect?', :default => true
5
+ config.define 'mobile.ua.positive', :allow_blank => true, :default => "palm,blackberry,nokia,phone,midp,mobi,symbian,chtml,ericsson,minimo,audiovox,motorola,samsung,telit,upg1,windows,ce,ucweb,astel,plucker,x320,x240,j2me,sgh,portable,sprint,docomo,kddi,softbank,android,mmp,pdxgw,netfront,xiino,vodafone,portalmmm,sagem,mot-,sie-,ipod,webos,amoi,novarra,cdm,alcatel,pocket,iphone,mobileexplorer,mobile"
6
+ config.define 'mobile.ua.negative', :allow_blank => true, :default => "ipad"
7
+ config.define 'mobile.ua.required', :allow_blank => true, :default => "mobile"
6
8
  end
@@ -1,5 +1,5 @@
1
1
  module MobilePage
2
- attr_accessor :mobile
2
+ attr_accessor :mobile, :app
3
3
 
4
4
  # The extended site controller calls page.mobile = true if we are in a mobile context
5
5
  #
@@ -7,11 +7,18 @@ module MobilePage
7
7
  !!@mobile
8
8
  end
9
9
 
10
+ # The extended site controller calls page.mobile = true if we are in a mobile context
11
+ #
12
+ def app?
13
+ !!@app
14
+ end
15
+
10
16
  include Radiant::Taggable
11
17
 
12
18
  desc %{
13
19
  Expands if the url of the current request matches the host name defined in Radiant::Config['mobile.host'].
14
- (or if there is no such definition, if the domain begins with m.)
20
+ (or if there is no such definition, if the domain begins with m.) Note that if there is an app site then it will
21
+ also be considered mobile.
15
22
 
16
23
  *Usage:*
17
24
  <pre><code><r:if_mobile>...</r:if_mobile></code></pre>
@@ -22,7 +29,8 @@ module MobilePage
22
29
 
23
30
  desc %{
24
31
  Expands unless the url of the current request matches the host name defined in Radiant::Config['mobile.host'].
25
- (or if there is no such definition, unless it begins with m.)
32
+ (or if there is no such definition, unless it begins with m.) Note that if there is an app site then it will
33
+ also be considered mobile.
26
34
 
27
35
  *Usage:*
28
36
  <pre><code><r:unless_mobile>...</r:unless_mobile></code></pre>
@@ -31,4 +39,26 @@ module MobilePage
31
39
  tag.expand unless mobile?
32
40
  end
33
41
 
42
+ desc %{
43
+ Expands if the url of the current request matches the host name defined in Radiant::Config['app.host'].
44
+ (or if there is no such definition, if the domain begins with app.)
45
+
46
+ *Usage:*
47
+ <pre><code><r:if_app>...</r:if_app></code></pre>
48
+ }
49
+ tag 'if_app' do |tag|
50
+ tag.expand if app?
51
+ end
52
+
53
+ desc %{
54
+ Expands unless the url of the current request matches the host name defined in Radiant::Config['app.host'].
55
+ (or if there is no such definition, unless it begins with app.)
56
+
57
+ *Usage:*
58
+ <pre><code><r:unless_app>...</r:unless_app></code></pre>
59
+ }
60
+ tag 'unless_app' do |tag|
61
+ tag.expand unless app?
62
+ end
63
+
34
64
  end
@@ -4,40 +4,66 @@ module MobileSiteController
4
4
  # we can redirect to the corresponding page in a mobile site, and if we are on the mobile
5
5
  # site we set a flag on the page that radius tags can use to select content.
6
6
 
7
-
8
- # approach and UA strings borrowed from mobile-fu
9
- # http://github.com/brendanlim/mobile-fu/tree/master
10
- MOBILE_USER_AGENTS = 'palm|blackberry|nokia|phone|midp|mobi|symbian|chtml|ericsson|minimo|' +
11
- 'audiovox|motorola|samsung|telit|upg1|windows ce|ucweb|astel|plucker|' +
12
- 'x320|x240|j2me|sgh|portable|sprint|docomo|kddi|softbank|android|mmp|' +
13
- 'pdxgw|netfront|xiino|vodafone|portalmmm|sagem|mot-|sie-|ipod|up\\.b|' +
14
- 'webos|amoi|novarra|cdm|alcatel|pocket|iphone|mobileexplorer|' +
15
- 'mobile'
16
-
17
7
  # Returns true if the requested host matches the defined mobile host
18
8
  # (or in the absence of such a definition, if the host begins m.)
19
9
  #
20
10
  def mobile?
21
11
  mobile_host = Radiant.config['mobile.host']
22
- unless mobile_host.blank?
12
+ match = unless mobile_host.blank?
23
13
  request.host == mobile_host
24
14
  else
25
15
  request.host =~ /^m\./
26
16
  end
17
+ !!match
18
+ end
19
+
20
+ # Returns true if the requested host matches the defined app host
21
+ # (or in the absence of such a definition, if the host begins app.)
22
+ #
23
+ def app?
24
+ app_host = Radiant.config['app.host']
25
+ match = unless app_host.blank?
26
+ request.host == app_host
27
+ else
28
+ request.host =~ /^app\./
29
+ end
30
+ !!match
27
31
  end
28
32
 
29
- # Returns true if the request comes from a mobile device
30
- # (based on the supplied user-agent string)
33
+ # Returns true if the request comes from a mobile device (based on the supplied user-agent string)
31
34
  #
32
35
  def mobile_device?
33
- request.user_agent.to_s.downcase =~ Regexp.new(MobileSiteController::MOBILE_USER_AGENTS)
36
+ ua = request.user_agent.to_s.downcase
37
+ ua =~ Regexp.new(positive_markers.join('|')) && ua =~ Regexp.new(required_markers.join('|')) && ua !~ Regexp.new(negative_markers.join('|'))
38
+ end
39
+
40
+ # Returns the list of string fragments whose presence indicates that this is a mobile device.
41
+ # The default list (and the approach) is borrowed from mobile-fu: https://github.com/brendanlim/mobile-fu/blob/master/lib/mobile_fu.rb
42
+ #
43
+ def positive_markers
44
+ @positive_ua_markers ||= Radiant.config['mobile.ua.positive'].split(/,\s*/)
45
+ end
46
+
47
+ # Returns the list of string fragments whose presence indicates that this is a tablet and should not be treated as a mobile device.
48
+ # eg. Ipad UA includes 'mobile' (which in this context is a false positive) and also 'ipad' (which allows us to eliminate it).
49
+ #
50
+ def negative_markers
51
+ @negative_ua_markers ||= Radiant.config['mobile.ua.negative'].split(/,\s*/)
52
+ end
53
+
54
+ # Returns the list of string fragments that must be present or this is not a mobile device.
55
+ # eg. android tablet UA includes 'android' but not 'mobile', so we require the mobile flag.
56
+ #
57
+ def required_markers
58
+ @required_ua_markers ||= Radiant.config['mobile.ua.required'].split(/,\s*/)
34
59
  end
35
60
 
36
- # Extends the process_page method to place a 'mobile' flag in the page-rendering
61
+ # Extends the process_page method to place a 'mobile' and 'app' flags in the page-rendering
37
62
  # context to support presentation choices in radius tags.
38
63
  #
39
64
  def process_page_with_mobile(page)
40
- page.mobile = mobile?
65
+ page.app = app?
66
+ page.mobile = app? || mobile?
41
67
  process_page_without_mobile(page)
42
68
  end
43
69
 
@@ -1,7 +1,7 @@
1
1
  module RadiantMobileExtension
2
- VERSION = '0.1.5'
3
- SUMMARY = %q{Provide a mobile version of your radiant site with minimal reworking.}
4
- DESCRIPTION = %q{This extension provides radius tags and a redirection mechanism that makes it trivially simple to provide a mobile version of your site.}
2
+ VERSION = '0.2.0'
3
+ SUMMARY = %q{Provide a mobile and app versions of your radiant site from within one page tree, using radius tags to select content.}
4
+ DESCRIPTION = %q{This extension provides radius tags and a redirection mechanism that makes it simple to provide a mobile version of your site and to serve web views for use in mobile apps.}
5
5
  URL = "http://github.com/spanner/radiant-mobile-extension"
6
6
  AUTHORS = ["William Ross"]
7
7
  EMAIL = ["radiant@spanner.org"]
@@ -6,8 +6,11 @@ describe SiteController do
6
6
  before do
7
7
  @host = "m.test.host"
8
8
  @page = pages(:first)
9
- Radiant::Config['mobile.host'] = @host
10
- Radiant::Config['mobile.redirect?'] = true
9
+ Radiant.config['mobile.host'] = @host
10
+ Radiant.config['mobile.redirect?'] = true
11
+ Radiant.config['mobile.ua.positive'] = "palm,blackberry,nokia,phone,midp,mobi,symbian,chtml,ericsson,minimo,audiovox,motorola,samsung,telit,upg1,windows,ce,ucweb,astel,plucker,x320,x240,j2me,sgh,portable,sprint,docomo,kddi,softbank,android,mmp,pdxgw,netfront,xiino,vodafone,portalmmm,sagem,mot-,sie-,ipod,webos,amoi,novarra,cdm,alcatel,pocket,iphone,mobileexplorer,mobile"
12
+ Radiant.config['mobile.ua.negative'] = "ipad"
13
+ Radiant.config['mobile.ua.required'] = "mobile"
11
14
  end
12
15
 
13
16
  describe "responding to a mobile-site request" do
@@ -25,6 +28,23 @@ describe SiteController do
25
28
  get :show_page, :url => @page.url
26
29
  end
27
30
  end
31
+
32
+ describe "responding to an app-site request" do
33
+ before do
34
+ request.stub!(:host).and_return("app.test.host")
35
+ controller.stub!(:find_page).and_return(@page)
36
+ end
37
+
38
+ it "should notice that this is a request for the app site" do
39
+ controller.app?.should be_true
40
+ end
41
+
42
+ it "should set both the mobile and app flags on a processed page to true" do
43
+ @page.should_receive(:mobile=).with(true)
44
+ @page.should_receive(:app=).with(true)
45
+ get :show_page, :url => @page.url
46
+ end
47
+ end
28
48
 
29
49
  describe "responding to a standard-site request" do
30
50
  before do
@@ -41,6 +61,50 @@ describe SiteController do
41
61
  get :show_page, :url => @page.url
42
62
  end
43
63
 
64
+ describe "detecting devices:" do
65
+ describe "android phone" do
66
+ before do
67
+ request.stub!(:user_agent).and_return("Mozilla/5.0 (Linux; U; Android 2.2.1; en-us; Nexus One Build/FRG83) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1")
68
+ end
69
+ it "should be mobile" do
70
+ controller.mobile_device?.should be_true
71
+ end
72
+ end
73
+ describe "iphone" do
74
+ before do
75
+ request.stub!(:user_agent).and_return("Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en) AppleWebKit/420+ (KHTML, like Gecko) Version/3.0 Mobile/1C25 Safari/419.3")
76
+ end
77
+ it "should be mobile" do
78
+ controller.mobile_device?.should be_true
79
+ end
80
+ end
81
+ describe "android tablet" do
82
+ before do
83
+ request.stub!(:user_agent).and_return("Mozilla/5.0 (Linux; U; Android 2.2.1; en-us; device Build/FRG83) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Safari/533.1")
84
+ end
85
+ it "should not be mobile" do
86
+ controller.mobile_device?.should be_false
87
+ end
88
+ end
89
+ describe "ipad" do
90
+ before do
91
+ request.stub!(:user_agent).and_return("Mozilla/5.0 (iPad; U; CPU OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B334b Safari/531.21.10")
92
+ end
93
+ it "should not be mobile" do
94
+ controller.mobile_device?.should be_false
95
+ end
96
+ end
97
+ describe "with configured ua fragments" do
98
+ before do
99
+ Radiant.config['mobile.ua.positive'] = 'foo,bar,baz'
100
+ request.stub!(:user_agent).and_return("Mozilla/5.0 (Foo) Mobile")
101
+ end
102
+ it "should be mobile" do
103
+ controller.mobile_device?.should be_true
104
+ end
105
+ end
106
+ end
107
+
44
108
  describe "from a mobile device" do
45
109
  before do
46
110
  controller.stub!(:mobile_device?).and_return(true)
@@ -11,4 +11,11 @@ describe Page do
11
11
  page.mobile.should be_true
12
12
  page.mobile?.should be_true
13
13
  end
14
+
15
+ it "should get and set an app? attribute" do
16
+ page.app?.should be_false
17
+ lambda{ page.app = true }.should_not raise_error
18
+ page.app.should be_true
19
+ page.app?.should be_true
20
+ end
14
21
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: radiant-mobile-extension
3
3
  version: !ruby/object:Gem::Version
4
- hash: 17
4
+ hash: 23
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
- - 1
9
- - 5
10
- version: 0.1.5
8
+ - 2
9
+ - 0
10
+ version: 0.2.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - William Ross
@@ -15,7 +15,8 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-10-13 00:00:00 Z
18
+ date: 2011-10-20 00:00:00 +01:00
19
+ default_executable:
19
20
  dependencies:
20
21
  - !ruby/object:Gem::Dependency
21
22
  name: paperclip
@@ -33,7 +34,7 @@ dependencies:
33
34
  version: 2.3.16
34
35
  type: :runtime
35
36
  version_requirements: *id001
36
- description: This extension provides radius tags and a redirection mechanism that makes it trivially simple to provide a mobile version of your site.
37
+ description: This extension provides radius tags and a redirection mechanism that makes it simple to provide a mobile version of your site and to serve web views for use in mobile apps.
37
38
  email:
38
39
  - radiant@spanner.org
39
40
  executables: []
@@ -56,7 +57,6 @@ files:
56
57
  - lib/radiant-mobile-extension.rb
57
58
  - lib/tasks/mobile_extension_tasks.rake
58
59
  - mobile_extension.rb
59
- - radiant-mobile-extension-0.1.5.gem
60
60
  - radiant-mobile-extension.gemspec
61
61
  - Rakefile
62
62
  - README.md
@@ -65,10 +65,11 @@ files:
65
65
  - spec/spec.opts
66
66
  - spec/spec_helper.rb
67
67
  - VERSION
68
+ has_rdoc: true
68
69
  homepage: http://github.com/spanner/radiant-mobile-extension
69
70
  licenses: []
70
71
 
71
- post_install_message: "\n Add this to your radiant project with a line in your Gemfile:\n\n gem 'radiant-mobile-extension', '~> 0.1.5'\n\n "
72
+ post_install_message: "\n Add this to your radiant project with a line in your Gemfile:\n\n gem 'radiant-mobile-extension', '~> 0.2.0'\n\n "
72
73
  rdoc_options: []
73
74
 
74
75
  require_paths:
@@ -94,10 +95,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
94
95
  requirements: []
95
96
 
96
97
  rubyforge_project:
97
- rubygems_version: 1.8.10
98
+ rubygems_version: 1.5.3
98
99
  signing_key:
99
100
  specification_version: 3
100
- summary: Provide a mobile version of your radiant site with minimal reworking.
101
+ summary: Provide a mobile and app versions of your radiant site from within one page tree, using radius tags to select content.
101
102
  test_files:
102
103
  - spec/controllers/mobile_site_controller_spec.rb
103
104
  - spec/models/mobile_page_spec.rb