rack-tracker 0.0.4 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c6f2b15cb4ac572305b8421779e956633f04f942
4
- data.tar.gz: f9cc033dda73492645c530763bb629be4e505074
3
+ metadata.gz: b2dfdebdbc6937a3f5b16f873392116a67de22d8
4
+ data.tar.gz: 69be8ee4f72840aa57eeb30656e1995fde83591a
5
5
  SHA512:
6
- metadata.gz: 6dc9d9ffa1264d87885c58042f4dafd3362fac3b8d45e6986362ffc8c743fe7dce1ca16a60f80f7bd1255255d6ab7e5985e71a67637cb85ae452adeb3fe545b4
7
- data.tar.gz: c4cca8ee9f40adc66b1b9e48497589af502c6a4513dcfe412da8cdc7cf764eaf160e3e890bf979b03890335ffeb81700a1abefb433784a27e64d8b0237f0d58c
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
- The event will show up in the next rendered page. If the next page is a redirect, the event are kept in the session for later use.
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 )
@@ -2,7 +2,9 @@ module Rack
2
2
  class Tracker
3
3
  module Controller
4
4
  def tracker(&block)
5
- yield(Rack::Tracker::HandlerDelegator.new(env)) if block_given?
5
+ if block_given?
6
+ yield(Rack::Tracker::HandlerDelegator.new(env)).keys.map(&:to_sym)
7
+ end
6
8
  end
7
9
  end
8
10
  end
@@ -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', @id, to_h.compact].to_json
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(*event)] }
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 Event < OpenStruct
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: 'event' }.merge(attributes).compact
13
+ { hitType: self.type }.merge(attributes).compact
9
14
  end
10
15
 
11
16
  def attributes
12
- Hash[to_h.map { |k,v| ['event' + k.to_s.capitalize, 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 < Struct.new(:action, :payload)
21
+ class Ecommerce < OpenStruct
17
22
  def write
18
- [self.action, self.payload.compact].to_json.gsub(/\[|\]/, '')
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 => [Event.new(event)] }
35
+ def self.track(name, *event)
36
+ { name.to_s => [Send.new(event.last)] }
32
37
  end
33
38
  end
@@ -1,5 +1,5 @@
1
1
  module Rack
2
2
  class Tracker
3
- VERSION = "0.0.4"
3
+ VERSION = "0.1.0"
4
4
  end
5
5
  end
@@ -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', {foo: 'bar'}) }
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('123456789', {
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::Event.new(category: "Users", action: "Login", label: "Standard")
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::Event.new(category: "Users", action: "Login", label: "Standard", value: 5)
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('ecommerce:addItem', {id: '1234', affiliation: 'Acme Clothing', revenue: 11.99, shipping: '5', tax: '1.29', currency: 'EUR'})
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', { value: '1', currency: 'EUR' }
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
- class SomeController
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
- context 'controller' do
20
- let(:event) { Rack::Tracker::GoogleAnalytics::Event.new(category: 'foo') }
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
- it 'writes the event into env' do
23
- controller = SomeController.new
24
- expect {
25
- controller.index
26
- }.to change {
27
- controller.env
28
- }.from({}).to('tracker' => {'google_analytics' => [event]})
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
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rack-tracker
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lars Brillert