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 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