This is the first installment in a series about implementing google analytics (with the new data export api) in Umbraco, so you can get your sites statistics in your CMS (where it should be). This post only deals with getting the section up and running, so everything is prepared for the next installment, which will deal with the actual statistics.
As you can see in my previous post I have been giving a shot at porting the analytics api to the .NET client library. Having the availability of analytics in Googles .NET client library would make the code and usage much prettier
…. and it would probably make the implementation in a sysmtem like Umbraco much easier.
Well back to the topic. When I first saw the announcement of the analytics api I touhgt that an ideal implementation would be a CMS like Umbraco (or Sitecore for that matter), and when Niels Hartvig twitted about the challenge to create an analytics plugin for Umbraco I knew it was my calling. Okay, not a calling in a biblical sense, but an obvious excuse to get started.
So how do one get started… I thought the best solution would be to create a statistics section and keep the style of the Umbraco sections. Lucky for me there is predefined css classes and icon for a statistics section, so I can concentrate on how to implement the functionality.
I haven’t actually created a new section before, so I started off by browsing the Umbraco forums for tips and inspiration, which I found in a two piece article on simm.dk – Part one & two. The article shows which tables in the database needs to be updated with info on the new section, which was a great help to get started.
I started by creating a new entry for my statistics app in the umbracoApp table:
The fields was filled with the following data:
- sortOrder: 9
- appAlias: stats
- appIcon: .traystats
- appName: Statistics
- appInitWithTreeAlias: NULL
You can find a description of the diffirent fields in the article on simm.dk, so I won’t go too much into detail about the above. The important thing here is to note the ‘appAlias’, which is used to reference the application in the next two tables that also has to be updated with some data about the application. The classname ‘.traystats’ is already present in the css, so we don’t need to change or anything special here – lucky me/us.
Next table that has to be changed in order for the statistics section to show in Umbraco is umbracoAppTree:
The fields was filled with the following data:
- treeSilent: False
- TreeInitialize: True
- treeSortOrder: 0
- appAlias: stats
- treeAlias: stats
- treeTitle: Statistics
- treeIconClosed: folder.gif
- treeIconOpen: folder_o.gif
- treeHandlerAssembly: Sitereactor.GoogleAnalytics
- treeHandlerType: LoadStatTree
- action: NULL
Again you’ll find a very nice description of the different fields in the article on simm.dk. The most important part here is probably the treeHandlerAssembly and treeHandlerType, which I have set to my custom assembly that will make up the Google Analytics section and the class which will load the tree (treeHandlerType) is set to LoadStatTree.
The Open and Closed tree icons are is standard, as I don’t want to do anything special on this part as of now.
I want to make a special note on the appAlias, one thing that I missed in the articles on simm.dk. You might want to add a key of the appAlias to the language xmls, which are located in /umbraco/config/lang/ (en.xml for the english language), otherwise the title on the treelist could end up being just [stat] (which isn’t very pretty). Look for the following area tag:
<area alias="sections"> and add the following key <key alias="stats">Statistics</key>
The next table is easy
Its just mapping the user(s) to the app/section – in this case I only have a single admin user who I want to give access.
The default admin user id is zero, so just add that and the appAlias and the table editing is done.
Now on to the coding.
I started off by trying the code example in the last of the two articles on simm.dk, but couldn’t actually get it to work so I browsed through the Umbraco source code to see how the User and Member sections are built. The way these two classes (loadUsers and loadMembers) are built is fairly simple and you can find them plus all the other classes, which loads treelists in Umbraco in the following folder: umbraco 4.0.1 source\umbraco\presentation\umbraco\Trees.
So to setup the code that loads the tree menu I created a class, which implements BaseTree – an abstract class that implements the ITree interface.
Example: public class LoadStatTree : BaseTree
This implementation implies that the following three clases are implemented in the LoadStatTree class:
- protected override void CreateRootNode(ref XmlTreeNode rootNode)
- public override void RenderJS(ref StringBuilder Javascript)
- public override void Render(ref XmlTree tree)
CreateRootNode simply does what the name implies – creates the root node for the current section. This can be implemented as follows:
rootNode.Icon = FolderIcon; //Standard icon for a folder
rootNode.OpenIcon = FolderIconOpen; //Standard icon for an open folder
rootNode.NodeType = TreeAlias; //Alias of the current tree
rootNode.NodeID = "-1"; //Start node should be set to minus in order to not interfer with the normal structure/nodetree.
RenderJS is used to render Javascript output to the browser, which (from the actually section in Umbraco) is used to open the webform with the dashboard/TabView (right side of the screen). Here is an example:
Javascript.Append(
@"
function openStats(id) {
parent.right.document.location.href = stats/statsDashboard.aspx?id=' + id;
}
");
In the sample code, which you will find at the end of this post the webform that is opened simply shows a Hello World text. In order for the dashboard to look correct and in keeping with the look and feel of Umbraco it would be a good idea to implement the TabView control. In the next post I’ll show you how it can be done and how I have used it.
The last method Render is used to programmatically create the tree menu using the XmlTree. For this example I have simply created four items in the menu using the XmlTreeNode like this:
XmlTreeNode xNode = XmlTreeNode.Create(this);
xNode.NodeID = "0";
xNode.Text = "Menu Item 1"; //Name
xNode.Action = "javascript:openStats(0);";
xNode.Icon = "folder.gif";
xNode.OpenIcon = "folder_o.gif";
tree.Add(xNode);
Okay, so now the tree menu is in place and we can concentrate on the content and how and what of the analytics statistics to show on the dashboard.
While we wait for a finished version of the analytics data export api implemented in the .NET client library, this article is a good place to start for using the available api in C#: Introducing Google Analytics API with asp.net / C#. It could of course be implemented using javascript, but not sure how well it would fit into the existing context of Umbraco. I have yet to try it out, but I fear that it will interfer with some of the existing javascript used by the Umbraco client and that the login functionality won’t be too smooth. But maybe initializing the login with some jQuery appended to the browser might do the trick. Anyway, I will look into both possibilities untill the next post where there will be an actual implementation of the google analytics data api.
Here is the code sample, which implements the above examples (and which will also be expanded with an implementation of google analytics).
And here is a screenshot of the results of the examples and code given in this post:




This looks like a great start and I look forward to your finished attempt of this new section/plugin/tool for Umbraco. It is going to rock !
Warren
Hiya just as thought to your great Google Anlaytics Umbraco implmentation.
I have an idea that you may want to implement into this package.
It would be cool to have a new Context menu item in the content section.
So for example I right click on my contact page node and select “Statistics” from the context menu.
This will then take me to the your NEW stats section with the specific stats for that node/page.
Richard Soeteman has a great post on using events to add a new item to the context menu.
http://www.richardsoeteman.net/PermaLink,guid,f470b6cf-40da-4aa9-a0d9-7b984fe9bf59.aspx
And here is a direct link to his example code on it
http://www.richardsoeteman.net/ct.ashx?id=f470b6cf-40da-4aa9-a0d9-7b984fe9bf59&url=http%3a%2f%2fwww.richardsoeteman.net%2fdownloads%2fUmbraco%2funpublishmenuitem.zip
I hope this idea helps you out.
Warren
Yes, this is a very good idea. I think it would be a very nice feature to have access to stats for the specific page/node in the Context menu. This would make the very specific statistics (like pageviews etc.) more accessable for the user.
I could add an entry to the dashboard config … I haven’t used it before, but it seems like a good option to add tabs to the nodes in the Content section. Not sure if this is what you had in mind?
Hi glad you agree that it is a good idea and I think it will be the best workflow for end users.
I was not suggesting about adding a tab to the content node itself, as you can specify an url to redirect to.
So in this case we could goto the NEW Statistics section that you have created and load a specific usercontrol passing in the nodeID to give us the specifc stats.
Feel free to email me or add me on MSN (same as email) to talk about this idea further if I am not making sense.
Warren
Ahh, okay I get it. My thougts were another place.
I will put it on the todo list
Hi,
Great article. I hoep you are tagging this article as a methodology for adding any type of application to Umbraco not just Analytics. It’s a great primer!!!
I’ve taken a look at the API with C# link you supplied and I integrated it with http://code.google.com/apis/chart. My clients are going to love this!
If you need any help or would like to collaborate give me a shout.
Matt
Cool… Nice to hear!
And agree that the Google Chart API is a very good addition. During the last couple of weeks I have become more and more aware of the usefullness of the google apis. They really put out some nice stuff for us developers to use!
Hi,
A great article, I agree with Matt’s comments above that it is a good primer for other things too. Infact I might be coming back as I have an idea where I will need to do this, and you might just have given me the inspiration to get it done
Cheers, Chris