wapl 0.1
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/MIT-LICENSE +20 -0
- data/Manifest +13 -0
- data/README.md +130 -0
- data/Rakefile +33 -0
- data/init.rb +1 -0
- data/install.rb +1 -0
- data/lib/wapl.rb +110 -0
- data/lib/wapl_helper.rb +178 -0
- data/tasks/wapl_tasks.rake +4 -0
- data/test/test_helper.rb +4 -0
- data/test/test_wapl.rb +66 -0
- data/test/test_wapl_helper.rb +84 -0
- data/uninstall.rb +1 -0
- data/wapl.gemspec +31 -0
- metadata +78 -0
data/MIT-LICENSE
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Copyright (c) 2009 [name of plugin creator]
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
4
|
+
a copy of this software and associated documentation files (the
|
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
9
|
+
the following conditions:
|
|
10
|
+
|
|
11
|
+
The above copyright notice and this permission notice shall be
|
|
12
|
+
included in all copies or substantial portions of the Software.
|
|
13
|
+
|
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Manifest
ADDED
data/README.md
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
# Wapple Architect plugin/library
|
|
2
|
+
|
|
3
|
+
This package contains a class which enables web developers to stop worrying about handling non-desktop browsers.
|
|
4
|
+
|
|
5
|
+
By utilizing [Wapple's](http://wapple.net) API for device detection and the [WAPL markup language](http://wapl.info) the websites can be adjusted, rendered and delivered properly to any device.
|
|
6
|
+
|
|
7
|
+
The package consists of API communication class and a view helper which makes it dead easy to create mobile friendly sites while retaining your standard, "big" version of your webapp untouched.
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
## The flow
|
|
11
|
+
1. A device hits your site
|
|
12
|
+
1. Do an API call to detect whether it's a mobile device or not (it's much more sophisticated than simple UA sniffing)
|
|
13
|
+
1. Store the result in the session
|
|
14
|
+
1. If it's mobile device (you will get to know the model and the maker!) build your view using wapl-helper
|
|
15
|
+
1. Do an API call to get the appropriate markup for the device
|
|
16
|
+
1. Profit
|
|
17
|
+
|
|
18
|
+
Wapple Architect preserves your url structure, your SEO and what-not.
|
|
19
|
+
|
|
20
|
+
## TODO
|
|
21
|
+
|
|
22
|
+
- wapl markup helper
|
|
23
|
+
- more docs
|
|
24
|
+
- sinatra example app
|
|
25
|
+
|
|
26
|
+
## Examples
|
|
27
|
+
### Rails
|
|
28
|
+
|
|
29
|
+
*application controller*
|
|
30
|
+
|
|
31
|
+
require 'wapl'
|
|
32
|
+
class ApplicationController < ActionController::Base
|
|
33
|
+
helper :all # include all helpers, all the time
|
|
34
|
+
def detect_mobile
|
|
35
|
+
# get an instance of Wapl class, use your dev key and pas through your headers
|
|
36
|
+
@wapl = Wapl.new "YOUR DEV KEY HERE", request.env
|
|
37
|
+
# check whether the device is a mobile device
|
|
38
|
+
# it's good to save this result in the session
|
|
39
|
+
@is_mobile = @wapl.is_mobile_device
|
|
40
|
+
|
|
41
|
+
# does pretty much the same thing, but als o gets the info about the device
|
|
42
|
+
@device_data = @wapl.get_mobile_device
|
|
43
|
+
end
|
|
44
|
+
def render_for_mobile
|
|
45
|
+
# grab the view dedicated for mobile
|
|
46
|
+
wapl_xml = render_to_string(:layout => 'wapl', :template => controller_name+'/wapl/'+action_name)
|
|
47
|
+
logger.info wapl_xml
|
|
48
|
+
# send the WAPL xml
|
|
49
|
+
resp = @wapl.get_markup_from_wapl wapl_xml
|
|
50
|
+
# get the final markup from the response
|
|
51
|
+
@markup = resp['markup'].to_s
|
|
52
|
+
# use the apropriate headers as well
|
|
53
|
+
resp['headers'].each { |k,v| response.headers[k] = v }
|
|
54
|
+
# render the stuff
|
|
55
|
+
render :inline => @markup
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
*controller* (test controller)
|
|
60
|
+
|
|
61
|
+
require 'wapl'
|
|
62
|
+
class TestController < ApplicationController
|
|
63
|
+
# set up
|
|
64
|
+
before_filter :detect_mobile, :render_for_mobile
|
|
65
|
+
def index
|
|
66
|
+
# check whether the device is mobile, if so - render appropriate stuff
|
|
67
|
+
if @is_mobile.to_i == 1
|
|
68
|
+
self.render_for_mobile
|
|
69
|
+
return
|
|
70
|
+
end
|
|
71
|
+
# proceed as usual
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
*view* (app/views/test/wapl/index.erb) (can be anywhere you want, but it's good to keep them in one place)
|
|
75
|
+
|
|
76
|
+
<easyChars>
|
|
77
|
+
<value>Your mobile phone is: </value>
|
|
78
|
+
</easyChars>
|
|
79
|
+
<% for info in @device_data %>
|
|
80
|
+
<easyChars make_safe="1">
|
|
81
|
+
<value>[b]<%= info[0] %>[/b]: <%= info[1] %></value>
|
|
82
|
+
</easyChars>
|
|
83
|
+
<% end %>
|
|
84
|
+
|
|
85
|
+
*layout*
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
<?xml version="1.0" encoding="UTF-8" ?>
|
|
89
|
+
<wapl xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://wapl.wapple.net/wapl.xsd">
|
|
90
|
+
<head>
|
|
91
|
+
<title>your mobile title</title>
|
|
92
|
+
</head>
|
|
93
|
+
<layout>
|
|
94
|
+
<%= yield %>
|
|
95
|
+
</layout>
|
|
96
|
+
</wapl>
|
|
97
|
+
|
|
98
|
+
And... That's it.
|
|
99
|
+
|
|
100
|
+
## Helper Example
|
|
101
|
+
|
|
102
|
+
You can use the WaplHelper, it's included now in the plugin.
|
|
103
|
+
For more information about WAPL markup refer to the [official docs](http://wapl.info/coding-for-the-mobile-web-with-WAPL/chapter/Developing-with-WAPL/).
|
|
104
|
+
|
|
105
|
+
It's still in development, but it's pretty usable :-)
|
|
106
|
+
|
|
107
|
+
<%= chars('wowza!') %>
|
|
108
|
+
<%= chars('[b]elo[/b]',{ :attributes =>{ 'make_safe'=>'false' }, :cell=>{ "class" => "test"}, :row=>{:id=>'duzy'}}) %>
|
|
109
|
+
<%= chars('[b]elo[/b]',{ :attributes =>{ 'make_safe'=>'false' }}) %>
|
|
110
|
+
<%= external_image('http://wapl.info/img/header_wapple.png') %>
|
|
111
|
+
<%= external_image('http://wapl.info/img/header_wapple.png', { :attributes=>{ :file_type => "png", :scale =>"150"} }) %>
|
|
112
|
+
<%= external_image('http://wapl.info/img/header_wapple.png' , { :children => { :safe_mode => "1"}}) %>
|
|
113
|
+
<%= external_image('http://wapl.info/img/header_wapple.png') %>
|
|
114
|
+
<%= external_link("Google", 'http://google.com') %>
|
|
115
|
+
<%= external_link("Google", "http://google.com", { :attributes => { :id => "wgp"}, :image => { :url => "http://wapl.info/img/header_wapple.png"}} ) %>
|
|
116
|
+
<%= external_link("Google", "http://google.com", { :attributes => { :id => "woop"} }) %>
|
|
117
|
+
<%= external_link("Google", "http://google.com", { :attributes => { :id => "woop"} }) %>
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
Or you can go one level deeper and use just the helper methods (not recommended):
|
|
121
|
+
|
|
122
|
+
<% ch = tag('chars', tag('value', "TEST")) %>
|
|
123
|
+
<%= row_cell(ch) %>
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
More examples and stuff to come - watch this space!
|
|
127
|
+
|
|
128
|
+
http://gist.github.com/272164
|
|
129
|
+
|
|
130
|
+
_Copyright (c) 2009 Łukasz Korecki, released under the MIT license_
|
data/Rakefile
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
require 'rake'
|
|
2
|
+
require 'rake/testtask'
|
|
3
|
+
require 'rake/rdoctask'
|
|
4
|
+
|
|
5
|
+
require 'echoe'
|
|
6
|
+
|
|
7
|
+
desc 'Default: run unit tests.'
|
|
8
|
+
task :default => :test
|
|
9
|
+
|
|
10
|
+
desc 'Test the wapl plugin.'
|
|
11
|
+
Rake::TestTask.new(:test) do |t|
|
|
12
|
+
t.libs << 'lib'
|
|
13
|
+
t.libs << 'test'
|
|
14
|
+
t.pattern = 'test/**/test_*.rb'
|
|
15
|
+
t.verbose = true
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
desc 'Generate documentation for the wapl plugin.'
|
|
19
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
|
20
|
+
rdoc.rdoc_dir = 'rdoc'
|
|
21
|
+
rdoc.title = 'Wapl'
|
|
22
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
|
23
|
+
rdoc.rdoc_files.include('README')
|
|
24
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
Echoe.new('wapl', '0.1') do |p|
|
|
28
|
+
p.description = "Library and helper for communicating with Wapple.net Architect web service, more information: http://wapl.info"
|
|
29
|
+
p.url = "http://github.com/plugawy/wapl"
|
|
30
|
+
p.author = "Lukasz Korecki"
|
|
31
|
+
p.email = "lukasz@coffeesounds.com"
|
|
32
|
+
p.development_dependencies= []
|
|
33
|
+
end
|
data/init.rb
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ActionView::Base.send :include, WaplHelper
|
data/install.rb
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# Install hook code here
|
data/lib/wapl.rb
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
require 'net/http'
|
|
2
|
+
require 'uri'
|
|
3
|
+
require 'rexml/document'
|
|
4
|
+
# This Class is responsible for communicating with Wapple Mobile Api
|
|
5
|
+
# It enables the programmer to completelty mobilize an existing web app
|
|
6
|
+
# Without breaking it :-)
|
|
7
|
+
# for more info about Wapple Architect please go to http://wapl.info
|
|
8
|
+
class Wapl
|
|
9
|
+
attr_accessor :dev_key, :header_string
|
|
10
|
+
# api root
|
|
11
|
+
@@api_root = "http://webservices.wapple.net"
|
|
12
|
+
def self.api_root
|
|
13
|
+
@@api_root
|
|
14
|
+
end
|
|
15
|
+
# RESTy resources
|
|
16
|
+
@@resources = {
|
|
17
|
+
"is_mobile_device" =>"/isMobileDevice.php",
|
|
18
|
+
"get_mobile_device" =>"/getMobileDevice.php",
|
|
19
|
+
"get_markup_from_wapl" =>"/getMarkupFromWapl.php",
|
|
20
|
+
"get_markup_from_url" =>"/getMarkupFromUrl.php"
|
|
21
|
+
}
|
|
22
|
+
def self.resources
|
|
23
|
+
@@resources
|
|
24
|
+
end
|
|
25
|
+
# the constructor
|
|
26
|
+
# Required parameters
|
|
27
|
+
# arch_dev_key:: Your Architect dev key
|
|
28
|
+
# headers:: headers for the request - for rails that would be request.env
|
|
29
|
+
# Returns a new instance of Wapl
|
|
30
|
+
def initialize(arch_dev_key = "", headers = {})
|
|
31
|
+
@dev_key= arch_dev_key
|
|
32
|
+
@header_string = self.parse_headers(headers)
|
|
33
|
+
@api_root="http://webservices.wapple.net"
|
|
34
|
+
end
|
|
35
|
+
def set_headers(headers)
|
|
36
|
+
@header_string = self.parse_headers(headers)
|
|
37
|
+
end
|
|
38
|
+
# Parses the request headers and gets only HTTP_* headers
|
|
39
|
+
# returns properly formatted string of keys and values
|
|
40
|
+
def parse_headers(headers_hash)
|
|
41
|
+
header_string = ""
|
|
42
|
+
for header in headers_hash.select { |k,v| k.match("^HTTP.*") } do
|
|
43
|
+
header_string += header[0]+":"+header[1]+"|"
|
|
44
|
+
end
|
|
45
|
+
return header_string
|
|
46
|
+
end
|
|
47
|
+
# Communicates with the API
|
|
48
|
+
# Does a simple POST call with required arguments
|
|
49
|
+
# Always sends the dev_key and the headers
|
|
50
|
+
# path:: path to the API resource
|
|
51
|
+
# arg:: hash containing additional arguments (see wapl.info docs)
|
|
52
|
+
# Returns HTTP::result object
|
|
53
|
+
def send_request(path,arg = {})
|
|
54
|
+
url= URI.parse(@@api_root + @@resources[path].to_s)
|
|
55
|
+
post_arg = {'devKey'=>@dev_key , 'headers'=>@header_string }
|
|
56
|
+
post_arg.merge!(arg)
|
|
57
|
+
res = Net::HTTP.post_form(url, post_arg)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# gets the info about mobile device
|
|
61
|
+
# Returns a Hash containing information model and the maker
|
|
62
|
+
def get_mobile_device()
|
|
63
|
+
res = self.send_request 'get_mobile_device'
|
|
64
|
+
device_info_xml = REXML::Document.new(res.body).root
|
|
65
|
+
rez ={}
|
|
66
|
+
device_info_xml.elements.each do |el|
|
|
67
|
+
rez.merge! Hash[el.name.to_s,el.text.to_s]
|
|
68
|
+
end
|
|
69
|
+
return rez
|
|
70
|
+
end
|
|
71
|
+
# checks whether the device is mobile
|
|
72
|
+
# Returns 1 for true and 0 for a desktop browser
|
|
73
|
+
def is_mobile_device()
|
|
74
|
+
res = self.send_request 'is_mobile_device'
|
|
75
|
+
return res.body
|
|
76
|
+
end
|
|
77
|
+
# Submits the wapl markup along with the headers
|
|
78
|
+
# wapl_xml:: Properly formatted WAPL XML (see docs at htp://wapl.info) or use the WaplHelper module
|
|
79
|
+
# Returns hash containing
|
|
80
|
+
# * proper markup for the current device
|
|
81
|
+
# * required headers which need to be sent back to the device
|
|
82
|
+
def get_markup_from_wapl(wapl_xml="")
|
|
83
|
+
raise ArgumentError, "Empty string" if wapl_xml == ""
|
|
84
|
+
res = self.send_request 'get_markup_from_wapl', {'wapl'=>wapl_xml}
|
|
85
|
+
unless res.body.scan('WAPL ERROR').empty?
|
|
86
|
+
markup = wapl_xml + "<!-- WAPL XML ERROR #{ res.body } -->"
|
|
87
|
+
headers = ''
|
|
88
|
+
else
|
|
89
|
+
markup_res_xml = REXML::Document.new(res.body).root
|
|
90
|
+
res = {}
|
|
91
|
+
markup_res_xml.elements.each('header/item') do |el|
|
|
92
|
+
splits = el.text.split(': ');
|
|
93
|
+
h = Hash[splits[0], splits[1]]
|
|
94
|
+
res.merge! h
|
|
95
|
+
end
|
|
96
|
+
markup = markup_res_xml.elements.collect('markup') { |el| el.cdatas}
|
|
97
|
+
end
|
|
98
|
+
return {'markup' => markup, 'headers'=>res }
|
|
99
|
+
end
|
|
100
|
+
# submits the wapl markup url along with the headers
|
|
101
|
+
# brings back proper markup for the current device and required headers
|
|
102
|
+
# TODO / FIXME check whether supplied string is a url
|
|
103
|
+
def get_markup_from_url(makrup_url="")
|
|
104
|
+
raise ArgumentError, "Wrong or empty url" if markup_url == ""
|
|
105
|
+
res = self.send_request 'get_markup_from_url', { 'waplUrl'=>markup_url }
|
|
106
|
+
markup_data = self.process_res_xml res.body
|
|
107
|
+
return {'res'=>res, 'data'=> markup_data}
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
data/lib/wapl_helper.rb
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
module WaplHelper
|
|
2
|
+
# Open a tag
|
|
3
|
+
# Parameters
|
|
4
|
+
# Tag_name:: string - name of the tag <em></em>
|
|
5
|
+
# Attribute:: string - like name="test" woop="woop"
|
|
6
|
+
def t_s(tag_name, attr="")
|
|
7
|
+
if attr.empty?
|
|
8
|
+
%Q{<#{tag_name}>}
|
|
9
|
+
else
|
|
10
|
+
%Q{<#{tag_name} #{attr}>}
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# Converts a hash to attribute string
|
|
15
|
+
# Parameters
|
|
16
|
+
# Attr:: hash - { :name => "test"}
|
|
17
|
+
def attr_string(attr)
|
|
18
|
+
op_str = ""
|
|
19
|
+
attr.each { |k,v| op_str += %Q{#{k}="#{v}" } }
|
|
20
|
+
return op_str.strip
|
|
21
|
+
end
|
|
22
|
+
# Close the tag
|
|
23
|
+
# Parameters
|
|
24
|
+
# Tag_name:: - string
|
|
25
|
+
def t_e(tag_name)
|
|
26
|
+
%Q{</#{tag_name}>}
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Sanitze content
|
|
30
|
+
# Parameters
|
|
31
|
+
# Content:: string
|
|
32
|
+
def sanitize_html(content)
|
|
33
|
+
require 'cgi'
|
|
34
|
+
CGI.escapeHTML(content)
|
|
35
|
+
end
|
|
36
|
+
# Wrap string in to cdata marker
|
|
37
|
+
# parameters
|
|
38
|
+
# content:: - string to be wrapped
|
|
39
|
+
def cdatize(content)
|
|
40
|
+
|
|
41
|
+
content = '<![CDATA[ ' << content << ' ]]>'
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Returns a tag with optional attributes and content
|
|
45
|
+
# Parameters
|
|
46
|
+
# Tag_name:: string - the tag you wan to create e.g. "value"
|
|
47
|
+
# Content:: string = inner text of the tag
|
|
48
|
+
# Attributes:: hash - hash of attributes (key - val) for the element (optional)
|
|
49
|
+
def tag(tag_name, content, attributes = {})
|
|
50
|
+
t = self.t_s(tag_name)
|
|
51
|
+
unless attributes.empty?
|
|
52
|
+
t = self.t_s(tag_name, self.attr_string(attributes))
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
t << content << self.t_e(tag_name)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# Inserts a row and a cell with a specified content
|
|
59
|
+
# tag_string:: string - the content that goes into the row/cell
|
|
60
|
+
# cell:: hash - attribute hash for the <cell /> element
|
|
61
|
+
# row:: hash - attribute hash for the <row /> element
|
|
62
|
+
def row_cell(tag_string, cell={}, row={})
|
|
63
|
+
cell = self.tag('cell', tag_string, cell)
|
|
64
|
+
self.tag('row', cell, row)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# Creates a list of child elements with their values
|
|
68
|
+
# Children:: hash with tags and their contents e.g. { :span => "cool content"}
|
|
69
|
+
def children_list(children={})
|
|
70
|
+
children_str =""
|
|
71
|
+
children.each { |tag, val| children_str += self.tag(tag, val)}
|
|
72
|
+
return children_str
|
|
73
|
+
end
|
|
74
|
+
# WAPL specific element
|
|
75
|
+
# Creates chars element (see http://wapl.info docs)
|
|
76
|
+
# content:: string - conent of the chars element
|
|
77
|
+
# options:: hash - custom options for the element, can contain:
|
|
78
|
+
# - :attributes - for the chars elements (like id and other chars-specific settings)
|
|
79
|
+
# - :row - row attribute hash
|
|
80
|
+
# - :cell - cell attribute hash
|
|
81
|
+
def chars(content, options={})
|
|
82
|
+
# defaults
|
|
83
|
+
attributes = options[:attributes] || {}
|
|
84
|
+
|
|
85
|
+
value = self.tag('value', content)
|
|
86
|
+
chars = self.tag("chars", value, attributes )
|
|
87
|
+
|
|
88
|
+
cell = options[:cell] || {}
|
|
89
|
+
row = options[:row] || {}
|
|
90
|
+
self.row_cell(chars, cell, row)
|
|
91
|
+
end
|
|
92
|
+
# WAPL specific element
|
|
93
|
+
# Creates external image element (see http://wapl.info docs)
|
|
94
|
+
# url:: string - url to your image, WAPL engine will download it an process it
|
|
95
|
+
# options:: hash - custom options for the element, can contain:
|
|
96
|
+
# - :attributes - for the chars elements (like id and other chars-specific settings)
|
|
97
|
+
# - :row - row attribute hash
|
|
98
|
+
# - :cell - cell attribute hash
|
|
99
|
+
# just_element:: bool - create just the element, without the wrapping <row /><cell />
|
|
100
|
+
def external_image(url, options={}, just_element=false)
|
|
101
|
+
attributes = options[:attributes] || {}
|
|
102
|
+
children = options[:children] || {}
|
|
103
|
+
|
|
104
|
+
children[:url] = url
|
|
105
|
+
child_elements = self.children_list(children)
|
|
106
|
+
|
|
107
|
+
img = self.tag('externalImage', child_elements, attributes)
|
|
108
|
+
|
|
109
|
+
unless just_element
|
|
110
|
+
cell = options[:cell] || {}
|
|
111
|
+
row = options[:row] || {}
|
|
112
|
+
self.row_cell(img, cell, row)
|
|
113
|
+
else
|
|
114
|
+
return img
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
# WAPL specific element
|
|
118
|
+
# Creates external link element (see http://wapl.info docs)
|
|
119
|
+
# link_label:: string - label for your link (usually content of <a /> element)
|
|
120
|
+
# url:: string - url for your link
|
|
121
|
+
# options:: hash - (optional) custom options for the element, can contain:
|
|
122
|
+
# - :attributes - for the chars elements (like id and other chars-specific settings)
|
|
123
|
+
# - :row - row attribute hash
|
|
124
|
+
# - :cell - cell attribute hash
|
|
125
|
+
def external_link(link_label, url, options={})
|
|
126
|
+
attributes = options[:attributes] || {}
|
|
127
|
+
children = options[:children] || {}
|
|
128
|
+
image = options[:image] || {}
|
|
129
|
+
|
|
130
|
+
img =""
|
|
131
|
+
unless image.empty?
|
|
132
|
+
img = self.external_image(image[:url], image, true)
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
child_elements = self.children_list(children) << img
|
|
136
|
+
link_label = self.tag('label', link_label)
|
|
137
|
+
url = self.tag('url', url)
|
|
138
|
+
link = self.tag('externalLink', url << link_label << child_elements, attributes)
|
|
139
|
+
|
|
140
|
+
cell = options[:cell] || {}
|
|
141
|
+
row = options[:row] || {}
|
|
142
|
+
self.row_cell(link, cell, row)
|
|
143
|
+
end
|
|
144
|
+
# head section tags
|
|
145
|
+
# XML / root element declaration for use in the layout
|
|
146
|
+
|
|
147
|
+
def start_wapl
|
|
148
|
+
return '<wapl xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://wapl.wapple.net/wapl.xsd">'
|
|
149
|
+
end
|
|
150
|
+
# closes the root element
|
|
151
|
+
def end_wapl
|
|
152
|
+
return self.t_e('wapl')
|
|
153
|
+
end
|
|
154
|
+
# Layout method
|
|
155
|
+
# Returns list of meta tags
|
|
156
|
+
# Options:: hash - a hash of meta properites with value e.g. { :author => "Lukasz Korecki"}
|
|
157
|
+
def meta(options={})
|
|
158
|
+
metaz = ""
|
|
159
|
+
options.each { |k,v| metaz += "<meta " + self.attr_string({ :name=>k, :content => v} )+ " />" }
|
|
160
|
+
return metaz
|
|
161
|
+
end
|
|
162
|
+
# Renders external css declaration in the <head /> element
|
|
163
|
+
# url:: - url for the external stylesheet
|
|
164
|
+
def style_sheet(url="")
|
|
165
|
+
self.tag('css', self.tag('url', url))
|
|
166
|
+
end
|
|
167
|
+
# Renders external css declaration in the <head /> element
|
|
168
|
+
# alias for style_sheet()
|
|
169
|
+
# url:: - url for the external stylesheet
|
|
170
|
+
def css(url="")
|
|
171
|
+
self.style_sheet(url)
|
|
172
|
+
end
|
|
173
|
+
# Title tag
|
|
174
|
+
# title:: string - title for your page
|
|
175
|
+
def title(title="")
|
|
176
|
+
self.tag('title', title)
|
|
177
|
+
end
|
|
178
|
+
end
|
data/test/test_helper.rb
ADDED
data/test/test_wapl.rb
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
require 'test/unit'
|
|
3
|
+
require File.dirname(__FILE__) + '/../lib/wapl'
|
|
4
|
+
require 'fakeweb'
|
|
5
|
+
class WaplTest < ActiveSupport::TestCase
|
|
6
|
+
# set this if you have one
|
|
7
|
+
attr_accessor :real_key
|
|
8
|
+
|
|
9
|
+
def setup
|
|
10
|
+
@real_key = "24958309458"
|
|
11
|
+
FakeWeb.register_uri(:post, 'http://webservices.wapple.net/isMobileDevice.php', { :body => 1.to_s })
|
|
12
|
+
FakeWeb.register_uri(:post, 'http://webservices.wapple.net/getMobileDevice.php', { :body =>
|
|
13
|
+
'<?xml version="1.0" ?>
|
|
14
|
+
<wapple_response>
|
|
15
|
+
<model>iPhone</model>
|
|
16
|
+
<manufacturer>Apple</manufacturer>
|
|
17
|
+
<mobile_device>1</mobile_device>
|
|
18
|
+
</wapple_response>'
|
|
19
|
+
})
|
|
20
|
+
end
|
|
21
|
+
def test_constructor_without_dev_key
|
|
22
|
+
assert Wapl.new
|
|
23
|
+
end
|
|
24
|
+
def test_constructor
|
|
25
|
+
testkey = "testkey"
|
|
26
|
+
wapl = Wapl.new testkey, {}
|
|
27
|
+
assert_equal wapl.dev_key, testkey
|
|
28
|
+
assert_instance_of Wapl, wapl
|
|
29
|
+
end
|
|
30
|
+
def test_setters_and_getters
|
|
31
|
+
wapl = Wapl.new "", {}
|
|
32
|
+
testkey = "testkey"
|
|
33
|
+
wapl.dev_key = testkey
|
|
34
|
+
assert_equal wapl.dev_key, testkey
|
|
35
|
+
end
|
|
36
|
+
def test_headers_constructor_and_parse_headers
|
|
37
|
+
wapl = Wapl.new "testkey", { "elo"=>"test", "HTTP_test" => "test"}
|
|
38
|
+
assert_equal wapl.header_string, "HTTP_test:test|"
|
|
39
|
+
assert_no_match(/elo/, wapl.header_string)
|
|
40
|
+
end
|
|
41
|
+
def test_headers_parser
|
|
42
|
+
wapl = Wapl.new "testkey"
|
|
43
|
+
headers = { "elo"=>"test", "HTTP_test" => "test"}
|
|
44
|
+
wapl.set_headers headers
|
|
45
|
+
assert_equal wapl.header_string, "HTTP_test:test|"
|
|
46
|
+
assert_no_match(/elo/, wapl.header_string)
|
|
47
|
+
end
|
|
48
|
+
def test_communication_success_and_is_mobile_device
|
|
49
|
+
wapl = Wapl.new @real_key, {"HTTP-User-Agent" => "Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en) AppleWebKit/420+ (KHTML, like Gecko) Version/3.0 Mobile/1C25 Safari/419.3"}
|
|
50
|
+
resp = wapl.is_mobile_device
|
|
51
|
+
assert_no_match(/Developer key authentication error/i, resp)
|
|
52
|
+
assert_equal resp, '1'
|
|
53
|
+
end
|
|
54
|
+
def test_communication_success_and_get_mobile_device
|
|
55
|
+
wapl = Wapl.new @real_key, {"HTTP-User-Agent" => "Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en) AppleWebKit/420+ (KHTML, like Gecko) Version/3.0 Mobile/1C25 Safari/419.3"}
|
|
56
|
+
resp = wapl.get_mobile_device
|
|
57
|
+
assert resp['model']
|
|
58
|
+
assert resp['manufacturer']
|
|
59
|
+
assert resp['mobile_device']
|
|
60
|
+
# XXX this might be excessive.... since this might not always yield the same results, but this UA detection/handling is pretty solid ;-)
|
|
61
|
+
# lets assume that everything was correctly detcted and
|
|
62
|
+
# we're sure about the results
|
|
63
|
+
assert_match(/iphone/i,resp['model'])
|
|
64
|
+
assert_match(/Apple/i, resp['manufacturer'])
|
|
65
|
+
end
|
|
66
|
+
end
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
|
|
2
|
+
require 'test_helper'
|
|
3
|
+
require 'test/unit'
|
|
4
|
+
require File.dirname(__FILE__) + '/../lib/wapl_helper'
|
|
5
|
+
class WaplTest < ActiveSupport::TestCase
|
|
6
|
+
include WaplHelper
|
|
7
|
+
def test_include_and_require_and_all_that_stuff
|
|
8
|
+
assert tag('chars', 'char')
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def test_tag_start
|
|
12
|
+
assert_equal("<tag>", t_s("tag"))
|
|
13
|
+
assert_equal('<tag test="val">', t_s("tag", 'test="val"'))
|
|
14
|
+
end
|
|
15
|
+
def test_tag_end
|
|
16
|
+
assert_equal("</tag>", t_e("tag"))
|
|
17
|
+
end
|
|
18
|
+
def test_cdatize
|
|
19
|
+
assert_equal("<![CDATA[ test ]]>", cdatize('test'))
|
|
20
|
+
assert_match(/CDATA/, cdatize('ts'))
|
|
21
|
+
|
|
22
|
+
end
|
|
23
|
+
def test_attr_string
|
|
24
|
+
assert_equal('ole="test"', attr_string({:ole=>"test"}))
|
|
25
|
+
end
|
|
26
|
+
def test_tag
|
|
27
|
+
assert_equal('<t>test</t>', tag('t','test'))
|
|
28
|
+
assert_not_equal('<t>test</t>', tag('t','dest'))
|
|
29
|
+
assert_equal('<t ole="ule">test</t>', tag('t','test',{:ole =>"ule"}))
|
|
30
|
+
assert_not_equal('<t ole="ule" style="display:none;float:left;">test</t>', tag('t','test',{:ole =>"ule"}))
|
|
31
|
+
assert_equal('<t ole="ule" style="display:none;float:left;">test</t>', tag('t','test',{:ole =>"ule", :style => "display:none;float:left;"}))
|
|
32
|
+
end
|
|
33
|
+
def test_row_cell
|
|
34
|
+
assert_equal('<row><cell>test</cell></row>', row_cell('test'))
|
|
35
|
+
assert_equal('<row id="test"><cell class="class">test</cell></row>', row_cell('test', {:class=>"class"}, {:id=>"test"}))
|
|
36
|
+
assert_not_equal('<row class="class"><cell id="test">test</cell></row>', row_cell('test', {:class=>"class"}, {:id=>"test"}))
|
|
37
|
+
end
|
|
38
|
+
def test_children_list
|
|
39
|
+
children= {:url=>"http://google.com", :value=>"test"}
|
|
40
|
+
assert_match("<url>http://google.com</url>", children_list(children))
|
|
41
|
+
assert_match("<value>test</value>", children_list(children))
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def test_chars
|
|
45
|
+
char_str = "<row><cell><chars><value>test</value></chars></cell></row>"
|
|
46
|
+
assert_equal(char_str, chars("test"))
|
|
47
|
+
|
|
48
|
+
char_str_2 = '<row><cell><chars make_safe="true"><value>test</value></chars></cell></row>'
|
|
49
|
+
assert_equal(char_str_2, chars('test', { :attributes=>{ :make_safe =>"true"}}))
|
|
50
|
+
|
|
51
|
+
char_str_3 = '<row id="test"><cell><chars make_safe="true"><value>test</value></chars></cell></row>'
|
|
52
|
+
assert_equal(char_str_2, chars('test', { :attributes=>{ :make_safe =>"true"}}))
|
|
53
|
+
end
|
|
54
|
+
def test_external_image
|
|
55
|
+
ext_img ='<row><cell><externalImage><url>http://localhost/1.gif</url></externalImage></cell></row>'
|
|
56
|
+
ext_img_element_only ='<externalImage><url>http://localhost/1.gif</url></externalImage>'
|
|
57
|
+
assert_equal(ext_img, external_image('http://localhost/1.gif'))
|
|
58
|
+
assert_equal(ext_img_element_only, external_image('http://localhost/1.gif',{}, true))
|
|
59
|
+
|
|
60
|
+
assert_match( 'scale="150"', external_image('http://localhost/1.gif', { :attributes=>{ :file_type => "png", :scale =>"150"} }) )
|
|
61
|
+
assert_match( 'file_type="png"', external_image('http://localhost/1.gif', { :attributes=>{ :file_type => "png", :scale =>"150"} }) )
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
end
|
|
65
|
+
def test_external_link
|
|
66
|
+
link = '<row><cell><externalLink><url>http://google.com</url><label>Google</label></externalLink></cell></row>'
|
|
67
|
+
assert_equal(link, external_link('Google', 'http://google.com'))
|
|
68
|
+
|
|
69
|
+
link = '<row><cell><externalLink id="wgp"><url>http://google.com</url><label>Google</label><externalImage><url>http://wapl.info/img/header_wapple.png</url></externalImage></externalLink></cell></row>'
|
|
70
|
+
assert_equal(link, external_link("Google", "http://google.com", { :attributes => { :id => "wgp"}, :image => { :url => "http://wapl.info/img/header_wapple.png"}} ))
|
|
71
|
+
link = '<row><cell id="dupa"><externalLink id="wgp"><url>http://google.com</url><label>Google</label><externalImage><url>http://wapl.info/img/header_wapple.png</url></externalImage></externalLink></cell></row>'
|
|
72
|
+
assert_equal(link, external_link("Google", "http://google.com", { :attributes => { :id => "wgp"}, :image => { :url => "http://wapl.info/img/header_wapple.png"}, :cell => { :id => "dupa"}} ))
|
|
73
|
+
end
|
|
74
|
+
def test_title
|
|
75
|
+
assert_equal('<title>my title</title>', title('my title'))
|
|
76
|
+
end
|
|
77
|
+
def test_style_sheet
|
|
78
|
+
assert_equal('<css><url>http://my.css.com/1.css</url></css>', style_sheet('http://my.css.com/1.css'))
|
|
79
|
+
end
|
|
80
|
+
def test_meta_tag
|
|
81
|
+
assert_equal('<meta name="keywords" content="a list of stuff" />', meta({:keywords =>"a list of stuff"}))
|
|
82
|
+
assert_equal('<meta name="keywords" content="a list of stuff" /><meta name="encoding" content="utf-8" />', meta({:keywords =>"a list of stuff", :encoding=>"utf-8"}))
|
|
83
|
+
end
|
|
84
|
+
end
|
data/uninstall.rb
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# Uninstall hook code here
|
data/wapl.gemspec
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
Gem::Specification.new do |s|
|
|
4
|
+
s.name = %q{wapl}
|
|
5
|
+
s.version = "0.1"
|
|
6
|
+
|
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
|
8
|
+
s.authors = ["Lukasz Korecki"]
|
|
9
|
+
s.date = %q{2010-01-12}
|
|
10
|
+
s.description = %q{Library and helper for communicating with Wapple.net Architect web service, more information: http://wapl.info}
|
|
11
|
+
s.email = %q{lukasz@coffeesounds.com}
|
|
12
|
+
s.extra_rdoc_files = ["README.md", "lib/wapl.rb", "lib/wapl_helper.rb", "tasks/wapl_tasks.rake"]
|
|
13
|
+
s.files = ["MIT-LICENSE", "README.md", "Rakefile", "init.rb", "install.rb", "lib/wapl.rb", "lib/wapl_helper.rb", "tasks/wapl_tasks.rake", "test/test_helper.rb", "test/test_wapl.rb", "test/test_wapl_helper.rb", "uninstall.rb", "Manifest", "wapl.gemspec"]
|
|
14
|
+
s.homepage = %q{http://github.com/plugawy/wapl}
|
|
15
|
+
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Wapl", "--main", "README.md"]
|
|
16
|
+
s.require_paths = ["lib"]
|
|
17
|
+
s.rubyforge_project = %q{wapl}
|
|
18
|
+
s.rubygems_version = %q{1.3.5}
|
|
19
|
+
s.summary = %q{Library and helper for communicating with Wapple.net Architect web service, more information: http://wapl.info}
|
|
20
|
+
s.test_files = ["test/test_wapl.rb", "test/test_helper.rb", "test/test_wapl_helper.rb"]
|
|
21
|
+
|
|
22
|
+
if s.respond_to? :specification_version then
|
|
23
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
|
24
|
+
s.specification_version = 3
|
|
25
|
+
|
|
26
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
|
27
|
+
else
|
|
28
|
+
end
|
|
29
|
+
else
|
|
30
|
+
end
|
|
31
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: wapl
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: "0.1"
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Lukasz Korecki
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
|
|
12
|
+
date: 2010-01-12 00:00:00 +00:00
|
|
13
|
+
default_executable:
|
|
14
|
+
dependencies: []
|
|
15
|
+
|
|
16
|
+
description: "Library and helper for communicating with Wapple.net Architect web service, more information: http://wapl.info"
|
|
17
|
+
email: lukasz@coffeesounds.com
|
|
18
|
+
executables: []
|
|
19
|
+
|
|
20
|
+
extensions: []
|
|
21
|
+
|
|
22
|
+
extra_rdoc_files:
|
|
23
|
+
- README.md
|
|
24
|
+
- lib/wapl.rb
|
|
25
|
+
- lib/wapl_helper.rb
|
|
26
|
+
- tasks/wapl_tasks.rake
|
|
27
|
+
files:
|
|
28
|
+
- MIT-LICENSE
|
|
29
|
+
- README.md
|
|
30
|
+
- Rakefile
|
|
31
|
+
- init.rb
|
|
32
|
+
- install.rb
|
|
33
|
+
- lib/wapl.rb
|
|
34
|
+
- lib/wapl_helper.rb
|
|
35
|
+
- tasks/wapl_tasks.rake
|
|
36
|
+
- test/test_helper.rb
|
|
37
|
+
- test/test_wapl.rb
|
|
38
|
+
- test/test_wapl_helper.rb
|
|
39
|
+
- uninstall.rb
|
|
40
|
+
- Manifest
|
|
41
|
+
- wapl.gemspec
|
|
42
|
+
has_rdoc: true
|
|
43
|
+
homepage: http://github.com/plugawy/wapl
|
|
44
|
+
licenses: []
|
|
45
|
+
|
|
46
|
+
post_install_message:
|
|
47
|
+
rdoc_options:
|
|
48
|
+
- --line-numbers
|
|
49
|
+
- --inline-source
|
|
50
|
+
- --title
|
|
51
|
+
- Wapl
|
|
52
|
+
- --main
|
|
53
|
+
- README.md
|
|
54
|
+
require_paths:
|
|
55
|
+
- lib
|
|
56
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - ">="
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: "0"
|
|
61
|
+
version:
|
|
62
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
63
|
+
requirements:
|
|
64
|
+
- - ">="
|
|
65
|
+
- !ruby/object:Gem::Version
|
|
66
|
+
version: "1.2"
|
|
67
|
+
version:
|
|
68
|
+
requirements: []
|
|
69
|
+
|
|
70
|
+
rubyforge_project: wapl
|
|
71
|
+
rubygems_version: 1.3.5
|
|
72
|
+
signing_key:
|
|
73
|
+
specification_version: 3
|
|
74
|
+
summary: "Library and helper for communicating with Wapple.net Architect web service, more information: http://wapl.info"
|
|
75
|
+
test_files:
|
|
76
|
+
- test/test_wapl.rb
|
|
77
|
+
- test/test_helper.rb
|
|
78
|
+
- test/test_wapl_helper.rb
|