From 06a3de33d4dd90f0b5118b9e4cf405d65c7cd691 Mon Sep 17 00:00:00 2001 From: Ken-ichi Ueda Date: Tue, 9 Dec 2014 14:12:09 -0800 Subject: [PATCH 1/4] Added support for multiple trackers. --- README.md | 2 ++ lib/rack/templates/async.erb | 22 +++++++++++++++++++--- test/test_rack-google-analytics.rb | 14 ++++++++++++++ 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 45605a6..da16551 100755 --- a/README.md +++ b/README.md @@ -44,6 +44,8 @@ config.middleware.use Rack::GoogleAnalytics, :tracker => 'UA-xxxxxx-x' ### Options +* `:tracker` - sets the Google Analytics tracker +* `:trackers` - array of arrays to set multiple trackers. Takes the form `[['name1', 'tracker1'], ['name2', 'tracker2'], ...]`. Note that `name1` in this example will be ignored because the first tracker is the default. All additional trackers must be named. See https://developers.google.com/analytics/devguides/collection/analyticsjs/advanced#multipletrackers for details. * `:anonymize_ip` - sets the tracker to remove the last octet from all IP addresses, see https://developers.google.com/analytics/devguides/collection/gajs/methods/gaJSApi_gat?hl=de#_gat._anonymizeIp for details. * `:domain` - sets the domain name for the GATC cookies. Defaults to `auto`. * `:site_speed_sample_rate` - Defines a new sample set size for Site Speed data collection, see https://developers.google.com/analytics/devguides/collection/gajs/methods/gaJSApiBasicConfiguration?hl=de#_gat.GA_Tracker_._setSiteSpeedSampleRate diff --git a/lib/rack/templates/async.erb b/lib/rack/templates/async.erb index 2d3c27d..80dca9a 100644 --- a/lib/rack/templates/async.erb +++ b/lib/rack/templates/async.erb @@ -1,12 +1,19 @@ \ No newline at end of file diff --git a/test/test_rack-google-analytics.rb b/test/test_rack-google-analytics.rb index a32ff5c..337adb0 100755 --- a/test/test_rack-google-analytics.rb +++ b/test/test_rack-google-analytics.rb @@ -99,6 +99,20 @@ class TestRackGoogleAnalytics < Test::Unit::TestCase end end + context "with multiple trackers" do + setup { mock_app trackers: [['name1','horchata'], ['name2','slurpee']]} + should "show multiple trackers" do + get "/" + assert_match %r{ga\('create', 'horchata', {}\)}, last_response.body + assert_match %r{ga\('create', 'slurpee', {}\)}, last_response.body + end + should "should trigger pageview for each tracker" do + get "/" + assert_match %r{ga\('send', 'pageview'\);}, last_response.body + assert_match %r{ga\('name2.send', 'pageview'\);}, last_response.body + end + end + # context "with custom _setSiteSpeedSampleRate" do # setup { mock_app :async => true, :tracker => 'happy', :site_speed_sample_rate => 5 } # should "add top_level domain script" do From 180f4a640c2834abef78a4f64b21a7fd80e402dd Mon Sep 17 00:00:00 2001 From: Ken-ichi Ueda Date: Tue, 9 Dec 2014 16:38:48 -0800 Subject: [PATCH 2/4] Bugfix: options belong in the object literal, not floating out in space. --- lib/rack/google-analytics.rb | 2 +- lib/rack/templates/async.erb | 4 ++-- test/test_rack-google-analytics.rb | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/rack/google-analytics.rb b/lib/rack/google-analytics.rb index 8c744c0..f1a8e03 100644 --- a/lib/rack/google-analytics.rb +++ b/lib/rack/google-analytics.rb @@ -46,7 +46,7 @@ def _call(env) def html?; @headers['Content-Type'] =~ /html/; end def inject(response) - @tracker_options = { cookieDomain: @options[:domain] }.select{|k,v| v }.to_json + @tracker_options = { cookieDomain: @options[:domain] }.select{|k,v| v } @template ||= ::ERB.new ::File.read ::File.expand_path("../templates/async.erb",__FILE__) response.gsub(%r{}, @template.result(binding) + "") diff --git a/lib/rack/templates/async.erb b/lib/rack/templates/async.erb index 80dca9a..a0dc5ba 100644 --- a/lib/rack/templates/async.erb +++ b/lib/rack/templates/async.erb @@ -7,11 +7,11 @@ })(window,document,'script','//www.google-analytics.com/analytics.js','ga'); <% if @options[:tracker] %> - ga('create', '<%= @options[:tracker] %>', <%= @tracker_options %>); + ga('create', '<%= @options[:tracker] %>', <%= @tracker_options.to_json %>); <% else %> <% @options[:trackers].each_with_index do |pair, i| %> <% name, tracker = pair %> - ga('create', '<%= tracker %>', <%= @tracker_options %>)<%= ", {'name': '#{name}'}" if i > 0 %>; + ga('create', '<%= tracker %>', <%= (i > 0 ? @tracker_options.merge(:name => name) : @tracker_options).to_json %>); <% end %> <% end %> diff --git a/test/test_rack-google-analytics.rb b/test/test_rack-google-analytics.rb index 337adb0..1c86bf7 100755 --- a/test/test_rack-google-analytics.rb +++ b/test/test_rack-google-analytics.rb @@ -104,7 +104,7 @@ class TestRackGoogleAnalytics < Test::Unit::TestCase should "show multiple trackers" do get "/" assert_match %r{ga\('create', 'horchata', {}\)}, last_response.body - assert_match %r{ga\('create', 'slurpee', {}\)}, last_response.body + assert_match %r{ga\('create', 'slurpee', {"name":"name2"}\)}, last_response.body end should "should trigger pageview for each tracker" do get "/" From eb18e8c990089005d46eee0c2fce74a98ea88888 Mon Sep 17 00:00:00 2001 From: Ken-ichi Ueda Date: Tue, 9 Dec 2014 17:34:38 -0800 Subject: [PATCH 3/4] Added support for specifying trackers as a block. --- lib/rack/google-analytics.rb | 5 +++++ test/test_rack-google-analytics.rb | 13 +++++++++++++ 2 files changed, 18 insertions(+) diff --git a/lib/rack/google-analytics.rb b/lib/rack/google-analytics.rb index f1a8e03..6a4998d 100644 --- a/lib/rack/google-analytics.rb +++ b/lib/rack/google-analytics.rb @@ -34,6 +34,7 @@ def _call(env) end @options[:tracker] = expand_tracker(env, @options[:tracker]) + @options[:trackers] = expand_trackers(env, @options[:trackers]) @body.each { |fragment| response.write inject(fragment) } @body.close if @body.respond_to?(:close) @@ -56,6 +57,10 @@ def expand_tracker(env, tracker) tracker.respond_to?(:call) ? tracker.call(env) : tracker end + def expand_trackers(env, trackers) + trackers.respond_to?(:call) ? trackers.call(env) : trackers + end + end end diff --git a/test/test_rack-google-analytics.rb b/test/test_rack-google-analytics.rb index 1c86bf7..afd2027 100755 --- a/test/test_rack-google-analytics.rb +++ b/test/test_rack-google-analytics.rb @@ -113,6 +113,19 @@ class TestRackGoogleAnalytics < Test::Unit::TestCase end end + context "with multiple trackers block" do + setup do + mock_app trackers: lambda {|env| + [['name1','horchata'], ['name2','slurpee']] + } + end + should "show multiple trackers" do + get "/" + assert_match %r{ga\('create', 'horchata', {}\)}, last_response.body + assert_match %r{ga\('create', 'slurpee', {"name":"name2"}\)}, last_response.body + end + end + # context "with custom _setSiteSpeedSampleRate" do # setup { mock_app :async => true, :tracker => 'happy', :site_speed_sample_rate => 5 } # should "add top_level domain script" do From 92f9fe2f699a429b194a4c0ed18a5089e03454f8 Mon Sep 17 00:00:00 2001 From: Ken-ichi Ueda Date: Wed, 10 Dec 2014 13:33:01 -0800 Subject: [PATCH 4/4] Lambda blocks should get evaluated with every request Or at least that's what makes sense to me. Before they were only getting evaluated when the applications started, stored in @options instance var, and kept around in the Rack::GoogleAnalytics instance across multiple requests. --- lib/rack/google-analytics.rb | 7 ++++--- lib/rack/templates/async.erb | 14 +++++++------- test/test_rack-google-analytics.rb | 9 +++++++++ 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/lib/rack/google-analytics.rb b/lib/rack/google-analytics.rb index 6a4998d..eae4e3d 100644 --- a/lib/rack/google-analytics.rb +++ b/lib/rack/google-analytics.rb @@ -33,12 +33,14 @@ def _call(env) env["rack.session"][EVENT_TRACKING_KEY] = env[EVENT_TRACKING_KEY] end - @options[:tracker] = expand_tracker(env, @options[:tracker]) - @options[:trackers] = expand_trackers(env, @options[:trackers]) + @tracker = expand_tracker(env, @options[:tracker]) + @trackers = expand_trackers(env, @options[:trackers]) @body.each { |fragment| response.write inject(fragment) } @body.close if @body.respond_to?(:close) + @tracker = nil + @trackers = nil response.finish end @@ -49,7 +51,6 @@ def html?; @headers['Content-Type'] =~ /html/; end def inject(response) @tracker_options = { cookieDomain: @options[:domain] }.select{|k,v| v } @template ||= ::ERB.new ::File.read ::File.expand_path("../templates/async.erb",__FILE__) - response.gsub(%r{}, @template.result(binding) + "") end diff --git a/lib/rack/templates/async.erb b/lib/rack/templates/async.erb index a0dc5ba..27de317 100644 --- a/lib/rack/templates/async.erb +++ b/lib/rack/templates/async.erb @@ -1,15 +1,15 @@