From dafd199b2224ba79ef9a89b5c9e9801e834d4bfe Mon Sep 17 00:00:00 2001
From: Salim Hbeiliny
Date: Wed, 6 May 2015 12:55:26 +0200
Subject: [PATCH 1/6] add exact_position option to allow injecting handlers
after the opening of the :position tag
---
lib/rack/tracker.rb | 6 +++++-
.../google_tag_manager/google_tag_manager.rb | 1 +
lib/rack/tracker/handler.rb | 3 ++-
spec/tracker/tracker_spec.rb | 17 ++++++++++++++++-
4 files changed, 24 insertions(+), 3 deletions(-)
diff --git a/lib/rack/tracker.rb b/lib/rack/tracker.rb
index 5f298dc..fae3556 100644
--- a/lib/rack/tracker.rb
+++ b/lib/rack/tracker.rb
@@ -55,7 +55,11 @@ def html?; @headers['Content-Type'] =~ /html/; end
def inject(env, response)
@handlers.each(env) do |handler|
- response.gsub!(%r{#{handler.position}>}, handler.render + "#{handler.position}>")
+ if handler.exact_position == :closing
+ response.gsub!(%r{#{handler.position}>}, handler.render + "#{handler.position}>")
+ else
+ response.gsub!(%r{<#{handler.position}>}, "<#{handler.position}>" + handler.render)
+ end
end
response
end
diff --git a/lib/rack/tracker/google_tag_manager/google_tag_manager.rb b/lib/rack/tracker/google_tag_manager/google_tag_manager.rb
index be01ed7..42d49a2 100644
--- a/lib/rack/tracker/google_tag_manager/google_tag_manager.rb
+++ b/lib/rack/tracker/google_tag_manager/google_tag_manager.rb
@@ -18,6 +18,7 @@ def attributes
# It is strongly recommended to put the google_tag_manager snippet only in the body tag
# https://developers.google.com/tag-manager/quickstart
self.position = :body
+ self.exact_position = :opening
def container
options[:container].respond_to?(:call) ? options[:container].call(env) : options[:container]
diff --git a/lib/rack/tracker/handler.rb b/lib/rack/tracker/handler.rb
index bcd2101..9f055d0 100644
--- a/lib/rack/tracker/handler.rb
+++ b/lib/rack/tracker/handler.rb
@@ -1,6 +1,7 @@
class Rack::Tracker::Handler
- class_attribute :position
+ class_attribute :position, :exact_position
self.position = :head
+ self.exact_position = :closing
attr_accessor :options
attr_accessor :env
diff --git a/spec/tracker/tracker_spec.rb b/spec/tracker/tracker_spec.rb
index 1f5a530..c751ff7 100644
--- a/spec/tracker/tracker_spec.rb
+++ b/spec/tracker/tracker_spec.rb
@@ -12,6 +12,11 @@ class BodyHandler < DummyHandler
self.position = :body
end
+class BodyOpeningHandler < DummyHandler
+ self.position = :body
+ self.exact_position = :opening
+end
+
RSpec.describe Rack::Tracker do
def app
Rack::Builder.new do
@@ -20,6 +25,7 @@ def app
use Rack::Tracker do
handler DummyHandler, { foo: 'head' }
handler BodyHandler, { foo: 'body' }
+ handler BodyOpeningHandler, { foo: 'body_opening' }
end
run lambda {|env|
@@ -55,6 +61,7 @@ def app
get '/'
expect(last_response.body).to include("console.log('head');")
expect(last_response.body).to_not include("console.log('body');")
+ expect(last_response.body).to_not include("console.log('body_opening');")
end
it 'injects custom variables that was directly assigned' do
@@ -69,11 +76,18 @@ def app
end
describe 'when body is present' do
- it 'will not inject the body handler code' do
+ it 'will inject only the body handler code' do
get '/body'
expect(last_response.body).to include("console.log('body');")
+ expect(last_response.body).to include("console.log('body_opening');")
expect(last_response.body).to_not include("console.log('head');")
end
+
+ it 'will inject the handlers in their exact_position' do
+ get '/body'
+ expect(last_response.body).to include("")
+ expect(last_response.body).to include("\n")
+ end
end
describe 'when head and body is present' do
@@ -81,6 +95,7 @@ def app
get '/body-head'
expect(last_response.body).to include("console.log('head');")
expect(last_response.body).to include("console.log('body');")
+ expect(last_response.body).to include("console.log('body_opening');")
end
end
From abba4a99a5a5bf8ff60cf4eddfccc7d42631cb57 Mon Sep 17 00:00:00 2001
From: Salim Hbeiliny
Date: Wed, 6 May 2015 14:42:38 +0200
Subject: [PATCH 2/6] rename position to container_tag and exact_position to
container_position
---
README.md | 19 ++++++++++++++++---
lib/rack/tracker.rb | 6 +++---
lib/rack/tracker/criteo/criteo.rb | 2 +-
lib/rack/tracker/facebook/facebook.rb | 2 +-
.../google_adwords_conversion.rb | 2 +-
.../google_tag_manager/google_tag_manager.rb | 4 ++--
lib/rack/tracker/handler.rb | 11 ++++++-----
spec/handler/criteo_spec.rb | 6 +++---
spec/handler/facebook_spec.rb | 4 ++--
spec/handler/go_squared_spec.rb | 4 ++--
.../handler/google_adwords_conversion_spec.rb | 6 +++---
spec/handler/google_analytics_spec.rb | 6 +++---
spec/handler/google_tag_manager_spec.rb | 10 +++++-----
spec/handler/vwo_spec.rb | 4 ++--
spec/integration/criteo_integration_spec.rb | 4 ++--
.../google_analytics_integration_spec.rb | 4 ++--
spec/support/fake_handler.rb | 2 +-
spec/tracker/tracker_spec.rb | 8 ++++----
18 files changed, 59 insertions(+), 45 deletions(-)
diff --git a/README.md b/README.md
index bd7eb0b..6a0f9b0 100644
--- a/README.md
+++ b/README.md
@@ -418,17 +418,30 @@ Everything you're passing to the `handler` will be available as `#options` in yo
template, so you'll also gain access to the `env`-hash belonging to the current request.
Run your application and make a request, the result of the above template can be
-found right before ``. You can change the position in your handler-code:
+found right before ``. You can change the `container_tag` in your handler-code:
```ruby
class MyHandler < Rack::Tracker::Handler
- self.position = :body
+ self.container_tag = :body
...
end
```
-The snippit will then be rendered right before `
`
To enable the *tracker dsl* functionality in your controllers
you need to implement the `track` class method on your handler:
diff --git a/lib/rack/tracker.rb b/lib/rack/tracker.rb
index fae3556..30ac441 100644
--- a/lib/rack/tracker.rb
+++ b/lib/rack/tracker.rb
@@ -55,10 +55,10 @@ def html?; @headers['Content-Type'] =~ /html/; end
def inject(env, response)
@handlers.each(env) do |handler|
- if handler.exact_position == :closing
- response.gsub!(%r{#{handler.position}>}, handler.render + "#{handler.position}>")
+ if handler.container_position == :closing
+ response.gsub!(%r{#{handler.container_tag}>}, handler.render + "#{handler.container_tag}>")
else
- response.gsub!(%r{<#{handler.position}>}, "<#{handler.position}>" + handler.render)
+ response.gsub!(%r{<#{handler.container_tag}>}, "<#{handler.container_tag}>" + handler.render)
end
end
response
diff --git a/lib/rack/tracker/criteo/criteo.rb b/lib/rack/tracker/criteo/criteo.rb
index b52a880..8a68f5b 100644
--- a/lib/rack/tracker/criteo/criteo.rb
+++ b/lib/rack/tracker/criteo/criteo.rb
@@ -13,7 +13,7 @@ def write
end
end
- self.position = :body
+ self.container_tag = :body
# global events (setSiteType, setAccount, ...) for each tracker instance
def tracker_events
diff --git a/lib/rack/tracker/facebook/facebook.rb b/lib/rack/tracker/facebook/facebook.rb
index 3f87247..bdea4db 100644
--- a/lib/rack/tracker/facebook/facebook.rb
+++ b/lib/rack/tracker/facebook/facebook.rb
@@ -5,7 +5,7 @@ def write
end
end
- self.position = :body
+ self.container_tag = :body
def render
Tilt.new( File.join( File.dirname(__FILE__), 'template/facebook.erb') ).render(self)
diff --git a/lib/rack/tracker/google_adwords_conversion/google_adwords_conversion.rb b/lib/rack/tracker/google_adwords_conversion/google_adwords_conversion.rb
index 68c95ab..b18c3f3 100644
--- a/lib/rack/tracker/google_adwords_conversion/google_adwords_conversion.rb
+++ b/lib/rack/tracker/google_adwords_conversion/google_adwords_conversion.rb
@@ -3,7 +3,7 @@ class Rack::Tracker::GoogleAdwordsConversion < Rack::Tracker::Handler
class Conversion < OpenStruct
end
- self.position = :body
+ self.container_tag = :body
def render
Tilt.new( File.join( File.dirname(__FILE__), 'template', 'google_adwords_conversion.erb') ).render(self)
diff --git a/lib/rack/tracker/google_tag_manager/google_tag_manager.rb b/lib/rack/tracker/google_tag_manager/google_tag_manager.rb
index 42d49a2..13ec935 100644
--- a/lib/rack/tracker/google_tag_manager/google_tag_manager.rb
+++ b/lib/rack/tracker/google_tag_manager/google_tag_manager.rb
@@ -17,8 +17,8 @@ def attributes
# It is strongly recommended to put the google_tag_manager snippet only in the body tag
# https://developers.google.com/tag-manager/quickstart
- self.position = :body
- self.exact_position = :opening
+ self.container_tag = :body
+ self.container_position = :opening
def container
options[:container].respond_to?(:call) ? options[:container].call(env) : options[:container]
diff --git a/lib/rack/tracker/handler.rb b/lib/rack/tracker/handler.rb
index 9f055d0..53db3e6 100644
--- a/lib/rack/tracker/handler.rb
+++ b/lib/rack/tracker/handler.rb
@@ -1,15 +1,16 @@
class Rack::Tracker::Handler
- class_attribute :position, :exact_position
- self.position = :head
- self.exact_position = :closing
+ class_attribute :container_tag, :container_position
+ self.container_tag = :head
+ self.container_position = :closing
attr_accessor :options
attr_accessor :env
def initialize(env, options = {})
self.env = env
- self.options = options
- self.position = options[:position] if options.has_key?(:position)
+ self.options = options
+ self.container_tag = options[:container_tag] if options.has_key?(:container_tag)
+ self.container_position = options[:container_position] if options.has_key?(:container_position)
end
def events
diff --git a/spec/handler/criteo_spec.rb b/spec/handler/criteo_spec.rb
index 8feded3..1fbb94b 100644
--- a/spec/handler/criteo_spec.rb
+++ b/spec/handler/criteo_spec.rb
@@ -14,8 +14,8 @@ def env
end
it 'will be placed in the body' do
- expect(described_class.position).to eq(:body)
- expect(described_class.new(env).position).to eq(:body)
+ expect(described_class.container_tag).to eq(:body)
+ expect(described_class.new(env).container_tag).to eq(:body)
end
describe '#render' do
@@ -119,4 +119,4 @@ def env
end
end
-end
\ No newline at end of file
+end
diff --git a/spec/handler/facebook_spec.rb b/spec/handler/facebook_spec.rb
index 6a24738..b8cdf42 100644
--- a/spec/handler/facebook_spec.rb
+++ b/spec/handler/facebook_spec.rb
@@ -13,8 +13,8 @@ def env
end
it 'will be placed in the body' do
- expect(described_class.position).to eq(:body)
- expect(described_class.new(env).position).to eq(:body)
+ expect(described_class.container_tag).to eq(:body)
+ expect(described_class.new(env).container_tag).to eq(:body)
end
describe 'with custom audience id' do
diff --git a/spec/handler/go_squared_spec.rb b/spec/handler/go_squared_spec.rb
index 4d15bab..40a9192 100644
--- a/spec/handler/go_squared_spec.rb
+++ b/spec/handler/go_squared_spec.rb
@@ -5,8 +5,8 @@ def env
end
it 'will be placed in the head' do
- expect(described_class.position).to eq(:head)
- expect(described_class.new(env).position).to eq(:head)
+ expect(described_class.container_tag).to eq(:head)
+ expect(described_class.new(env).container_tag).to eq(:head)
end
describe "with events" do
diff --git a/spec/handler/google_adwords_conversion_spec.rb b/spec/handler/google_adwords_conversion_spec.rb
index a81dd15..695fef4 100644
--- a/spec/handler/google_adwords_conversion_spec.rb
+++ b/spec/handler/google_adwords_conversion_spec.rb
@@ -8,9 +8,9 @@ def env
end
it 'will be placed in the body' do
- expect(described_class.position).to eq(:body)
- expect(described_class.new(env).position).to eq(:body)
- expect(described_class.new(env, position: :body).position).to eq(:body)
+ expect(described_class.container_tag).to eq(:body)
+ expect(described_class.new(env).container_tag).to eq(:body)
+ expect(described_class.new(env, container_tag: :body).container_tag).to eq(:body)
end
describe "with events" do
diff --git a/spec/handler/google_analytics_spec.rb b/spec/handler/google_analytics_spec.rb
index 66d842c..22dd603 100644
--- a/spec/handler/google_analytics_spec.rb
+++ b/spec/handler/google_analytics_spec.rb
@@ -7,9 +7,9 @@ def env
end
it 'will be placed in the head' do
- expect(described_class.position).to eq(:head)
- expect(described_class.new(env).position).to eq(:head)
- expect(described_class.new(env, position: :body).position).to eq(:body)
+ expect(described_class.container_tag).to eq(:head)
+ expect(described_class.new(env).container_tag).to eq(:head)
+ expect(described_class.new(env, container_tag: :body).container_tag).to eq(:body)
end
describe '#ecommerce_events' do
diff --git a/spec/handler/google_tag_manager_spec.rb b/spec/handler/google_tag_manager_spec.rb
index 77f7b1d..38e0ff7 100644
--- a/spec/handler/google_tag_manager_spec.rb
+++ b/spec/handler/google_tag_manager_spec.rb
@@ -8,9 +8,9 @@ def env
end
it 'will be placed in the body by default' do
- expect(described_class.position).to eq(:body)
- expect(described_class.new(env).position).to eq(:body)
- expect(described_class.new(env, position: :head).position).to eq(:head)
+ expect(described_class.container_tag).to eq(:body)
+ expect(described_class.new(env).container_tag).to eq(:body)
+ expect(described_class.new(env, container_tag: :head).container_tag).to eq(:head)
end
describe "with events" do
@@ -31,10 +31,10 @@ def env
end
end
- describe "with dynamic tracker" do
+ describe "with dynamic container" do
subject { described_class.new(env, { container: lambda { |env| return env[:misc] }}).render }
- it 'will call tracker lambdas to obtain tracking codes' do
+ it 'will call container lambdas to obtain container codes' do
expect(subject).to match(%r{\(window,document,'script','dataLayer','foobar'\)})
end
end
diff --git a/spec/handler/vwo_spec.rb b/spec/handler/vwo_spec.rb
index 5b4fab6..27432e0 100644
--- a/spec/handler/vwo_spec.rb
+++ b/spec/handler/vwo_spec.rb
@@ -5,8 +5,8 @@ def env
end
it 'will be placed in the head' do
- expect(described_class.position).to eq(:head)
- expect(described_class.new(env).position).to eq(:head)
+ expect(described_class.container_tag).to eq(:head)
+ expect(described_class.new(env).container_tag).to eq(:head)
end
end
diff --git a/spec/integration/criteo_integration_spec.rb b/spec/integration/criteo_integration_spec.rb
index 77364ec..4d919dd 100644
--- a/spec/integration/criteo_integration_spec.rb
+++ b/spec/integration/criteo_integration_spec.rb
@@ -27,10 +27,10 @@
expect(page.find("body")).to have_content "window.criteo_q.push({\"event\":\"viewBasket\",\"item\":[{\"id\":\"P001\",\"price\":\"6.54\",\"quantity\":1},{\"id\":\"P0038\",\"price\":\"2.99\",\"quantity\":1}]});"
end
- describe 'adjust tracker position via options' do
+ describe 'adjust tracker container_tag via options' do
before do
setup_app(action: :criteo) do |tracker|
- tracker.handler :criteo, { set_account: '1234', position: :head }
+ tracker.handler :criteo, { set_account: '1234', container_tag: :head }
end
visit '/'
end
diff --git a/spec/integration/google_analytics_integration_spec.rb b/spec/integration/google_analytics_integration_spec.rb
index 14bf48b..320ba0f 100644
--- a/spec/integration/google_analytics_integration_spec.rb
+++ b/spec/integration/google_analytics_integration_spec.rb
@@ -16,10 +16,10 @@
expect(page.find("head")).to have_content('ga("send",{"hitType":"event","eventCategory":"button","eventAction":"click","eventLabel":"nav-buttons","eventValue":"X"})')
end
- describe 'adjust tracker position via options' do
+ describe 'adjust tracker container_tag via options' do
before do
setup_app(action: :google_analytics) do |tracker|
- tracker.handler :google_analytics, { tracker: 'U-XXX-Y', position: :body }
+ tracker.handler :google_analytics, { tracker: 'U-XXX-Y', container_tag: :body }
end
visit '/'
end
diff --git a/spec/support/fake_handler.rb b/spec/support/fake_handler.rb
index c40c1e5..b89c6e5 100644
--- a/spec/support/fake_handler.rb
+++ b/spec/support/fake_handler.rb
@@ -14,7 +14,7 @@ def track_me
class AnotherHandler < Rack::Tracker::Handler
- self.position = :body
+ self.container_tag = :body
def render
Tilt.new( File.join( File.dirname(__FILE__), '../fixtures/another_handler.erb') ).render(self)
diff --git a/spec/tracker/tracker_spec.rb b/spec/tracker/tracker_spec.rb
index c751ff7..11bc8f5 100644
--- a/spec/tracker/tracker_spec.rb
+++ b/spec/tracker/tracker_spec.rb
@@ -9,12 +9,12 @@ def dummy_alert
end
class BodyHandler < DummyHandler
- self.position = :body
+ self.container_tag = :body
end
class BodyOpeningHandler < DummyHandler
- self.position = :body
- self.exact_position = :opening
+ self.container_tag = :body
+ self.container_position = :opening
end
RSpec.describe Rack::Tracker do
@@ -83,7 +83,7 @@ def app
expect(last_response.body).to_not include("console.log('head');")
end
- it 'will inject the handlers in their exact_position' do
+ it 'will inject the handlers at their container_position in the container_tag' do
get '/body'
expect(last_response.body).to include("")
expect(last_response.body).to include("\n")
From a17b6c0bd8a328ee35071a5dae68ea1ce48d7475 Mon Sep 17 00:00:00 2001
From: Salim Hbeiliny
Date: Wed, 6 May 2015 16:41:48 +0200
Subject: [PATCH 3/6] it should still work when container_tag has attributes
---
lib/rack/tracker.rb | 4 ++--
spec/tracker/tracker_spec.rb | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/lib/rack/tracker.rb b/lib/rack/tracker.rb
index 30ac441..544e36c 100644
--- a/lib/rack/tracker.rb
+++ b/lib/rack/tracker.rb
@@ -56,9 +56,9 @@ def html?; @headers['Content-Type'] =~ /html/; end
def inject(env, response)
@handlers.each(env) do |handler|
if handler.container_position == :closing
- response.gsub!(%r{#{handler.container_tag}>}, handler.render + "#{handler.container_tag}>")
+ response.gsub!(%r{#{handler.container_tag}>}, handler.render + '\0')
else
- response.gsub!(%r{<#{handler.container_tag}>}, "<#{handler.container_tag}>" + handler.render)
+ response.gsub!(%r{<#{handler.container_tag}[^>]*>}, '\0' + handler.render)
end
end
response
diff --git a/spec/tracker/tracker_spec.rb b/spec/tracker/tracker_spec.rb
index 11bc8f5..455e528 100644
--- a/spec/tracker/tracker_spec.rb
+++ b/spec/tracker/tracker_spec.rb
@@ -34,7 +34,7 @@ def app
when '/' then
[200, {'Content-Type' => 'application/html'}, ['Hello world']]
when '/body' then
- [200, {'Content-Type' => 'application/html'}, ['bob here']]
+ [200, {'Content-Type' => 'application/html'}, ['bob here']]
when '/body-head' then
[200, {'Content-Type' => 'application/html'}, ['']]
when '/test.xml' then
@@ -85,7 +85,7 @@ def app
it 'will inject the handlers at their container_position in the container_tag' do
get '/body'
- expect(last_response.body).to include("")
+ expect(last_response.body).to include("")
expect(last_response.body).to include("\n")
end
end
From f89d54a022b7e5c07e3718da44a24b3b3eb8d44b Mon Sep 17 00:00:00 2001
From: Salim Hbeiliny
Date: Thu, 7 May 2015 09:41:45 +0200
Subject: [PATCH 4/6] new position dsl with :append and :prepend options
---
README.md | 9 ++++-----
lib/rack/tracker.rb | 10 ++++++----
lib/rack/tracker/criteo/criteo.rb | 2 +-
lib/rack/tracker/facebook/facebook.rb | 2 +-
.../google_adwords_conversion.rb | 2 +-
.../google_tag_manager/google_tag_manager.rb | 3 +--
lib/rack/tracker/handler.rb | 19 +++++++++++++------
spec/handler/criteo_spec.rb | 5 +++--
spec/handler/facebook_spec.rb | 5 +++--
spec/handler/go_squared_spec.rb | 5 +++--
.../handler/google_adwords_conversion_spec.rb | 6 +++---
spec/handler/google_analytics_spec.rb | 6 +++---
spec/handler/google_tag_manager_spec.rb | 6 +++---
spec/handler/vwo_spec.rb | 5 +++--
spec/integration/criteo_integration_spec.rb | 8 ++++----
.../google_analytics_integration_spec.rb | 4 ++--
spec/support/fake_handler.rb | 2 +-
spec/tracker/tracker_spec.rb | 7 +++----
18 files changed, 58 insertions(+), 48 deletions(-)
diff --git a/README.md b/README.md
index 6a0f9b0..6e92a00 100644
--- a/README.md
+++ b/README.md
@@ -418,11 +418,11 @@ Everything you're passing to the `handler` will be available as `#options` in yo
template, so you'll also gain access to the `env`-hash belonging to the current request.
Run your application and make a request, the result of the above template can be
-found right before ``. You can change the `container_tag` in your handler-code:
+found right before ``. You can change the `position` in your handler-code:
```ruby
class MyHandler < Rack::Tracker::Handler
- self.container_tag = :body
+ self.position body: :append
...
end
@@ -430,12 +430,11 @@ end
The snippet will then be rendered right before `")
expect(last_response.body).to include("\n