Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 1 addition & 6 deletions lib/rack/tracker.rb
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,7 @@ def html?; @headers['Content-Type'] =~ /html/; end

def inject(env, response)
@handlers.each(env) do |handler|
# Sub! is enough, in well formed html there's only one head or body tag.
# Block syntax need to be used, otherwise backslashes in input will mess the output.
# @see http://stackoverflow.com/a/4149087/518204 and https://github.com/railslove/rack-tracker/issues/50
response.sub! %r{</#{handler.position}>} do |m|
handler.render << m.to_s
end
handler.inject(response)
end
response
end
Expand Down
23 changes: 18 additions & 5 deletions lib/rack/tracker/google_tag_manager/google_tag_manager.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,29 @@ def write
end
end

# 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
def inject(response)
# Sub! is enough, in well formed html there's only one head or body tag.
# Block syntax need to be used, otherwise backslashes in input will mess the output.
# @see http://stackoverflow.com/a/4149087/518204 and https://github.com/railslove/rack-tracker/issues/50
response.sub! %r{<head>} do |m|
m.to_s << self.render_head
end
response.sub! %r{<body>} do |m|
m.to_s << self.render_body
end
response
end

def container
options[:container].respond_to?(:call) ? options[:container].call(env) : options[:container]
end

def render
Tilt.new( File.join( File.dirname(__FILE__), 'template', 'google_tag_manager.erb') ).render(self)
def render_head
Tilt.new( File.join( File.dirname(__FILE__), 'template', 'google_tag_manager_head.erb') ).render(self)
end

def render_body
Tilt.new( File.join( File.dirname(__FILE__), 'template', 'google_tag_manager_body.erb') ).render(self)
end

def self.track(name, *event)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<% if container %>
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=<%= container %>"
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
<% end %>
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,9 @@ dataLayer.push(
);
</script>

<noscript><iframe src="//www.googletagmanager.com/ns.html?id=<%= container %>"
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'//www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','<%= container %>');</script>

<% end %>
10 changes: 10 additions & 0 deletions lib/rack/tracker/handler.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,16 @@ def render
raise NotImplementedError.new('needs implementation')
end

def inject(response)
# Sub! is enough, in well formed html there's only one head or body tag.
# Block syntax need to be used, otherwise backslashes in input will mess the output.
# @see http://stackoverflow.com/a/4149087/518204 and https://github.com/railslove/rack-tracker/issues/50
response.sub! %r{</#{self.position}>} do |m|
self.render << m.to_s
end
response
end

def self.track(name, event)
raise NotImplementedError.new("class method `#{__callee__}` is not implemented.")
end
Expand Down
10 changes: 2 additions & 8 deletions spec/handler/google_tag_manager_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,6 @@ 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)
end

describe "with events" do
describe "default" do
def env
Expand All @@ -23,15 +17,15 @@ def env
}}
end

subject { described_class.new(env, container: 'somebody').render }
subject { described_class.new(env, container: 'somebody').render_head }
it "will show events" do
expect(subject).to match(%r{"page":"Cart","price":50,"content_ids":\["sku_1","sku_2","sku_3"\]})
end
end
end

describe "with dynamic tracker" do
subject { described_class.new(env, { container: lambda { |env| return env[:misc] }}).render }
subject { described_class.new(env, { container: lambda { |env| return env[:misc] }}).render_head }

it 'will call tracker lambdas to obtain tracking codes' do
expect(subject).to match(%r{\(window,document,'script','dataLayer','foobar'\)})
Expand Down
5 changes: 3 additions & 2 deletions spec/integration/google_tag_manager_integration_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@
subject { page }

it "embeds the script tag with tracking event from the controller action" do
expect(page.find("body")).to have_content 'GTM-ABCDEF'
expect(page.find("body")).to have_content "dataLayer.push( {\"click\":\"X\",\"price\":10}, {\"transactionProducts\":[{\"sku\":\"DD44\",\"name\":\"T-shirt\"},{\"sku\":\"DD66\",\"name\":\"Jeans\"}]} );"
expect(page.find("head")).to have_content 'GTM-ABCDEF'
expect(page.find("head")).to have_content "dataLayer.push( {\"click\":\"X\",\"price\":10}, {\"transactionProducts\":[{\"sku\":\"DD44\",\"name\":\"T-shirt\"},{\"sku\":\"DD66\",\"name\":\"Jeans\"}]} );"
expect(page.find("body")).to have_xpath '//body/noscript/iframe[@src="https://www.googletagmanager.com/ns.html?id=GTM-ABCDEF"]'
end

end