Tuesday, February 28, 2006

Python Web Application Frameworks (Part 1: A Trip To Yesteryear)

Lately there has been a lot of discussion in Python circles about web application frameworks. This has been spurred on by the success of Ruby On Rails and the perceived lack of a similar all-in-one solution in the Python world. Here I am going to try to summarise the state of the art and make a few comments as a one-time developer of such a beast. Along the way you'll get definitions, perspectives, and lots of references. Plus a joke. But only one.

Python is a great language for the web. In fact it's a great language for just about anything. It's easy to read, easy to work with, and comprehensive. There is a library for any task you might need, usually far too many libraries in fact.

And that is the problem when it comes to Web Application Frameworks (WAFs). It's not that Python doesn't have them, it's that Python has too many. It is so easy to build your own WAF that there is little incentive to use an existing one. So developers, one after the other, line up and create their own solution, driven by their own needs, and with their own perspective on how the web should be done.

But if anyone should come up with the perfect WAF that everyone agrees does the job, the least I can do, besides offer congratulations, is to provide a name. I hearby christen this mythical achievement Python Off The Rails. 1

Back when I first looked at this domain (in the last millenium) there were a few dominant players, none of which suited me. Others arose over time but they still didn't seem to be built with some of the principles I had in mind.

Of those initial candidates Zope was the most monolithic, an almost impregnable fortress of code. Modules had to be written explicitly with Zope in mind. There was an alien world of technology and terminology to navigate. Just listen to the name: Zope. You'd have to be a character named Zorg to take to that. This was certainly the opposite of what I was looking for. I wanted a simple solution that played nicely with other modules and expected you had a body with but a single head.

I also discarded Twisted, Webware, SkunkWeb, and the like. They were either too vast, complex, or low-level. They were multi-headed tentacled beasts that bathed in Freon and spat out, well, they spat out HTML I suppose. But still, Freon!

A good amount of my dislike for some systems came from their templating language. Templates allow regular HTML to be extended with additional tags or commands to facilitate generating dynamic pages. (There, that's one of those definitions I promised.) But many of these system encourage the use of Python code in HTML, following the model of Microsoft's own ASP.

I thought then that this was the worst possible idea for web development. (For the record, my opinion has not changed.) Mixing functionality with interface is a recipe for disaster. Designers should not have to care about program code and vice versa. These sorts of templating languages seemed to be written by people who expected to do all the jobs themselves and who never thought about how their tool might integrate with an entire development team.

That ruled out template systems like Spyce and a lot more besides. (I don't mean to pick on this product specifically. But since it has a catchy name it came into my head first.)

Later a second wave of sophisticated applications washed up on shore. (I suppose this had better be an alien shore 2 in order to keep my metaphors unmixed.) For example, there was CherryPy, which required that your app be compiled into a standalone HTTP server, an idea that broke all sorts of standard expectations about how Python code should behave 3. That irked me, but on a more practical level that particular architecture made it impossible to run a site at standard web hosting firms that don't allow full server access.

It seemed that developers were being too clever for their own good. Since I am rarely clever enough for my own good, I did what any decent Python coder would do and wrote my own solution. By 2002 I had released a program called Wasp4, which included session support, cookies, form handling, remote debugging, exception handling, templates, and a bunch of other goodies. It was written to work as a simple CGI process on standard web servers. Later I extended it to include its own web server, work with Twisted, etc., but these versions I did not release. In fact, I'm not even going to give you a link to it, because it is so far behind the times it looks positively ancient.

That's what happens in four years.

One intriguing aspect of Wasp was that it could be used as a static templating system: feed it template files and it would spit out the results as normal HTML that could be used anywhere. It did not need a web server at all. This facility proved most handy.

However, although it is small and concept-free compared to most WAFs, it was monolithic in the sense that the core components could not be readily used apart from one another. It was beginning to look a lot like a framework indeed and frameworks suck as many have noted. Again, this was less an issue in the current, unreleased version. (But then again I could claim an unreleased version cured hunger, helped single dads and consequently removed the need for people like Bob Geldof 5 to even exist. And how would you know. It's unreleased.)

A library allows each piece to be used if and as the developer wishes. A framework demands that the developer take an all-or-nothing approach. Frameworks are good for end-users, those building a website with little desire to programme. But they are bad for developers, who need to tweak and mix'n'match to fit custom circumstances.

So what are these "core components" that WAFs contain? It turns out that there are an awful lot of them. And that's where I'll start my discussion next time. Because I appear to have run out of space for footnotes.

1 And would claim copyright on the name, except that I know you can't copyright a name. Sheesh!

2 Despite the fact that I am or was a Canadian, this is not a reference to Rush, prog rock group and science-fiction fans.

3 Some time ago, that architectural restriction was lifted, and you can now use CherryPy with mod_python, IIS/ASP, FastCGI, or SCGI. Just so you know I'm paying attention.

4 It was originally called Goat. Don't ask. Because I don't remember. But certainly Wasp sounds much cooler.

5 For the record (aha! a pun!) I am a big Boomtown Rats fan, even if the recent remastered CDs squashed the life out of the music and contained some odd editing errors.
Monday, February 27, 2006

A Few Things You Can Expect

This week I'm going to be posting a four article series on Python Web Application Frameworks. If you are a developer of web apps this will bring you up to speed. You can also expect further entries in my Best Software series. Yes, articles are coming thick and fast, so pay attention, subscribe via email, or use the RSS thingie.

So that I don't obsess exclusively over computer stuff I'm going to give equal opportunity to obsessing over music stuff. Next up is an article on one of the great lost American post-punk bands, Urban Verbs.

I will also endeavour to post some complete non sequiturs and keep things lively with a bit of humour. Not too much, mind you. Wouldn't want to establish a precedent.

In other site news I've just changed, ever so slightly, my page template. The copyright is updated and I have a set of new Python links in the sidebar.
Saturday, February 25, 2006

New York Comic-Con Unearths P.K. Dick

According to Newsday, the current comics festival in NYC is to feature "scenes from the upcoming film A Scanner Darkly and a conversation with the author, Philip K. Dick." What they don't tell us is that this will not be a recent conversation.

Dick has been dead for almost a quarter century. Though you may hear from him from beyond the grave all such conversations will be marked by a beam of pink light.

I was a fan of his writings even when he was alive, and obtained all of his books, yes, even those that were not science-fiction and available only in first edition hardcovers. Actually, I never did find a copy of his children's book Nick and the Glimmung, so if you have one you'd like to donate, I'd be grateful. And Gather Yourselves Together was published long after I'd already stopped accumulating paper.

When I was shopping this past Christmas I noticed with shock and delight that the Gollancz SF imprint of Orion Books has just issued some of Dick's mainstream novels. Before they go out of print again you should snap up Mary and the Giant, Confessions of a Crap Artist, and In Milton Lumky Territory. This last book is now generally available for the first time since it was released in 1985.

I find it impossible to believe that a writer this popular with readers and critics alike should have books that people still can't buy, but such is the unfortunate case. Here are the four remaining mainstream novels with their dates of last (often the same as first) availability:

* The Broken Bubble (1991)
* Humpty Dumpty in Oakland (1988)
* Puttering About in a Small Land (1987)
* The Man Whose Teeth Were All Exactly Alike (1986)

They are all wonderful.
Friday, February 24, 2006

Rarest New Order Song

Last week I wrote about the release of the original "Ceremony" on CD after all this time. Apparently I'm not yet done musing about New Order (for no particular reason, it's just that I'm a music geek). On this particular occasion I'm wondering "what is the rarest New Order song?" And of course I've got an answer for you.

First, to clarify the question. I don't mean some obscure white label remix, or a live recording of a tune they played once. I want to determine which of their regular run-of-the-mill studio tracks is the most difficult to stumble upon. This is likely only the sort of thing that completists care about, and although I am not a fanatic by any means, I do enjoy seeking out the dark hidden places in post-punk music catalogues.

And I've got an answer: "Mesh".

Now I can hear all you other post-punk music geeks clammering "but that was on Substance, how rare is that?" To which I reply that yes, there was a song with that name on Substance, but it was not the song "Mesh". You have been duped! "Mesh" itself has not been issued on any readily-available CD. Let me explain.

Back in December of 1981 New Order liked the b-side of their second single "Procession" so much that they turned around and issued an extended version of it on a slab of 12" vinyl. "Everything's Gone Green" was released on Factory Benelux as FBNL 8 with two b-sides, listed as follows with their timings: "Mesh" (3:25) and "Cries and Whispers" (3:00).

These are both low-key mood pieces that sound exactly as though they are extra tracks from the session for their debut album Movement, released one month prior. They've got the same song-writing, the same recording, the same mood. And so although I have not read it anywhere officially, I will assume they are Movement cast-offs. The odd thing is they are as good as the tracks from the album, a record short by any standards at 35 minutes in length. Why they were not included on the album (or at least the CD version) is a mystery, though not the mystery I am investigating here.

Here's the root of the enigma: the names for these b-sides were accidentally switched. So actually it's "Cries and Whispers" at 3:25 which begins with the swirling synth reminisent of "Procession". And it's "Mesh", 3:00 in length, which has a plodding beat and the line "out in the woods and the trees / atrocity lays". (Or at least I imagine those are the lines, which is the same thing.)

The compilation Substance 1987 perpetuated this problem. The second disk contains single b-sides on CD for the first time. It has a track called "Mesh" but it's actually "Cries and Whispers".

The massive boxed set Retro includes exactly the same song, but correctly labels it, for the first time, as "Cries and Whispers". The new Singles collection does not include b-sides and so has neither track.

Now oddly, there is one place where you can find "Mesh" on CD. In November 1982 the 12" vinyl EP 1981-1982 was released in Canada to collect up some of the group's non-album material. It's a pretty scatter-brained effort on the whole, not including the "Ceremony" single or "Cries and Whispers".

In 1989 this EP was released on CD and become the only place on disk to get the full 12" version of "Hurt" (at 8:03), a song truncated by about a minute for Substance 1987.

More to the point, it is the first and only time that "Mesh" has been available on CD -- and correctly labelled to boot.

As a Canadian I know this well, having bought the vinyl EP when it was first released. Besides the musical content, it is notable for having cover art designed by Martha Ladly (ex-Martha and the Muffins), who was dating Peter Saville at the time.

But before I branch out into the unwritten history of Martha Ladly, I'll stop. I could easily fill several pages with this sort of esoterica, but no-one reads anything except my tech posts anyway.
Thursday, February 23, 2006

FireFox & Python

According to Brendan Eich, Python is going to start making its way into FireFox for XUL scripting and as a template for new JavaScript features. This totally rocks on the one hand, since Python should be everywhere. But it doesn't matter at all on the other hand... since we're never going to get to a world where everyone runs the best available browser.

I found out about this development through Uwe's blog, which is one I read from time to time. While I'm at it, why don't I mention a few other good Python blogs?

Bob at pythonmac is a good spot if you are into Python on Mac OS X. He's got a great example of developing a toy web app in three languages: Python, PHP, and Java. The Python version is a readable 117 lines of code; the PHP implementation is larger and "one big security flaw"; the grotesque Java version is "246 lines of XML configuration sludge in 5 files, 29 lines of SQL schema in 1 file, and 3004 lines of Java code in 45 files".

A brilliant source for Python blog posts is Ryan Phillips's Unofficial Planet Python. Essential is Fredrik Lundh's effbot.org and the rest of his site. The Daily Python URL is a good starting place for recent development news.

I will be writing more about Python and web frameworks soon. But I've got a chunk of research to do first.
Wednesday, February 22, 2006

Solar Systems: A Music Compilation

I recently had a conversation about the outermost planet of our solar system with a friend of mine, who happens to be a girl just turned eleven. We were also recently looking up at the stars and trying to identify constellations, getting only about as far as The Big Dipper, Orion, and The Shopping Trolley. So for her birthday I thought it appropriate to compile a CD entitled Solar Systems. Here I'll share the track listing and premiere a brand new recording by escalation 372.

Only one planet is missing from the compilation, Uranus, because the Hendrix tune sucks and I don't have Klaatu's "Anus of Uranus" closer than a vinyl record kept on the other side of the Atlantic.

Of course the other planet I had a difficult time representing was 2003 UB313, not only because it was unknown until a couple of years ago, but also because with a name like that it's not going to attract too many songwriters. (They may be happier with its nickname, "Xena".)

Being an odd sort of composer, I find the designation quite evocative, and thought I'd be the first to write a tune for this trans-Neptunian object.

01 The Beatles: Here Comes The Sun
02 Red Hot Chili Peppers: On Mercury
03 Bananarama: Venus
04 Duran Duran: Planet Earth [Night Version]
05 XTC: Another Satellite
06 The Police: Walking On The Moon
07 David Bowie: Life On Mars
08 The Cure: Jupiter Crash
09 Barry Adamson: Saturn In The Summertime
10 The Shamen: Neptune
11 Andheri: Pluto
12 The Only Ones: Another Girl, Another Planet
13 The B-52's: Planet Claire
14 The Human League: The Black Hit of Space
15 Elysian Fields: Shooting Stars
16 Björk: Aurora
17 Wire: Comet
18 Brian Eno: Just Another Day
19 escalation 372: 2003 UB313

In case you're wondering, Andheri are from Iceland.
Wednesday, February 22, 2006

Best Software: Internet Apps

This is the second in a series of articles about some of my favourite software. I hope my decades (yikes!) of experience will help you make a quick decision as to what to download. This article will cover software to help you get the most from the Internet itself.

Free Agent is not Open Source but it is a handy newsgroup and email client that I've been using for more years than I can remember. It hasn't changed much in that time, which means that while it may not be terribly exciting now, it was very full-featured compared to the competition when I first adopted it. In fact, though there is a free version, I long ago considered the extra features to be essential. This may have been the first app I bought over the internet.

Thunderbird x o is the counterpart to FireFox in the world of email & newsgroup reading. I will do no more than mention it here, since I do not have significant experience using it. But maybe if I was starting over I'd use it instead of Agent.

PuTTY o is a SSH and telnet client for win32 and Linux. It does the job whenever I need to connect to a remote computer, which is often, given the nature of my consulting work.

There are many download managers but TrueDownloader o for Windows is a rare Open Source choice. A few interface glitches detract from a capable programme. You may wish to use FlashGot to integrate it with Firefox, but it only saves a click.

o Open Source
x cross-platform

Tuesday, February 21, 2006

Article One-Hundred: Dan Quayle

This is my one-hundredth article since I started this blog on 7 August 2005. That's not a bad track record, really, and I seem to be back in the swing of things after a sparse couple of months. To celebrate this centennial I'm going to give you something to laugh at, a classic series of quotes from Dan Quayle. Remember him? He used to be vice-president of this obscure little country they call the United States of America. At the time he seemed like a right idiot, but now that things have got so much worse we can look back with a sense of nostalgia and even longing.

"Hawaii is a unique state. It is a small state. It is a state that is by itself. It is different from the other 49 states. Well, all states are different, but it's got a particularly unique situation."

"If we don't succeed, we run the risk of failure."

"It isn't pollution that's harming the environment. It's the impurities in our air and water that are doing it."

"I love California. I practically grew up in Phoenix."

"What a waste it is to lose one's mind. Or not to have a mind is being very wasteful. How true that is."

"It is wonderful to be here in the great state of Chicago..."

"We are ready for an unforseen event that may or may not occur."

"I stand by all the misstatements that I've made."

This article is part of my Retro series.
Monday, February 20, 2006

Best Software: Two Obvious Choices

This is the first in an ongoing short series of articles recommending some of my favourite software. I have done away with Microsoft products (other than Windows XP itself). I never want to buy another piece of bloated, slow, crappy, single-platform, proprietary, talking paperclip-infested software again. To begin with I'd like to alert you to two obvious choices, plus an innovative way you can install and use these apps.

 Use OpenOffice.org OpenOffice.org x o is a full office application suite. It boasts great compatibility with the common Microsoft Office file formats that you will need in order to operate in the business world. Applications include a word processor, spreadsheet, slideshow app, draw program, and a new database manager. It is available in more than 60 languages and has a full feature set including mail merge, powerful stylesheets, automatic cross-references and table of contents, etc. Check out the list of features new in version 2.0.

I recently laid out an entire book in OpenOffice.org and the experience was overall a pleasant one. Certainly there are some aspects of the programme that are not obvious but the documentation is improving all the time. It might have helped had I come across the article Creating A Book With OpenOffice.org Writer before starting.

There are some glitches and gotchas (what complex app doesn't have them?) but I have now put aside MicroSoft Word and PageMaker forever. And so has the state of Massachusetts, more than one Canadian province, the city of Vienna, and the entire nation of Brazil!

One thing I love is the small file size. The 218 page book (text, no images) fits in a file of 164KB. Producing a PDF for production printing is a piece of cake, and the resulting file is only half a meg.

I should warn you that this app is very large, currently around 80MB.

Available through a third-party venture is Portable OpenOffice.org the complete suite packaged as a portable app. The idea here is that you can bang it on a flash disk and use it wherever you go without needing to install anything. All programme files, configuration settings, temporary files, etc. stay on the flash disk.

Get Firefox! The second obvious choice is FireFox x o, a better browser than Internet Explorer in any number of ways: popup blocking, plugin availability, rendering, privacy controls, etc. The tabbed interface is to die for. Simply put: once you try it you will never be able to go back. In Europe Firefox has passed 20% market share and is unstoppable as far as I am concerned. Besides, it's got a cute fox logo.

As a bonus, a portable version is available, for those nasty internet cafes that are still stuck on IE. Full disclosure: I am just about to try this portable solution for myself, so it comes untested by yours truly.

o Open Source
x cross-platform

Saturday, February 18, 2006

Remember Having To Buy Software?

Let me introduce you to the strange worlds of yesteryear. In this fanciful, far-off realm (a.k.a. the nineteen-eighties) we bought magazines for advertising that might help us decide which software was best. That's right. We bought magazines. And read the ads. For information. But wait, it gets stranger.

After putting together a shortlist of possible solutions, we then visited our local library to look up back-issues and hopefully find maybe, perhaps, if we were very lucky, one measly review that might give us help in our purchase decision. Then we wrote letters, licked stamps, and sent off requests for product catalogues and flyers, obtained through the post. When this information proved to have shortcomings we could pick up our telephones (you know, the old type, connected to the wall by a cord) and call long distance numbers so specific questions might be answered.

After spending a fortune on telephone calls we could finally order a product by mail-order. Or perhaps we would go to a local computer shop and convince the proprietor to obtain it from their distributor. In those days dinosaurs ruled the earth and software came packaged in a large box with a paper manual and a stack of floppy disks. When a disk failed we waited for another. When the software wouldn't install an expert came to our home. When we wanted an update we waited six to eight weeks and paid a fistfull of bills.

Oh yeah, and the software cost money. Maybe $400-500 for a standard business application like, for example, WordPerfect.

We called this experience "buying software".

Well I am about to change your life forever by introducing you to a wonderful thing called "the internet". Now you can look up product info and reviews as quick as a wink (at least for those of you who have very slow cheek muscles). You can download apps almost as quickly, try one out, grab another, compare, see which best fits your work habits and requirements, and then write your own review (or blog page) to tell the rest of the world about how you got on.

Better yet, as we edge our way into the twenty-first century the best software is free. And not just free as in euros but Open Source, which means all of the source code is also free and open for people to use as they wish. Gone are the days of proprietary companies deciding when and how we should use their software and when and how they will make updates to fix long-standing critical bugs. The control hierarchy of the software industry has been destabilised. (Which some of us knew it would, years ago. Ah victory, sweet victory.)

Over the next little while I am going to post articles telling you about some of my favourite software, almost all free and Open Source and far far better than the crud we had to deal with years ago. Some of the applications will be familiar to you, some will be popular choices, but maybe others will be new discoveries that can save you money or make your life easier and more fun. Yippee!

Though I will be recommending apps base on my experiences on Windows XP, many will be marked "cross-platform", which generally means they can be used with Win32, Linux, Mac OS X, and maybe other platforms. Check the product info for full details.
Friday, February 17, 2006


this is why events unnerve me
"this is why events unnerve me"

I missed this until now, being rather bored with New Order since, er, well since 1983 actually. In that time there have been numerous compilations: Substance, The Best Of New Order, International, the boxed set Retro. So did we really need the release late last year of Singles, yet another anthology? Seemed like a calculated rip-off of an already saturated market.

Oddly, the answer is "yes", we do need this record. Because Singles includes, in all it's original unadulterated heartbursting glory, the stunning "Ceremony".

One of the last songs Joy Division wrote, "Ceremony" was premiered at their final concert. The performance at High Hall, Birmingham University on 2 May 1980 was made available on the posthumous double-album Still. Rough recordings from April or May 1980 capture the band rehearsing both this and a second track, titled "In A Lonely Place (Detail)" when included on the excellent Heart and Soul boxed set.

Soon after this came the death of Ian Curtis. The remaining three members of Joy Division renamed themselves New Order; their first act was to record and release the single of "Ceremony" backed with "In A Lonely Place". For this record Bernard Sumner took his first faltering steps in the role of vocalist, a task at this time shared by each of the band members in turn.

it's got to be this time
"it's got to be this time"

"Ceremony" was released in March 1981 on Factory Records as catalogue number FAC 33. The 7" is in a stamped gold-bronze sleeve, while the 12" cover was a completely separate design: roman lettering on a green background. Both of these were of course designed by Peter Saville, a name firmly linked to the aesthetics of these groups. The production was by Martin Hannett, also well known from Joy Division releases.

Then, for some reason, the song was re-recorded with Gillian Gilbert on keyboards, just before she formally joined the group. That version of the single was re-issued in 12" format only, in September 1981, with the same catalogue number. The sleeve was changed to a light cream with a vertical blue stripe, though with the same motif and typography as the original 12".

the same old story
"the same old story"

After supplies of this sleeve ran out, copies of the original cover were substituted. Thus (contrary to some reports) if you buy the 12" it is not possible to tell which version of "Ceremony" you will get, based only on the cover design.

The only way to be sure is to read the run-off groove on the a-side of the vinyl itself. The original says "Watching love grow forever" while the re-release says "This is why events unnerve me". Both are lyrics from "Ceremony".

There are significant differences in the recordings. The original is approximately 4:34 in length while the re-recording is 4:23. The original has a much more "Joy Division" sound, with throbbing bass, distorted guitar, and solid drum kit contributing a wash of cymbals. In the re-recording the bass is diminished, cymbals restrained, and vocals less dramatic and quieter in the mix. The guitar has a sound typical of that used on the album Movement. Drum hits in the opening verse are dramatically panned in the mix. There is a greater contrast between verse and chorus, with the latter sections reaching some of the emotional pitch of the original recording.

The re-recorded version was used on all subsequent compilations until the aforementioned 2005 compilation Singles, which also includes two other early tracks previously unavailable on CD in their original 7" single versions: "Temptation" and "Everything's Gone Green".

Those without access to vinyl can now hear one of the most chilling, resounding, achingly beautiful hymns to lost experience ever penned. This is a song that can make grown men break down and cry, as it did one music critic upon release. For one shining moment in 1981 it seemed like the naive romanticism of Ian Curtis might continue into the future. As I suppose it did, for a while, through to the Power, Corruption, And Lies album, though not in any way we might have envisaged.

But back to the record. At the two-thirds mark the bass tries harder than ever to break free of the contraints of the grooves. Guitar shards chime and echo around that frail voice, never quite up to the task. The final lines then usher in a resounding refrain that is full of "yes, yes, yes" and fate and destiny too.

And this is what the voice says:

"forever, watching love grow"

That's worth cherishing. So get this record. Now.

This recording sounds as though it is sourced from a cassette tape that has been deliberately erased just prior to a delicate lyric in the song.

I have adapted this article as a wikipedia entry.

I will say more about another New Order rarity in a future post.

Lyrics by Ian Curtis. © Deborah Curtis, 1995.

Thursday, February 16, 2006

Boat House Photos

Believe it or not, I have not forgotten this blog. I have a whole bunch of articles to post in the next few days, but will start with some photos, taken November 13th at the Boat House in Limerick.

At this gig Vertigo Smyth opened for the Brad Pitt Light Orchestra. A splendid time was had by all. They're playing again this Saturday February 18th at 9pm, by the way.

This post is also for people (mostly relatives) who want to see more of what I look like these days! I am not particularly fond of this self-portrait but that's par for the course.

The next one is a light fixture and finally some (not all) of the BPLO guitars.

Saturday, February 11, 2006

Javascript Implementation Of Recent Comments

In my search for ways to make the information on this site more timely and accessable, I came across the so-called Farrago Recent Comments Hack. It does some pseudo-magical stuff with Blogger tags, but I thought I could go one better by encapsulating the code in a proper class, providing comments, and enhancing the code for readability. Plus I made it work with my chosen date format and have made it easier for all of you to do the same.

Once you have read how the original works, follow these steps to use my enhanced version. I do assume you know something about what you are doing here. This is not for those unfamiliar with their template.

1. The following is the Javascript which does the processing. There are two ways of using it.

a) The preferred way is to save it as its own text file, with a name like "rc.js" and then upload it somewhere you have space on the web. Link to it from the header of your template with a line like: <script type="text/javascript" src="http://www.x.com/rc.js"></script>

b) If you don't have external storage, put this code in the header of your template, wrapped in script tags. To be explicit, this line goes first: <script type="text/javascript" language="JavaScript1.2">, then the code below, then finally this line: </script>.

OK, here's the code.

Blogger Recent Comments

Based on the Farrago Recent Comments Hack v1.03
(c) 2004 Ebenezer Orthodoxy

Statement: I would GPL the code if the original author would.
Mods by: Robin Parmar
Visit: noisetheatre.blogspot.com

// our class
function RecentComments() {
// options to change
this.displayAmount = 10;
this.displayTemplate = '<li>[name]:<br/>[title]</li>';
this.displayPre = '<ul>';
this.displayPost = '</ul>';
this.displayLink = true;

// properties
this.comments = new Array();
this.title = '';
this.itemurl = '';

// methods
this.SetTemplate= rcSetTemplate;
this.SetAmount = rcSetAmount;
this.SetLink = rcSetLink;
this.SetPrePost = rcSetPrePost;

this.SetTitle = rcSetTitle;
this.SetUrl = rcSetUrl;

this.SortDate = rcSortDate;
this.AddComment= rcAddComment;
this.Display = rcDisplay;

// this line uses my date converter method
this.DateConvert = rcDateConvert;

// comment out the previous line and uncomment the
// next line to use original date format
// this.DateConvert = rcDateConvertDefault;

// or write your own and insert it

// simple property setters: these are used by process
function rcSetTitle(x) {
this.title = document.getElementById(x).innerHTML;
function rcSetUrl(x) {
this.itemurl = x;

// these are used by user to customise
function rcSetTemplate(x) {
this.displayTemplate = x;
function rcSetAmount(x) {
this.displayAmount = x;
function rcSetLink(x) {
if (x==0) {
this.displayLink = false;
} else {
this.displayLink = true;
function rcSetPrePost(x, y) {
this.displayPre = x;
this.displayPost = y;

// date format converter
// insert your own here depending on the format you use for comment dates
// this one converts from:
// 01 November, 2005 16:35
// to:
// 11/01/2005 16:35:00
function rcDateConvert(dt) {
var s = dt.split(' ');
var d = s[0];
var m = s[1];
var y = s[2];
var t = s[3];

var MonthHash = new Array();
MonthHash['January'] = '01';
MonthHash['February'] = '02';
MonthHash['March'] = '03';
MonthHash['April'] = '04';
MonthHash['May'] = '05';
MonthHash['June'] = '06';
MonthHash['July'] = '07';
MonthHash['August'] = '08';
MonthHash['September']= '09';
MonthHash['October'] = '10';
MonthHash['November'] = '11';
MonthHash['December'] = '12';

// trim off comma
m = m.substring(0, m.length-1);

return MonthHash[m] + '/' + d + '/' + y + ' ' + t + ':00';

// default converter: does nothing
// use if your comment date format is:
// mm/dd/yyyy hh:mm:ss
function rcDateConvertDefault(dt) {
return dt;

// given a date string this returns a sorted representation
function rcSortDate(strDate) {
strDate = this.DateConvert(strDate)

var d = new Date(strDate);

var day = '' + d.getDate();
if (day.length==1) {
day = '0' + day;
var month = '' + (d.getMonth()+1);
if (month.length==1) {
month = '0' + month;
var hour = '' + d.getHours();
if (hour.length==1) {
hour = '0' + hour;
var min = '' + d.getMinutes();
if (min.length==1) {
min = '0' + min;
var sec = '' + d.getSeconds();
if (sec.length==1) {
sec = '0' + sec;
var sortDate = '' + d.getFullYear() + month + day + hour + min + sec;
return sortDate;

// adds to global comments array
function rcAddComment(title, url, id, a, datestamp) {
var author = a;
var expt = '';
var st = '';

// grab content of our hidden layer containing all items
var html = document.getElementById('comm' + id).innerHTML;

// strip out whitespace
while (html.indexOf("\n") > -1) {
html = html.replace("\n", "");
while (html.indexOf(" />") > -1) {
html = html.replace(" />", "/>");
while (html.indexOf(" <a/>") > -1) {
html = html.replace(" <a/>", "<a/>");

var htmll = html.toLowerCase();
var pos1 = htmll.lastIndexOf('<br><a></a>posted by');
var pos2 = htmll.lastIndexOf('<br><a></a><a></a>');
var pos3 = htmll.lastIndexOf('<br/><a/><a/>');
var pos4 = htmll.lastIndexOf('<br/><a></a><a></a>');
var aoffset = pos1 + 6;

if (pos3 > -1) {
pos2 = pos3;
if (pos4 > -1) {
pos2 = pos4;
if (pos2 > -1) {
pos1 = pos2;
aoffset = htmll.lastIndexOf('<a><b> </b></a>');
if (aoffset == -1) {
aoffset = htmll.lastIndexOf('<a><b></b></a>') - 1;

if (pos1 > -1) {
author = html.substr(aoffset+15, html.length-1);
expt = html.substr(0, pos1-4);
} else {
expt = html;
expt = expt.replace(/(<([^>]+)>)/ig, "");

if (expt.length > 50) {
expt = expt.substr(0, 50);
if (expt.lastIndexOf(' ') > -1) {
expt = expt.substr(0, expt.lastIndexOf(' '));
expt += '...';
expt = expt.replace('"', "\"");
expt = expt.replace("'", "\'");

author = author.replace("<A ", "<a ");
if (!this.displayLink) {
author = author.replace(/(<([^>]+)>)/ig, "");

// build a template string of HTML
st = this.displayTemplate.replace('[name]', author);
st = st.replace('[title]', '<a title="' + expt + '" href="' + url + '#c' + id + '">' + title + '</a>');

// prefix with date for sorting purposes
st = this.SortDate(datestamp) + st;

// accumulate on our array

function rcDisplay() {
// most recent comments first

if (this.displayPre.length >0) {

for (i=0; i<10 && i < this.comments.length && i < this.displayAmount; i++) {
var s = this.comments[i];

// strips off date prefix
s = s.substr(14, s.length-1);

if (this.displayPost.length >0) {

2. Depending on the comment date format you use, you may need to provide your own conversion method. This class works with the original Farrago format and my format as well. If you know a bit of Javascript it's pretty easy to extend, following the code example here.

3. Edit your template to put the following in the sidebar where you'd like the comments to appear. Your formatting may be different, but it'll be pretty darned similar. This whole block is wrapped in tags to ensure it only appears on the main page, because it produces an empty list on item pages and a misleading list on archive pages.

<!-- START RecentComments 1.05 -->
<h2>recent comments</h2>
<script type="text/javascript" language="JavaScript1.2">
var rc = new RecentComments();
rc.SetTemplate('[name]: [title]<br/>');
rc.SetPrePost('', '');
<span id="comm<$BlogItemNumber$>" style="visibility:hidden; position:absolute;">
<script type="text/javascript" language="JavaScript1.2">
<span id="comm<$BlogCommentNumber$>" style="visibility:hidden; position:absolute;">
<script type="text/javascript" language="JavaScript1.2">
rc.AddComment(rc.title, rc.itemurl, '<$BlogCommentNumber$>', '<$BlogCommentAuthor$>', '<$BlogCommentDateTime$>');
<script type="text/javascript" language="JavaScript1.2">
<!-- END RecentComments 1.05 -->

4. This example shows how the various options can be set from directly in your template code, so that you do not need to directly edit the Javascript file. There are four methods called in the first script block above. But you may be just as happy with the defaults.

rc.SetTemplate() sets the template string for each entry in the comment list. The placeholder "[name]" will get filled by the author's name, and "[title]" with the title of the post. The default is <li>[name]:<br/>[title]</li> which sets up each comment as an HTML list item.

rc.SetPrePost() takes two string parameters containing the HTML you want to be written before and after the comment list. The default is <ul> and </ul>, again for a simple list implementation.

rc.SetLink() takes the number "0" to turn off author links. Otherwise, by default, the author's name will link to their page.

rc.SetAmount() takes a number up to 10 indicating how many comments to display, 10 being the default.

So, in the example above we have changed the default code from an HTML list to a simple sequence of lines seperated by line breaks. We have turned off name linking, and set the maximum number of comments to 5.

Following the Javascript, the tag section performs some magic. Remember that everything within a Blogger tags gets repeated for each of your posts. It is a loop construct. The first invisible span prints out the item (that is to say, the article) title with its own special ID.

The Javascript following this sets the title referencing that ID, and sets the URL using the appropriate blog tag.

Then we use a similar trick to grab the comment info. Blog tags loop over each comment, set in its own invisible span. The following Javascript associates the title and URL we already set with further details from the comment.

The final section, outside the Blogger tags, simply calls a method to display the results.

Note: I do not recommend you change any of the code in this section.

6. Once you have saved your template with these changes, and republished the site, you should have a lovely list of the most recent comments made to your blog. Note that mousing over the title reveals the first characters of the comment.

All is not perfect however. I have discovered that some comments seem to be ignored by this list, presumably because they are for articles too old to be on your main page. But altering the tags to access these would result in every article in your entire blog being included in invisible spans on your home page. The resulting slowdown is likely not worth it.

Think of this as "recent comments on recent articles" and you have the right idea!

Post any ideas for enhancements here. My regards to the original author, who did a great job of hacking Blogger code. My contribution is only to make this more understandable.

Addendum: 2006.03.17
I have made the explanation in section 4 a bit more explicit and added in the complete text of sections 5 and 6.