I’ve recently been looking at how I can use Google Analytics to track website usage of content based on the category it has been assigned. We are using META tags in the page headings to store the category name and title of the content.
Google have just rolled out a bunch of excessively handy features allowing custom variables in their most recent update to the analytics package, unfortunetly my Analytics account hasn’t yet been updated to include them. As a fall back I’ve used the Event Tracking functionality instead.
At the bottom of each page which I want to track the category of, added the following code;
-
-
<script type="text/javascript">
-
var pageTracker = _gat._getTracker("<%= googleAnalyticsId %>");
-
-
function getMeta(name) {
-
var metas = document.getElementsByTagName(‘META’);
-
for (var i = 0; i < metas.length; i++){
-
if (metas[i].getAttribute(‘NAME’) == name){
-
return metas[i].getAttribute(‘CONTENT’);
-
}
-
}
-
return "null";
-
}
-
-
try {
-
var cat = getMeta("CATEGORY");
-
var title = getMeta("ARTICLE_NAME");
-
-
if(cat != "null" && title != "null"){
-
pageTracker._trackEvent(‘Category’,cat,title);
-
}
-
}catch(ex){
-
/* do nothing */
-
}
-
pageTracker._trackPageview();
-
</script>
-
Using this codes means that I can put these meta tags into the headings of any page;
-
-
<meta name="CATEGORY" content="Analytics" />
-
<meta name="ARTICLE_NAME" content="Custom Variables" />
-
And Google Analytics will track the my each of my articles based on the category they have been tagged with.
I’m currently developing ten tonne of portlets using the Spring Portlet MVC framework. It’s been a frustrating but rewarding experience. I’ve been struggling with general documentation and examples for a while, and I wanted to make a quick post about a problem I’ve been having. Mainly because I found lots of people with similar issues, but no help at a resolution.
I’ve been using the AbstractWizardFormController, and over-riding the
-
-
public ModelAndView showForm
(RenderRequest request, RenderResponse response,
BindException errors
) throws Exception
-
method to display my view and the
protected Object formBackingObject(PortletRequest request) throws Exception
method to populate my command bean.
My XML looked like this;
-
-
<bean id="menuSpotlightController" class="uk.co.smileham.cms.controller.edit.SpotlightController">
-
<property name="viewName" value="spotlightMenu" />
-
<property name="commandName" value="preferenceCommand" />
-
<property name="commandClass" value="uk.co.smileham.cms.model.PreferenceCommand" />
-
</bean>
-
This all seemed fine to me, however whenever I then tried to use the porlet I’d have a huge exception that went something along the lines of;
-
-
2009-10-21 14:04:28,765 ERROR [http-8080-Processor19] org.springframework.web.servlet.tags.form.SelectTag – Neither BindingResult nor plain target object for bean name ‘preferenceCommand’ available as request attribute
-
java.
lang.
IllegalStateException: Neither BindingResult nor plain target object
for bean name
‘preferenceCommand’ available as request attribute
-
at org.springframework.web.servlet.support.BindStatus.<init>(BindStatus.java:141)
-
at org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getBindStatus(AbstractDataBoundFormElementTag.java:172)
-
at org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getPropertyPath(AbstractDataBoundFormElementTag.java:192)
-
at org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getName(AbstractDataBoundFormElementTag.java:158)
-
at org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.writeDefaultAttributes(AbstractDataBoundFormElementTag.java:121)
-
at org.springframework.web.servlet.tags.form.AbstractHtmlElementTag.writeDefaultAttributes(AbstractHtmlElementTag.java:379)
-
at org.springframework.web.servlet.tags.form.SelectTag.writeTagContent(SelectTag.java:198)
-
at org.springframework.web.servlet.tags.form.AbstractFormTag.doStartTagInternal(AbstractFormTag.java:90)
-
at org.springframework.web.servlet.tags.RequestContextAwareTag.doStartTag(RequestContextAwareTag.java:77)
-
at org.apache.jsp.WEB_002dINF.jsp.spotlightMenu_jsp._jspService(spotlightMenu_jsp.java:658)
-
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:98)
-
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
-
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:331)
-
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:329)
-
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:265)
-
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
-
After much frustration I discovered that the problem was that the “preferenceCommand” was being set in the model, but then being overridden by a new model in my showForm() method.
The solution was to read the documentation (funny that) and eventually found that when using the AbstractFormController you should not directly create a new ModelAndView object to return but instead get the current model from the “BindException errors” variable that has been passed in and then “return super.showForm(request, errors, viewName);”
So my final showForm method went from;
-
-
public ModelAndView showForm
(RenderRequest request, RenderResponse response,
BindException errors
) throws Exception {
-
ModelAndView mav = new ModelAndView(viewName);
-
return mav;
-
}
-
to
-
-
public ModelAndView showForm
(RenderRequest request, RenderResponse response,
BindException errors
) throws Exception {
-
Map<String,Object> model = errors.getModel();
-
return super.showForm(request, errors, viewName);
-
}
-
That may all seem like giberish, but hopefully it’ll mean that someone else seeing the same problem might figure out what’s going on sooner! (That and I shouldn’t fall into this problem again any time soon now.)

RedLaser
Over the weekend I was sitting in a cafe with a friend of mine who works at a supermarket. He mentioned that he’d heard of a program on the iPhone which could read barcodes, RedLaser. I grabbed a copy, and we played around for a moment scanning the shopping we’d just bought.
Then sitting at home this morning, my eyes wandered to my DVD collection, and cogs began to whirr. A few moments later and I started the task of scanning each DVD, with the aim of e-mailing the list of results to myself, thus cataloguing my collection. Next I start on the CDs and books. So yeah, I had a nerdgasm, but only a little one.
Similar to the foliagometer a while ago, I stumbled across another “fun” feature on a website today.
The random weather generator of devthought.com. Worth checking out for a bit of inspiration.
Built using MooTools rather than jQuery, but I wouldn’t hold that against it
Devthought — JavaScript, MooTools, PHP, Symfony, Wordpress and all the stuff you love.
Google as a company just seem to get it, by introducing (yet) another browser into the wild, they began another round of the browser wars. Kicking off a flurry of innovation, which browser manages to render the acid tests? Who can perform the most javascript calls per milli-second? etc.
All Google seems to care about is that this innovation continues, so that they can build web applications to run on these platforms.
This interview is really worth a read to see the direction of Google and the Chrome browser.
Interview: what’s next for Google Chrome
Always the Google fan boy!
I am definitely a huge fan of jQuery. Every release seems to astound and amaze in it’s sheer brilliance and genius. The new ad spinner on the home page is written in jQuery, as well as the small bit of functionality on the Photography page.
Anyway, go and check out the newest release, mostly a maintenance update, it still has a few new features too! I shall certainly be using jQuery in all future developments!
jQuery 1.3.2
Who would have believed that it was the Norwegians that would lead the charge in the revolution?
IE6 is the bane of the web developer. With the (hopefully) imminent release of Internet Explorer 8 (with its huge list of “incompatible” websites) the world will be one step closer to a standards compliant web, and developers will be able to take a step back from the brink of madness.
Several websites in Norway have kicked the pebble down the hill which I hope will cause an avalanche. They have stopped developing for this hideous browser and provide a nice big warning to anyone using the out dated monster to upgrade to a newer browser.
Ajaxian » The Campaign To End IE6.
Viva la resistance!!
The sad hideous truth of Liferay…
I still love Liferay, but this may save some people a bit of heart break! I went through almost exactly the same journey in choosing Liferay for a new large scale website.
At first it seems to offer everything you ever wanted in a portal system, even more so (including making the coffee), but once you start to look beneath the hood, things become a little murkier. It was after a shambolic training course that I fell out of love with Liferay, but after looking through a few alternatives, it became the best contender again.
It’s all about managing expectations…
Your Software Made Me Cry: How to Select an Open-Source Java Portal for your Enterprise.
Seeing as I am a Google fan boy and I love my iPhone, I was really pleased that Google finally got round to enabling sync with Google Calendar.
Previously I had been using Nueva Sync, a third party tool which acted as an Exchange server.
Now Google have produced their own service which can push updates to an Exchange enabled client.
Google Mobile – Sync.
A sly flourish or something more loud and ostentatious?
I stumbled across this site whilst looking for a fix for PNG’s in IE6, but keep coming back to it as an example of some awesome jQuery flashyness.
Web sites should be more fun
Komodo Media