Tame your analytics libraries with Analytical

May 5, 2010

May 5, 2010

[wpseo_breadcrumb]

Categories

We recently integrated KISSMetrics tracking into our website (more on that in a future post!)… and I was once again faced with the annoying task of carefully updating the mess of javascript that was cluttering up our page in various places.  We’re data & analytics tracking freaks at TransFS.com… so we have a bunch of different analytics […]

46 Seconds to Discover Thousands of Wasted Dollars in your Business.

82% of companies find $12,000 wasted annually. How much are you losing?

nexus-feefighters-quiz-saving-money

We recently integrated KISSMetrics tracking into our website (more on that in a future post!)… and I was once again faced with the annoying task of carefully updating the mess of javascript that was cluttering up our page in various places.  We’re data & analytics tracking freaks at TransFS.com… so we have a bunch of different analytics packages in place on our site. Managing all of these packages and keeping the tracking javascript clean & simple had finally become a real pain point for me.

At various times, we’ve had Google Analytics, Clicky, MixPanel, and our own internal FunnelCake tracking code all monitoring our visitor traffic.  Each library requires specific javascript code to be added to the page; some insisting that the code be added to the top of the <body> element, while others suggesting that it be before the closing </body> tag.  To further complicate matters, we want to be able to trigger a manual track() function to track a specific event.  However, it isn’t always convenient to declare these tracking calls at the bottom of the page, or in a controller, or in any single location.  What if we want to track an action in a view?  How can we be sure that the corresponding library has been initialized at the time when the javascript code is inserted?  What if we want to declare a tracking event in a controller?  How can we easily send the same tracking event to all of the different analytics packages we have installed?

So, in a fury of frustration, I banged out a new rails gem for helping with this exact problem.  I’d like to introduce you to Analytical.  This gem is designed to be an all-purpose analytics front-end.  By providing a simple API to a variety of analytics libraries, it allows you to clean up your views and easily track events in your app without worrying about the details of the underlying analytics apis.  Even better, it gracefully deals with queuing up tracking commands for services, so that the tracking commands are always inserted after the initialization scripts have been added to your page.

So, how does it work?  You start off by adding a single line to your application controller:

    analytical :modules=>[:google, :clicky]

This tells analytical which packages you intend to use. You can define the api keys in config/analytical.yml, like so:

   google:
     key: UA-5555555-5
   clicky:
     key: 55555

Then, in your layout file, you need to add a few hooks so that Analytical can insert any initialization code for your modules:

    <!DOCTYPE html>
    <html>
      <head>
        <title>Example</title>
        <%= stylesheet_link_tag :all %>
        <%= javascript_include_tag :defaults %>
        <%= csrf_meta_tag %>
        <% analytical.identify current_user.id, :email=>current_user.email if current_user %>
        <%= raw analytical.head_javascript %>
      </head>
      <body>
        <%= raw analytical.body_prepend_javascript %>
        <%= yield %>
        <%= raw analytical.body_append_javascript %>
      </body>
    </html>

As you can see, I’ve also added a simple identify call to the template, so that we can tell our analytics modules about the current user (if they support per-user identification, like Clicky/KISSMetrics).

From there, using analytical to track events is dead simple. Track a url with:

    analytical.track '/a/really/nice/url'

And an event with:

    analytical.event 'Some Awesome Event', :with=>:data

… and these can be used anyplace in your app: views, controllers, templates, whatever. Since views are processed before templates, your commands will queued up and then inserted immediately after the corresponding analytics library has been initialized. This produces javascript code on your page that might look something like:

    <!-- Analytical Init: KissMetrics --> 
    <script type="text/javascript"> 
        var .... initialization javascript for KISSMetrics ...
    </script> 
    <script type='text/javascript'> 
        _kmq.push(["record", "Visited Tour", {}]);
    </script>

In this example, analytical.event 'Visited Tour' was called in the view… and the event was queued up so it could be inserted immediately after the KISSMetrics library was initialized.

But what about triggering a specific command that is not one of the standard calls that Analytical knows about (track, event, identify)? No problem… you can call any custom method on a module like so:

   analytical.clicky.special_tracking_method :that_only=>:clicky_supports

If you need to output javascript immediately without queuing it up for later insertion (to use in a javascript callback, for instance)… you can do this using the .now accessor:

   <%= analytical.now.track '/some/url' %>

outputs:

   clicky.log('/some/url');
   googleAnalyticsTracker._trackPageview("/some/url");

In our app, we wrap this into a convenience javascript function in our that looks like:

	var analytical_track = function(page){
		<%= analytical.now.track('page').gsub(/"page"/,'page') %>
	};
	var analytical_event = function(event, data){
		if (!data) { data = {}; }
		<%= analytical.now.event('event', {}).gsub(/"event"/,'event').gsub(/\"?\{\}\"?/,'data') %>
	};

This allows us to call

analytical_track('/some/url');

from our javascript, anywhere in the page, and it’ll hit every module that we have installed. (Note: we do have to be sure that if we use this javascript helper, that we only call it in ajax situations where the page is certain to be fully baked and all analytics libraries are initialized.)

That’s about it. We’ve had the gem in production for a while now, and it has really cleaned up our tracking code. However, I’d love to get some feedback on how it could be improved!

As of now, I have implemented support for Google Analytics, Clicky, and KISSMetrics… but the library is extremely easy to extend, so I’m hopeful that the community will add support for other services that people would like to use. You can find the code here: http://github.com/jkrall/analytical, so fork away!

Lastly, I’d like to call out the cool Snogmetrics library for providing a lot of the inspiration for Analytical. I stole some great ideas from that project, and adapted it for our broader needs. Thanks Theo!

Reduce Credit Card Processing Fees

with FeeFighters

[comments-template]

Recent Posts

In today’s business world, the point of sale (POS) system has become a key part of operations for retailers. The POS system is involved in several aspects of a business, such as inventory management, funds, and managing the inflow and outflow of products and services within a store. Due to its unique position in key […]

What Is Sales Tax Compliance Outsourcing? (SALT)Ever since the South Dakota v. Wayfair court ruling that you don’t need to have a presence in a state in order to be required to collect taxes on sales there, tax law has never quite been the same. If you need to collect taxes in many states and […]

Knowing how to properly collect sales taxes in different states and jurisdictions is incredibly complicated. Different tax jurisdictions have different laws and rates, but accountants and tax lawyers are expensive. Worse yet, a tax mistake due to ignorance of sales tax law can lead to an audit or penalty that will cost your business a […]

Chargebacks are debit or credit card charges that have been disputed by customers. Sometimes these come in the form of chargeback fraud, but other times they are legitimate. When a chargeback happens, you have to deal with the acquiring bank and other entities in order to dispute it. Regardless of the reason for any given […]

© 2019 – FeeFighters, LLC – Call Us – (646) 448-8804

PO BOX 1459, MOUNTAINSIDE, NJ 07092

×