radiant-mobile-extension 0.1.5 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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