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 +24 -1
- data/config/initializers/radiant_config.rb +6 -4
- data/lib/mobile_page.rb +33 -3
- data/lib/mobile_site_controller.rb +42 -16
- data/lib/radiant-mobile-extension.rb +3 -3
- data/spec/controllers/mobile_site_controller_spec.rb +66 -2
- data/spec/models/mobile_page_spec.rb +7 -0
- metadata +11 -10
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
|
-
|
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.
|
3
|
-
|
4
|
-
|
5
|
-
|
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
|
data/lib/mobile_page.rb
CHANGED
@@ -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
|
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'
|
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.
|
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.
|
3
|
-
SUMMARY = %q{Provide a mobile
|
4
|
-
DESCRIPTION = %q{This extension provides radius tags and a redirection mechanism that makes it
|
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
|
10
|
-
Radiant
|
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:
|
4
|
+
hash: 23
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 0.
|
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-
|
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
|
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.
|
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.
|
98
|
+
rubygems_version: 1.5.3
|
98
99
|
signing_key:
|
99
100
|
specification_version: 3
|
100
|
-
summary: Provide a mobile
|
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
|