rack-tracker 0.0.4 → 0.1.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.
- checksums.yaml +4 -4
- data/README.md +102 -3
- data/lib/rack/tracker/controller.rb +3 -1
- data/lib/rack/tracker/facebook/facebook.rb +2 -8
- data/lib/rack/tracker/google_analytics/google_analytics.rb +12 -7
- data/lib/rack/tracker/version.rb +1 -1
- data/spec/handler/facebook_spec.rb +4 -3
- data/spec/handler/google_analytics_spec.rb +3 -3
- data/spec/support/metal_controller.rb +1 -1
- data/spec/tracker/controller_spec.rb +22 -17
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b2dfdebdbc6937a3f5b16f873392116a67de22d8
|
4
|
+
data.tar.gz: 69be8ee4f72840aa57eeb30656e1995fde83591a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1aafbe6cb3abdece6b939244f995daa9cd1e2c1fb8dfc6fbbcb9e5c488925427e644cd563e70fc63ea002b348aed342afcd9135c40b3cef14c1dc2c1255541b8
|
7
|
+
data.tar.gz: c69c3ccf4ed538f429a56031c322e7bb66f3f9972652bdf0f20b28024a79685fffeb0fff8855eee4f8a0c990db19451d1e348a3007415aa4b2e3277db71a1372
|
data/README.md
CHANGED
@@ -49,12 +49,45 @@ To issue [Events](https://developers.google.com/analytics/devguides/collection/a
|
|
49
49
|
```ruby
|
50
50
|
def show
|
51
51
|
tracker do |t|
|
52
|
-
t.google_analytics category: 'button', action: 'click', label: 'nav-buttons', value: 'X'
|
52
|
+
t.google_analytics :send, { type: 'event', category: 'button', action: 'click', label: 'nav-buttons', value: 'X' }
|
53
53
|
end
|
54
54
|
end
|
55
55
|
```
|
56
56
|
|
57
|
-
|
57
|
+
It will render the following to the site source:
|
58
|
+
|
59
|
+
```javascript
|
60
|
+
ga('send', { 'hitType': 'event', 'eventCategory': 'button', 'eventAction': 'click', 'eventLabel': 'X' })
|
61
|
+
```
|
62
|
+
|
63
|
+
#### Ecommerce
|
64
|
+
|
65
|
+
You can even trigger ecommerce directly from within your controller:
|
66
|
+
|
67
|
+
```ruby
|
68
|
+
def show
|
69
|
+
tracker do |t|
|
70
|
+
t.google_analytics :ecommerce, { type: 'addItem', 'id': '1234', 'affiliation': 'Acme Clothing', 'revenue': '11.99', 'shipping': '5', 'tax': '1.29' }
|
71
|
+
end
|
72
|
+
end
|
73
|
+
```
|
74
|
+
|
75
|
+
Will give you this:
|
76
|
+
|
77
|
+
```javascript
|
78
|
+
ga('ecommerce:addItem', { 'id': '1234', 'affiliation': 'Acme Clothing', 'revenue': '11.99', 'shipping': '5', 'tax': '1.29' })
|
79
|
+
```
|
80
|
+
|
81
|
+
To load the `ecommerce`-plugin, add some configuration to the middleware initialization,
|
82
|
+
this is _not_ needed for the above to work, but recommened, so you don't have to
|
83
|
+
take care of the plugin on your own.
|
84
|
+
|
85
|
+
```ruby
|
86
|
+
config.middleware.use(Rack::Tracker) do
|
87
|
+
handler :google_analytics, { tracker: 'U-XXXXX-Y', ecommerce: true}
|
88
|
+
end
|
89
|
+
````
|
90
|
+
|
58
91
|
|
59
92
|
### Facebook
|
60
93
|
|
@@ -67,11 +100,77 @@ To track [Conversions](https://www.facebook.com/help/435189689870514) from the s
|
|
67
100
|
```ruby
|
68
101
|
def show
|
69
102
|
tracker do |t|
|
70
|
-
t.facebook '123456789', value: 1, currency: 'EUR'
|
103
|
+
t.facebook :track, { id: '123456789', value: 1, currency: 'EUR' }
|
71
104
|
end
|
72
105
|
end
|
73
106
|
```
|
74
107
|
|
108
|
+
Will result in the following:
|
109
|
+
|
110
|
+
```javascript
|
111
|
+
window._fbq.push(["track", "123456789", {'value': 1, 'currency': 'EUR'}]);
|
112
|
+
```
|
113
|
+
|
114
|
+
## Custom Handlers
|
115
|
+
|
116
|
+
Tough we give you Google Analytics and Facebook right out of the box, you might
|
117
|
+
be interested adding support for your custom tracking/analytics service.
|
118
|
+
|
119
|
+
Writing a handler is straight forward ;) There are just a couple of methods that
|
120
|
+
your class needs to implement.
|
121
|
+
|
122
|
+
Start with a plain ruby class that inherits from `Rack::Tracker::Handler`
|
123
|
+
|
124
|
+
```ruby
|
125
|
+
class MyHandler < Rack::Tracker::Handler
|
126
|
+
...
|
127
|
+
end
|
128
|
+
```
|
129
|
+
|
130
|
+
Second we need a method called `#render` which will take care of rendering a
|
131
|
+
template.
|
132
|
+
|
133
|
+
```ruby
|
134
|
+
def render
|
135
|
+
Tilt.new( File.join( File.dirname(__FILE__), 'template' 'my_handler.erb') ).render(self)
|
136
|
+
end
|
137
|
+
```
|
138
|
+
|
139
|
+
This will render the `template/my_handler.erb` and inject the result into the source. You
|
140
|
+
can be creative about where the template is stored, we tend to have them around
|
141
|
+
our actual handler code.
|
142
|
+
|
143
|
+
```erb
|
144
|
+
<script>
|
145
|
+
console.log('my tracker: ' + <%= options.to_json %>)
|
146
|
+
</script>
|
147
|
+
```
|
148
|
+
|
149
|
+
Lets give it a try! We need to mount our new handler in the `Rack::Tracker` middleware
|
150
|
+
|
151
|
+
```ruby
|
152
|
+
config.middleware.use(Rack::Tracker) do
|
153
|
+
handler MyTracker, { awesome: true }
|
154
|
+
end
|
155
|
+
````
|
156
|
+
|
157
|
+
Everything you're passing to the `handler` will be availble as `#options` in your
|
158
|
+
template, You'll also gain access to the `env`-hash belonging to the current request.
|
159
|
+
|
160
|
+
Run your application and make a request, the result of the above template can be
|
161
|
+
found right before `</head>`. You can change the position in your handler-code:
|
162
|
+
|
163
|
+
```ruby
|
164
|
+
class MyHandler < Rack::Tracker::Handler
|
165
|
+
self.position = :body
|
166
|
+
|
167
|
+
...
|
168
|
+
end
|
169
|
+
```
|
170
|
+
|
171
|
+
The snippot will then be rendered right before `</body>`.
|
172
|
+
|
173
|
+
|
75
174
|
## Contributing
|
76
175
|
|
77
176
|
1. Fork it ( http://github.com/railslove/rack-tracker/fork )
|
@@ -1,13 +1,7 @@
|
|
1
1
|
class Rack::Tracker::Facebook < Rack::Tracker::Handler
|
2
2
|
class Event < OpenStruct
|
3
|
-
attr_reader :id
|
4
|
-
def initialize(id, attributes = {})
|
5
|
-
@id = id
|
6
|
-
super(attributes)
|
7
|
-
end
|
8
|
-
|
9
3
|
def write
|
10
|
-
['track',
|
4
|
+
['track', self.id, to_h.except(:id).compact].to_json
|
11
5
|
end
|
12
6
|
end
|
13
7
|
|
@@ -18,7 +12,7 @@ class Rack::Tracker::Facebook < Rack::Tracker::Handler
|
|
18
12
|
end
|
19
13
|
|
20
14
|
def self.track(name, *event)
|
21
|
-
{ name.to_s => [Event.new(
|
15
|
+
{ name.to_s => [Event.new(event.last)] }
|
22
16
|
end
|
23
17
|
|
24
18
|
end
|
@@ -1,21 +1,26 @@
|
|
1
1
|
class Rack::Tracker::GoogleAnalytics < Rack::Tracker::Handler
|
2
|
-
class
|
2
|
+
class Send < OpenStruct
|
3
|
+
def initialize(attrs = {})
|
4
|
+
attrs.reverse_merge!(type: 'event')
|
5
|
+
super
|
6
|
+
end
|
7
|
+
|
3
8
|
def write
|
4
9
|
['send', event].to_json.gsub(/\[|\]/, '')
|
5
10
|
end
|
6
11
|
|
7
12
|
def event
|
8
|
-
{ hitType:
|
13
|
+
{ hitType: self.type }.merge(attributes).compact
|
9
14
|
end
|
10
15
|
|
11
16
|
def attributes
|
12
|
-
Hash[to_h.map { |k,v| [
|
17
|
+
Hash[to_h.slice(:category, :action, :label, :value).map { |k,v| [self.type.to_s + k.to_s.capitalize, v] }]
|
13
18
|
end
|
14
19
|
end
|
15
20
|
|
16
|
-
class Ecommerce <
|
21
|
+
class Ecommerce < OpenStruct
|
17
22
|
def write
|
18
|
-
[self.
|
23
|
+
["ecommerce:#{self.type}", self.to_h.except(:type).compact].to_json.gsub(/\[|\]/, '')
|
19
24
|
end
|
20
25
|
end
|
21
26
|
|
@@ -27,7 +32,7 @@ class Rack::Tracker::GoogleAnalytics < Rack::Tracker::Handler
|
|
27
32
|
Tilt.new( File.join( File.dirname(__FILE__), 'template', 'google_analytics.erb') ).render(self)
|
28
33
|
end
|
29
34
|
|
30
|
-
def self.track(name, event)
|
31
|
-
{ name.to_s => [
|
35
|
+
def self.track(name, *event)
|
36
|
+
{ name.to_s => [Send.new(event.last)] }
|
32
37
|
end
|
33
38
|
end
|
data/lib/rack/tracker/version.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
RSpec.describe Rack::Tracker::Facebook do
|
2
2
|
describe Rack::Tracker::Facebook::Event do
|
3
3
|
|
4
|
-
subject { described_class.new('id',
|
4
|
+
subject { described_class.new({id: 'id', foo: 'bar'}) }
|
5
5
|
|
6
6
|
describe '#write' do
|
7
7
|
specify { expect(subject.write).to eq(['track', 'id', {foo: 'bar'}].to_json) }
|
@@ -36,10 +36,11 @@ RSpec.describe Rack::Tracker::Facebook do
|
|
36
36
|
'tracker' => {
|
37
37
|
'facebook' =>
|
38
38
|
[
|
39
|
-
Rack::Tracker::Facebook::Event.new(
|
39
|
+
Rack::Tracker::Facebook::Event.new(
|
40
|
+
'id'=> '123456789',
|
40
41
|
'value' => '23',
|
41
42
|
'currency' => 'EUR'
|
42
|
-
|
43
|
+
)
|
43
44
|
]
|
44
45
|
}
|
45
46
|
}
|
@@ -14,7 +14,7 @@ RSpec.describe Rack::Tracker::GoogleAnalytics do
|
|
14
14
|
def env
|
15
15
|
{'tracker' => {
|
16
16
|
'google_analytics' => [
|
17
|
-
Rack::Tracker::GoogleAnalytics::
|
17
|
+
Rack::Tracker::GoogleAnalytics::Send.new(category: "Users", action: "Login", label: "Standard")
|
18
18
|
]
|
19
19
|
}}
|
20
20
|
end
|
@@ -28,7 +28,7 @@ RSpec.describe Rack::Tracker::GoogleAnalytics do
|
|
28
28
|
describe "with a event value" do
|
29
29
|
def env
|
30
30
|
{'tracker' => { 'google_analytics' => [
|
31
|
-
Rack::Tracker::GoogleAnalytics::
|
31
|
+
Rack::Tracker::GoogleAnalytics::Send.new(category: "Users", action: "Login", label: "Standard", value: 5)
|
32
32
|
]}}
|
33
33
|
end
|
34
34
|
|
@@ -44,7 +44,7 @@ RSpec.describe Rack::Tracker::GoogleAnalytics do
|
|
44
44
|
def env
|
45
45
|
{'tracker' => {
|
46
46
|
'google_analytics' => [
|
47
|
-
Rack::Tracker::GoogleAnalytics::Ecommerce.new('
|
47
|
+
Rack::Tracker::GoogleAnalytics::Ecommerce.new({type: 'addItem', id: '1234', affiliation: 'Acme Clothing', revenue: 11.99, shipping: '5', tax: '1.29', currency: 'EUR'})
|
48
48
|
]
|
49
49
|
}}
|
50
50
|
end
|
@@ -17,7 +17,7 @@ class MetalController < ActionController::Metal
|
|
17
17
|
|
18
18
|
def facebook
|
19
19
|
tracker do |t|
|
20
|
-
t.facebook 'conversion-event',
|
20
|
+
t.facebook :track, { id: 'conversion-event', value: '1', currency: 'EUR' }
|
21
21
|
end
|
22
22
|
render "metal/index"
|
23
23
|
end
|
@@ -1,31 +1,36 @@
|
|
1
|
-
|
1
|
+
TestController = Struct.new(:env) do
|
2
2
|
include Rack::Tracker::Controller
|
3
3
|
|
4
|
-
attr_accessor :env
|
5
|
-
|
6
|
-
def initialize
|
7
|
-
@env = {}
|
8
|
-
end
|
9
|
-
|
10
4
|
def index
|
11
5
|
tracker do |t|
|
12
|
-
t.google_analytics category: 'foo'
|
6
|
+
t.google_analytics :send, category: 'foo'
|
13
7
|
end
|
14
8
|
end
|
15
9
|
end
|
16
10
|
|
17
11
|
|
18
12
|
RSpec.describe Rack::Tracker::Controller do
|
19
|
-
|
20
|
-
let(:event) { Rack::Tracker::GoogleAnalytics::
|
13
|
+
describe '#tracker' do
|
14
|
+
let(:event) { Rack::Tracker::GoogleAnalytics::Send.new(category: 'foo') }
|
15
|
+
let(:controller) { TestController.new({}) }
|
16
|
+
|
17
|
+
context 'controller' do
|
18
|
+
it 'writes the event into env' do
|
19
|
+
expect {
|
20
|
+
controller.index
|
21
|
+
}.to change {
|
22
|
+
controller.env
|
23
|
+
}.from({}).to('tracker' => {'google_analytics' => [event]})
|
24
|
+
end
|
21
25
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
26
|
+
it 'returns only the handlers' do
|
27
|
+
expect(
|
28
|
+
controller.tracker do |t|
|
29
|
+
t.google_analytics category: 'foo'
|
30
|
+
t.facebook some: 'thing'
|
31
|
+
end
|
32
|
+
).to eql([:google_analytics, :facebook])
|
33
|
+
end
|
29
34
|
end
|
30
35
|
end
|
31
36
|
end
|