Sorting categories by count

Yet more XML and AJAX, what can I say, it’s just so much fun playing around with this stuff.

While in Sweden we were talking about how a real “nice to have” would be to be able to get a list of categories sorted by the number of documents in each category. As has become patently obvious I am not a Notes client guy, but on the browser this is really pretty simple. There are two steps that we need to go through.

So what we’re aiming to get is a list of the categories that are in this blog and then sort them by the number of documents within each category.

Step 1 – Getting the data
This is where the AJAX comes in. Recently I have switched over to using prototype for all of my AJAX calls, it’s a really powerful (and free) javascript library which handles all of your AJAX needs and some more besides. You may have noticed the new “Now Playing” block over on the left which is using prototype to make a request every 5 minutes to see what I’m listening to in iTunes.

So to get the XML for the categories I do the following:

function getCategories()
{
var a=$H(
{
collapseview: “true”,
count: 1000
}
);
var myAjax = new Ajax.Request(
http://www.11tmr.com/11tmr.nsf/BlogByCategoryCount?readviewentries’,
{method: ‘get’, parameters: a.toQueryString(), onComplete: outputCategories}
);
}

To me this is why prototype is so great, I just need to give it a URL and some parameters and it will go and handle everything else for me including browser issues. The final URL we’re building here is:

http://www.11tmr.com/11tmr.nsf/BlogByCategoryCount?readviewentries&count=1000&collapseview=true

When the URL is loaded then prototype will call the “outputCategories” function and pass in the response from the URL (whether that be XML or HTML or text doesn’t matter at this point).

Step 2 – Sorting the Data
OK, now we have the XML of the view, one entry per category thanks to the “collapseview” URL parameter. The attributes of each entry tell us the number of blog entries under each category (the “children” attribute) and also the total number of documents for the category (i.e. the number of blog entries plus the number of comments as well) in the “descendants” attribute:

This next bit I can’t claim credit for, instead I pass on thanks to Breaking Par Consulting who posted a great tip about sorting multi dimensional arrays in javascript. The pattern is to create a class function, in this case it has three properties – Category Title, Count and Number of Comments. We loop through the XML and create a category object for each category and place the new object into an array. After the array has been populated it’s just a matter of calling the sort method but making sure that you give it a function to define the sort rule:


for (i=0; i<results.length; i++)
{
cat = getInnerText(results[i].getElementsByTagName(“entrydata”)[0]);
count = parseInt(results[i].attributes[2].value, 10);
comments = parseInt(results[i].attributes[3].value, 10) – count;
aCats.push(new category(cat, count, comments));
}

aCats.sort(sortCount);

function category(title, count, comments)
{
this.Title = editReplace(title, “\n”, “”);
this.Count = count;
this.Comments = comments;
}

/*
sorting pattern courtesy of Breaking Par
http://www.breakingpar.com/bkp/home.nsf/0/87256B280015193F87256C8D00514FA4
*/
function sortCount(a, b)
{
var x = a.Count;
var y = b.Count;
return ((x > y) ? -1 : ((x < y) ? 1 : 0));
}

The Result
Hopefully that makes sense. If not then go and have a look at the final result and follow through the whole code there.

Sat in Arlanda Airport

I’m sat here in the bar at Arlanda Airport beavering away on the laptop while I wait for the plane in a couple of hours, there was an earlier one but it was full so I couldn’t get on. Anyway, not to worry as there is plenty to do. 

I’ve uploaded a few photos that I took yesterday. My hosts rather nicely let me have yesterday morning off so that I could have a look around. Stockholm’s a beautiful city (if a little cold at the moment) with a huge amount to see and do. Hopefully I’ll be able to get back in the summer to see what the different is. Currently most of the lakes and the sea are frozen over still, while we were in the office today we could see people cross country skiing across the lake, while another guy was fishing through the ice, neither were things I had ever seen before.

It’s been a very productive week all round, got a lot of quit ecool AJAX code working, I may be able to share bits of it, though that will have to wait until next week at the earliest as an email from Ben has reminded me that I need to be getting some work done on the next release of the Domino Wiki project. I must say, there are worse places to be working on code than here right now.

XML Encoding “European” characters

So while in Sweden one of the things I have been working on required me to output some XML from a view. I have a standard function which I use to encode text so that it will work correctly. But I learned two things which may well be blindingly obvious to you but were new to me…

Firstly, if you’re using a European character set which has lots of high number ASCII characters in then you want to be using ISO-8859-1, not UTF-8, as your XML encoding style:

<?xml version="1.0" encoding="ISO-8859-1" ?>

Second, where I had just encoded the basic 5 characters in the past: <, >, ", ‘ and &, you also need to translate any character with an ASCII code above 127 to it’s XML representation. So my new XMLEncode function looks like this:

Function XMLEncode (TextData As String) As String
    Dim MyChar As String
    Dim F_XML As String
    Dim i As Integer
    
    F_XML=""
    For i=1 To Len(TextData)
        MyChar=Mid(TextData,i,1)
        Select Case MyChar
        Case "<"
            F_XML= F_XML & "&lt;"
        Case ">"
            F_XML= F_XML & "&gt;"
        Case |"|
            F_XML= F_XML & "&quot;"
        Case "’"
            F_XML= F_XML & "’"
        Case "&"
            F_XML= F_XML & "&amp;"
        Case Else
            If Asc(myChar) > 127 Then
                F_XML = F_XML & "&#" + Cstr(Asc(myChar)) + ";"
            Else
                F_XML= F_XML & MyChar
            End If

        End Select
    Next
    XMLEncode=F_XML
End Function

PS: I have only changed the bold lines above, I don’t think I wrote the rest of the function but I can’t remember where i got it from so if you recognise it please let me know and I’ll add your credits!

Off to Sweden

Well it’s been a busy few days. We had a family gathering at a house in Norfolk over the weekend to celebrate my brother’s thirtieth birthday. A pretty relaxing time for all I think with a really great dinner on Saturday night, I think there were 12 people there and a few (if not more) bottles of wine and champagne.

It was the first time I’d seen my niece since her christening back in January. It’s only eight weeks or so but in that time she has grown up so much, she can sit up on her own now and is really close to crawling. But the biggest change is how much she interacts with you, constantly seeming to be learning something about what she’s seeing. It is incredible. She also seems to be unnaturally happy the whole time, I guess we only see her when she’s on form as she’s the centre of attention but from what I have seen she is always giggling about something. It’ll be another few weeks until I get a chance to go up to Nottingham again so I guess in that time everything will have changed once more.

Unfortunately I had to leave early to get down to Heathrow last night as I am off to Sweden for a week’s consulting work. Because the house we were in was so remote, up on the Norfolk coastline the drive down took almost four hours so I’m very glad I did leave early or I’d never have made it on time this morning. As it is I’ve managed to have a nice relaxing start and am just waiting for the plane to start boarding from Terminal 1. The lengthy security queues which Ed mentioned seem to have been solved, I got through at rush hour on a Monday morning in under ten minutes.

Anyway I will be online for a lot of the time in Sweden so if you have any tips for things that I should see while in Stockholm then please do let me know.

Inaugural UK LNUG Meeting

Today was the first meeting on the new UK Lotus Notes User Group (LNUG). Ben Rose did a cracking job of organising the morning’s session hosted at the IBM Bedfont Lakes office near Heathrow. There was a pretty good turnout of about 20 people to see a “Hannover and Beyond” presentation by an IBM-er and a best practices session given by TeamStudio. Neither were new stuff but were still interesting and sparked a good bit of discussion.

Hopefully this will be the first of many sessions that Ben would like to have happening all around the country. So if you missed this first session get over to the website, get registered and come along to the next one.

A few of the guys who went along today had been to the Lotusphere Comes To You event in London. Apparently this was not so successful with several people leaving at lunchtime. One thing which seemed particularly insensitive on a cold, grey and wet London day was to show a video of Lotusphere “proper” attendees having a great time in sunny Florida. That’s just nasty!

So where’s the third thing?

Yesterday afternoon while I was driving home from lunch I was sat at the traffic lights waiting for them to change. While waiting I could see a guy on a push bike weaving through all of the cars trying to get past, he looked a little unsteady but seemed OK, that was until he got to my car. It looked like he hit a stone on the road or something because suddenly he lost control and managed to fall over the bonnet (hood) with his bike scratching and denting as he went and ended up in a heap in front of me. Very spectacular.

When myself and the guy from the car in front got out to help him it was pretty obvious that he’d had a couple of drinks, he also couldn’t speak English (he was Russian I think) so the prospect of getting any of his details was pretty unlikely. So now to get my car fixed looks like it will cost a couple of hundred quid. Thing One.

Then today I managed to spill a whole mug of tea over myself which was annoying but not a massive problem. I stuck the clothes into the (new) washing machine to try and stop them getting stained only to realise an hour later that I had left my wallet in my trousers! So now all of my bank cards are warped and only two of them are actually working at all! Thing Two.

Neither of these bits of luck are particularly bad but they are annoying so I am now just wondering what the third thing will be to complete the set.

Finally Gone

Well yesterday was my last in my contract hence the lack of a SnTT post, definitely feels very strange not going to work today. Although it’s quite welcome as I didn’t get to the hotel until 2ish this morning and I definitely feel like I had a drink last night.

We had a really great turnout at the pub after work, must have been 40 people there are one point, the poor waitresses certainly earned their tips as everyone seemed to be thirsty. There were a lot of old faces there of people who I have worked with over the years, it was fun to catch up with them all. I’ve stuck a few photos up on Flickr.

The amount of experience which was gathered in the pub was quite incredible, some of the best Domino developers I have ever seen, some great .Net / SQL guys, BAs, Project Managers, Testers and general managers. As I was saying to them all yesterday, it’s not the work which made me stay for almost six years, it was the people. I hope everyone else had as good a time as me.

Now I’ll take a few days to relax and then after that it’s straight back on to the horse to try and find a new job.

Blogsphere 2.5 Upgrade

I’ve just spent an hour or so upgrading the site to use the new Blogsphere 2.5 template, an entirely painless process and well worth while if you’re using Blogsphere if only to get the automated Technorati tags.

I had to run a migration on all the blog entries so apologies if that has caused everything to come through in your RSS reader.

The only design change I have made is to the way that the Technorati tags are computed. With the default template, if your category has spaces in it then the formula which computes the tags explodes the category into a list so I have simply replaced out spaces in the field Technorati_Tag_List in the Input Translation formula:

@ReplaceSubstring(@ThisValue; ” “; “”)

Now as Kevin has pointed out I need to get my head around the CoComment stuff.

Show and Tell Thursday – Using gmail as a spam filter

No code this week, no time what with the release this morning and washing machines blowing up earlier in the week.

So instead a tip. It’s something which I have mentioned to a few people and they seemed to think it was an interesting idea for those of us running home Domino servers for email.

In the control panel application of my main mail domain I have it set up to forward all of the mail received to be forwarded on to my gMail account. In gMail I then have it set up to forward all mail that it receives on to a different, undisclosed email address which is hosted on my home server.

So why would I do this? Well there are two main reasons…

1) I don’t need to worry about spam filtering as gMail handles that for me. gMail doesn’t have the best spam filtering in the world but it’s getting better and it will only forward on mail which it doesn’t think is spam, so my home Domino configuration can remain nice and simple.

2) I have a backup of my mail for when my home server is not accessable during network outages or, in the worst case, if the server dies completely.

There are downsides to this approach, all mail that I receive has the flag to identify suspicious mail in the new ND7 mail template, but I have just hidden that column in my Inbox so it doesn’t bother me. When I’m sending mail from the Notes client, to make it come from my "real" email address I need to have my Location document set with the correct "Internet mail address".

Other than that it has been a really successful set up for me over the last few months.

Now all you admins out there can start to pick holes! (Actually I am serious about that, if there are obvious flaws which I have missed I’d love to know them please).

Last Early Start

Before finishing my contract next week I have one more version of the application I have been working on to release into production. So a 4:30 start this morning to get into the office in time for the templates to be released. After that a bit of configuration work and some unit testing before handing over to the users for them to make sure they are happy with everything.

It’s the end of an era for me, I have worked on this application on and off for almost six years now. As with all big, mature apps it gets its fair share of critiscism, it’s by no means perfect but it does work and has been used during my whole time here so I do feel a strong attachment to it. But you have to change things round every so often, so I’m really looking forward to new challenges over the next few weeks and months. Should be exciting times.

Now I just need to find some more work to keep me busy!