Skip to content

Instantly share code, notes, and snippets.

@2called-chaos
Last active August 29, 2015 14:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 2called-chaos/f29186330d2d1a8af9c8 to your computer and use it in GitHub Desktop.
Save 2called-chaos/f29186330d2d1a8af9c8 to your computer and use it in GitHub Desktop.
Piwik in Ruby on Rails with Turbolinks (and proxy)
# Heavily inspired by https://gist.github.com/erpe/8586565
# Call `PiwikAnalytics.init()` once per document load, e.g.:
# unless $(document).data("piwik_loaded")
# PiwikAnalytics.init()
# $(document).data("piwik_loaded", "loaded")
class @PiwikAnalytics
@trackerUrl: -> "//analytics.example.net"
@siteId: ->
switch document.location.hostname.toLowerCase()
when "de.example.com" then "1"
when "fr.example.com" then "2"
else "3"
# ========
# = Core =
# ========
@init: ->
return if PiwikAnalytics.isLocalRequest()
# Piwik Analytics depends on a global _paq array. window is the global scope.
window._paq = []
window._paq.push(['setTrackerUrl', PiwikAnalytics.trackerUrl() + '/piwik.php'])
window._paq.push(['setSiteId', PiwikAnalytics.siteId()])
window._paq.push(['enableLinkTracking'])
# Create a script element and insert it in the DOM
pa = document.createElement("script")
pa.type = "text/javascript"
pa.defer = true
pa.async = true
pa.src = PiwikAnalytics.trackerUrl() + '/piwik.js'
firstScript = document.getElementsByTagName("script")[0]
firstScript.parentNode.insertBefore pa, firstScript
# If Turbolinks is supported, set up a callback to track pageviews on page:change.
# If it isn't supported, just track the pageview now.
if typeof Turbolinks isnt 'undefined' and Turbolinks.supported
document.addEventListener "page:change", (->
PiwikAnalytics.trackPageView("refresh")
), true
else
PiwikAnalytics.trackPageView()
@isLocalRequest: ->
host = PiwikAnalytics.documentDomainIncludes
return true if host "localhost"
return true if host "127.0.0.1"
return true if host "staging"
false
@documentDomainIncludes: (str) -> document.domain.indexOf(str) isnt -1
@push: (ary) -> window._paq.push(ary)
@trackPageView: (url) ->
unless PiwikAnalytics.isLocalRequest()
if url
if url == "refresh"
window._paq.push ["setCustomUrl", document.location.href]
window._paq.push ["setDocumentTitle", document.title]
window._paq.push ["trackPageView"]
window._paq.push ["enableLinkTracking"]
else
window._paq.push ["trackPageView", url]
else
window._paq.push ["trackPageView"]
# =========================================
# = Add your custom tracking methods here =
# =========================================
# @trackEcommerceView: (sku) ->
# unless PiwikAnalytics.isLocalRequest()
# window._paq.push(['setEcommerceView', sku])
# @trackGoal: (id, price=0 ) ->
# unless PiwikAnalytics.isLocalRequest()
# window._paq.push(['trackGoal', id, price])
# @addEcommerceItem: (sku, name, category, price) ->
# unless PiwikAnalytics.isLocalRequest()
# window._paq.push(['addEcommerceItem', sku, name, category, parseFloat(price)])
# @trackEcommerceOrder: (order_id, revenue) ->
# unless PiwikAnalytics.isLocalRequest()
# window._paq.push(['trackEcommerceOrder', order_id, parseFloat(revenue)])
# @trackEcommerceCartUpdate: (sum) ->
# unless PiwikAnalytics.isLocalRequest()
# window._paq.push(['trackEcommerceCartUpdate', parseFloat(sum)])
# NOTE: requires HTTParty gem
#
# - Change your trackerUrl to your domain, no need to change the js location as with the PHP proxy!
# - Add to your config/routes.rb:
# get 'piwik' => 'piwik#proxy'
class PiwikController < ApplicationController
# Required because you will get this errors otherwise (don't ask me why):
# Security warning: an embedded <script> tag on another site requested protected JavaScript.
# If you know what you're doing, go ahead and disable forgery protection on this action to
# permit cross-origin JavaScript embedding.
skip_before_filter :verify_authenticity_token
def proxy
# Edit the line below, and replace http://your-piwik-domain.example.org/piwik/
# with your Piwik URL ending with a slash.
# This URL will never be revealed to visitors or search engines.
piwik_url = 'http://your-piwik-domain.example.org/piwik/'
# Edit the line below, and replace xyz by the token_auth for the user "UserTrackingAPI"
# which you created when you followed instructions above.
token_auth = 'xyz'
# Maximum time, in seconds, to wait for the Piwik server to return the 1*1 GIF
timeout = 5
# Don't edit below here!
if params[:format] == "php"
headers = { "User-Agent" => request.user_agent }
data = params.except(:action, :controller, :format).merge(cip: request.remote_ip, token_auth: token_auth)
gif = HTTParty.get("#{piwik_url}piwik.php?#{data.to_query}", timeout: timeout, headers: headers).response.body
send_data gif, type: :gif
else
# Rack::Cache will take care of the heavy lifting
response.headers["Expires"] = 1.hour.from_now.httpdate
render js: HTTParty.get("#{piwik_url}piwik.js").response.body
end
end
end
@erpe
Copy link

erpe commented Apr 29, 2015

the additional
window._paq.push ['enableLinkTracking']
in @trackPageView causes piwik to error on page-reloads:

The method enableLinkTracking is registered more than once in "_paq" variable. Only the last call has an effect. Please have a look at the multiple Piwik trackers documentation: http://developer.piwik.org/guides/tracking-javascript-guide#multiple-piwik-trackers

but nice improvement anyway

thx

@2called-chaos
Copy link
Author

@erpe yeah you are right but it's only a warning and we couldn't find any disadvantage due to this. I removed the warning from the js code. As it says "only the last call has an effect" and that's okay. Otherwise you won't track after loading a page via turbolinks.

If I'm not mistaken the warning doesn't show up anymore in the new releases.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment