Message
back to the journal

Tracking TiddlyWiki with Google Analytics

July 5th, 2007

Logo ga Since we recently redeveloped the Osmosoft web site, we figured that we had better have some decent analytics on the site to monitor the activity. Google Analytics is perfectly good enough for our needs, and so I set about implementing it.

After signing up for a free Google Analytics account, it is a simple task to start tracking the hits on your site. You just need to add the javascript code that google generates for you onto into your code. The best way to do this in TiddlyWiki, is to modify the MarkupPostHead tiddler. This tiddler exists precisely for this kind of task. It inserts code into the end of the Head of your TiddlyWiki page.

The code you insert here looks something like this:

<script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
</script;
<script type="text/javascript">
  _uacct = "UA-123456789";
  urchinTracker();
;/script>

With this code in place, Google will start collecting information about the traffic to your site and present it to you via your Google Analytics account. But there is a problem, and that is that you really want to know what content your visitors are looking at within your site. You want their navigation in your site to be recorded too. On a traditional site, that’s no problem. Each page just has this same bit of javascript included and Google can register hits on each page. In TiddlyWiki however, everything happens within a single page so this kind of mechanism won’t quite do the job.

Thankfully both Google Analytics and TiddlyWiki are flexible enough for us to find a pretty simple solution.

Google Analytics allow you to register a ‘hit’ using a javascript function call, so we can tell them whenever a tiddler has been opened. The function call looks something like this:

urchinTracker('/destination');

We can pass this function any string we like (although it must begin with a ‘/’) and Google Analytics will register a hit on that ‘destination’. Now, how do we make TiddlyWiki call this function whenever a tiddler is opened? It turns out that this is also pretty simple.

As you would expect, there is a javascript function that is called whenever a tiddler needs to be opened. The function is story.displayTiddler and we really want to extend that to include our urchinTracker call.

My first instinct was to open up the source of the page and look for that javascript function and simply include urchinTracker call, and that would work just fine, but it’s the wrong way to go. It just isn’t good practice to start hacking at the core pf an application if an alternate solution exists. And it does. There is a useful concept in javascript of overriding functions. This allows you to replace or extend an existing function, while leaving it safe and intact. A simple example of this is below.

// Copy the function we want to override so that we can call to it later 
old_function = existingFunction;
 
// Re-define the function to include whatever additional code we need.
existingFunction = function()
{
  // Extend the function with new functionality.
  alert('Do something new!');
 
  // Call the original function.
  old_function(arguments);
}

This works nicely and we can apply this to the story.displayTiddler function like so:

var TiddlyLock = {}; // Create a namespace for our new function.
TiddlyLock.displayTiddler = story.displayTiddler;
story.displayTiddler = function(srcElement,titles,template,unused1,unused2,animate,unused3)
{
  if (urchinTracker) { urchinTracker('/' + titles); }
  TiddlyLock.displayTiddler.apply(this,arguments);
}

So we can add this to the javascript code of TiddlyWiki and we haven’t edited any of its’ existing functions, we have simply extended it. But even this is not ideal. We have still made changes to the TiddlyWiki code. The best thing to do is simply to insert this javascript into a tiddler. I created a tiddler called UrchinSupport and inserted our code into it. Then, I tagged this new tiddler with the tag ’systemConfig’, this makes sure that TiddlyWiki knows to include the code it contained. After saving the TiddlyWiki and reloading, the javascript from all the systemConfig tiddlers is included and we are off to the races.

One final detail was to wrap the code in triple braces. This just formats the code as pre-formatted text in the tiddler display and makes it a little easier for us to read.

{{{
 
  // Overide displayTiddler function to also Google Analytics urchin.
  var TiddlyLock = {}; // Create a namespace for our new function.
  TiddlyLock.displayTiddler = story.displayTiddler;
  story.displayTiddler = function(srcElement,titles,template,unused1,unused2,animate,unused3)
  {
    if (urchinTracker) { urchinTracker('/' + titles); }
    TiddlyLock.displayTiddler.apply(this,arguments);
  }
 
}}}

I hope that all makes sense and helps if you are trying to implement Google Analytics in TiddlyWiki yourself. If you have any questions, please feel free to post them in the comments section.

Update

Further to the above, Christopher Lakey has written up an excellent evolution of this technique which can be found on his blog.

4 Responses to “Tracking TiddlyWiki with Google Analytics”

  1. Chad,

    Thanks for this. I’ve been looking for this functionality for quite some time. However, after following your instructions, none of my tiddlers work (i.e. I can’t get any of them to open). Any suggestions on what could be the problem? The problem occurs once I add the UrchinSupport tiddler into my tiddlywiki file.

  2. PhilHawksworth,

    Chad,

    If you omit the additional function call from the new story.displayTiddler function, do you still encounter an error?

    That is, if you comment out the line:

    if (urchinTracker) { urchinTracker(’/’ + titles); }

    I’m wondering if you are having a problem calling google’s urchinTracker function which is halting the execution of the next line - which opens a tiddler.

    If you try that, it might help us figure out where the problem might be.

    You could also make sure that you are correctly copying the original function into TiddlyLock.displayTiddler by alerting that function. Try replacing the line:

    if (urchinTracker) { urchinTracker(’/’ + titles);

    with:

    alert(TiddlyLock.displayTiddler);

    just to be sure that you are capturing the function so that it can be called. Be aware though that if you have lots of tiddler open by default at startup, when you reload your page, you will get an alert for every tiddler.

    Let me know how you get on and we’ll see of we can get to the bottom of this.

    Good luck. P

  3. Chad,

    Thanks Phil. Your troubleshooting tips were helpful. It turned out that I was only experiencing issues on one particular computer and it wasn’t the fault of the code (which doesn’t surprise me!) Thanks again for your help.

  4. PhilHawksworth,

    Hooray! Thanks for posting that, Chad. I’m glad to hear that it’s all sorted.

WordPressRSSXHTMLCSS