Tutorials - Big bits of code to help you do more
Quick & Easy Google Analytics with SiteConfig
Tweet24 November 2010 | | | Supports v2.4
Many people need a way to monitor their website, and while it's pretty easy to add the code to a SilverStripe template, or even the basic Page_Controller, I thought I would show how I modularized and made it accessible from the SiteConfig area of the CMS.
Module Structure
First, you're gonna need the directory setup for your GoogleAnalytics module. Mine looks something like:
- GoogleAnalytics (main module folder)
---- _config.php
---- code
-------- GoogleAnalytics.php
-------- GoogleAnalyticsExtender.php
Code
Now you need the code for your GoogleAnalytics object in SiteConfig, where you actually store the Analytics ID. Mine is very simple, and looks something like this:
GoogleAnalytics/code/GoogleAnalytics.php
<?php
class GoogleAnalytics extends DataObjectDecorator
{
function extraStatics(){
return array(
'db' => array(
'GoogleAnalyticsAccountID' => 'Text'
)
);
}
public function updateCMSFields(FieldSet &$fields) {
$fields->addFieldToTab('Root.Main', new TextField('GoogleAnalyticsAccountID', 'Google Analytics Code (Example: UA-XXXXXXXX-X)', '', 13));
}
function contentControllerInit($controller) {
}
}
It basically just extends the SiteConfig with a DataObjectDecorator to include a GoogleAnalyticsAccountID, then updates the CMS fields so you can set it and save it. In retrospect, it would probably be nice to have a validator on that field that only accepts an appropriately formatted ID, but we'll keep it simple for now.
Next, you need something that extends your pages to include the Javascript with the Analytics code in it, so Google can keep track of your Page Views, Bounces, and all that other important data you crave!
GoogleAnalytics/code/GoogleAnalyticsExtender.php
<?php
class GoogleAnalyticsExtender extends DataObjectDecorator
{
function contentControllerInit($controller) {
$accountId = $this->owner->SiteConfig->GoogleAnalyticsAccountID;
if(preg_match("/UA-[0-9]{7,}-[0-9]{1,}/", $accountId)) {
Requirements::customScript(<<<JS
var _gaq = _gaq || [];
_gaq.push(['_setAccount', '$accountId']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
JS
);
}
}
}
This basically says "If the site ID is a (relatively, I'm terrible at regular expressions, and any improvements are welcome!) valid GoogleAccountID, then add the custom Javascript to anything that is, or extends from a Page class. So all of you custom pages, like Staff Page, or EventPage, or BlogEntry will all get the analytics JS as well.
Lastly, you need to tell SilverStripe to add this functionality to the two objects: Page, and SiteConfig. You can do this in your _config.php file.
GoogleAnalytics/_config.php
<?php
Object::add_extension('SiteConfig', 'GoogleAnalytics');
Object::add_extension('Page', 'GoogleAnalyticsExtender');
And you're done! You should now have a brand new field in your SiteConfig where you can set and save your GoogleAnalyticsAccountID, saving you all that agitating time adding it to your Page_Controller manually. Plus, you've got a module you can reuse on any SilverStripe site!
16 Comments
RSS feed for comments on this page RSS feed for all comments
johnny
24/11/2010 7:15pm (1 year ago)
in GoogleAnalyticsExtender - your source code highlighter probably cut this:
bad one:
var _gaq = _gaq []; --> the || is missing
good one:
var _gaq = _gaq || [];
MRKDevelopment
25/11/2010 2:05am (1 year ago)
Does this work for a multi-site situation ?
I'll do my own tests but it didn't seem like it would be from first read.
Ty Barho
25/11/2010 7:07pm (1 year ago)
johnny, good catch, and yeah it was the source code highlighter. changed and resubmitted...
Ty Barho
25/11/2010 7:10pm (1 year ago)
MRK, I've never actually tried to track multiple domains like that, but I did dig up an article from Google that looks like you just need to do some simple editing to the tracking code, here: http://www.google.com/support/analytics/bin/answer.py?hl=en&answer=55503
It's probably obvious, but you would change that in the Requirements block of GoogleAnalytics/code/GoogleAnalyticsExtender.php, where you write your embedded JS.
MRKDevelopment
26/11/2010 12:24am (1 year ago)
Hi Ty,
Thanks for that. I was actually thinking of having two sets of tracking code for different sites.
For examples, lets say we do a promotional site of the main site for a customer they would want that GA account to be on its own to measure the results of that particular campaign.
Currently we use the template to do this but I'm thinking I might extend the site config to see if their is an alternative.
Thanks again for the feedback.
guy van bael
02/12/2010 2:38pm (1 year ago)
Hi Ty,
I tried this on my testsite (locally with mamp) and if i copy the folder structure with the files, i can't browse to the site anymore (localhost:8888/testsite). A dev/build doesn't work either
Can you tell me what am i doing wrong?
Thanx in advance
guy
Vinko
07/12/2010 4:50pm (1 year ago)
I'm having the same problem with blank pages, just as guy van bael.
mathiasmex
08/12/2010 10:29am (1 year ago)
Hi guy van bael,
Hi Vinko,
make sure in GoogleAnalyticsExtender the last "JS"(line 21) and the following ");" (line 22) are at the beginning of the line, without white space. That should solve the problem of blank page.
moloko_man
07/01/2011 5:13am (1 year ago)
Very simple and nice example. Thanks for this.
A quick question on the Google Analytics Account ID.
Is there any security issues with storing the ID in the database or is there any reason you can't declare it in your _config.php file?
Ty Barho
21/01/2011 4:36pm (1 year ago)
moloko_man,
The security for Google Analytics is based on domain verification with Google. If you look at the page source for a major site, like, let's say Twitter, you can see their account ID in the bottom of their page source. However, if you tried to add that ID to your page, Google would say the domain isn't verified, and you'd have to somehow either add the verification HTML or CNAME record to the twitter Server / DNS Server, respectively.
So in short, there aren't really any security issues with storing the ID like, since it's blatantly visible on the page no matter how you use it.
Hope that helps!
oillescas
25/02/2011 2:23pm (1 year ago)
I have developed a module based on this paper to integrate Piwik in SilverStripe you can found here http://code.google.com/p/silverstripe-module-piwik-analytics/
Jan
12/10/2011 9:41pm (7 months ago)
Hello, thanks for this interesting module. I've tried and copied everyting to my setup. I could set the analytics code in the cms, but nothing comes up in my pages.
Any idea what i could have missed?
Tnx.
Jan
18/10/2011 9:32am (7 months ago)
Ok, I found my Google Analytics code did not match the criteria of the regex so the code wasn't added. If I removed the check, everything works fine. I have to find out what the correct regex-check is.
Jan
18/10/2011 9:47am (7 months ago)
One other thing: I've changed in GoogleAnalyticsExtender.php the requirements:javascript to requirements:insertHeadTags because Google Analytics asks to put your script in the head section
Steven
14/12/2011 11:10am (5 months ago)
@Jan, the reason that the regex code didn't work, is that where the number are checked, it's looking for 7 in the first batch and only 1 at the end.
Google Analytics Tracking IDs can have more than 1 digit at the end, and less than 7 in the middle.
The following regex template should match any GA ID that you throw at it.
I'm no regex expert, just that this works for me across the different IDs I've used it with:
/UA-[0-9]{7,}-[0-9]{1,}/
Steven
14/12/2011 11:18am (5 months ago)
Sorry, I meant it's looking for 7 or more in the first batch and 1 or more in the second batch.
Since the first batch can be as short as 5, this is where it's failing, I've also realised that my previous post has the regex from the post, rather than mine. (Copy/paste fail)
Try this one:
"/UA\-[0-9]*\-[0-9]*/"
Post a comment ...
You cannot post comments until you have logged in. Login Here.