Permalinks, Gravatars and Django

Wednesday 16 January 2008

I’ve made some changes to this site. In some ways, they are only small changes, but under the hood, they are quite large.

The first change is that each blog entry here now has its own URL. We can debate whether or not I had permalinks the old way: it depends if you accept the fragment identifier in a URL (the part after the hash mark) as part of the permalink. Reddit does not recognize the fragment identifier as part of the URL (something that was pointed out to me by a commenter there), and so it was difficult for them (and probably other sites) to link accurately here. With the new scheme, I hope we can all agree that there are now permalinks.

One of the complexities in writing your own blog software is defending deviations from the norm. The old way of identifying blog posts was different than the vast majority of blog systems out there, so it eventually seemed not just different but truly odd, and incompatibilities with other important parts of the web ecosystem made it actually broken. So now I have one URL per blog post.

The aversion to differences can go too far. Another commenter on reddit also noted that my comment links said “5 reactions” instead of “5 comments”, adding, “wtf?”. Maybe he was kidding. In any case, tough on that one. You’re a human, you can adapt.

As a result of the page-per-post change, comments are handled differently as well. Gone is the pop-up window for entering or reading comments: they are displayed on the page with the post. This presented a typographic challenge — how to visually distinguish the comments from the post itself, without overwhelming the page with rules and dividers? I had long admired Gravatar as being a clever and lightweight way to let people control their appearance on other people’s sites. Adding them to the comments solved the design problem: they added a strong visual element to the comments section, and helped divide one comment from the next without slicing the page into ribbons.

Because most of my commenters don’t have gravatars, I am using automatically-assigned pictures when a gravatar is not available. There are a couple of hundred of these impersonal avatars, and they are assigned based on a hash of your email and site addresses, so you should get the same one each time. The photos are either ones I have taken, or from the public domain category at Wikimedia Commons. None of the impersonal avatars show a person, so if you see a face next to a comment, it is genuine!

Those are the visible changes. The invisible change is how this site is produced. The original technique involved a great deal of XSLT. I started adding the permalink structure with the old XSLT code, and it became too difficult. The old design finally gave out. Now I am using Django, but in an unconventional way. I don’t use a Django-friendly host, and my commenting system is written in PHP. Both are obstacles that can be overcome, but I decided not to take them on now.

So I use Django, but create static HTML files with it, then upload the files to my hosting provider. Jared Kuolt’s StaticGenerator was a piece of serendipity that appeared after I decided on a course of action, but before I needed to write the code myself. The site starts with the same pile of XML source files, but now they are used to build a SQLite database, which is then used by the Django code to produce the HTML files.

So in a few ways, I’ve smoothed out some of the idiosyncracy behind the scenes of this blog, which makes me feel good. I’m glad to have had a chance to make changes on this scale.

Everything should be working just as before, but there may be some hiccups. If you see anything amiss, please let me know!


Jay Graves 9:15 PM on 16 Jan 2008

Gah! I'm a blueberry muffin!

I just set up a Gravatar but it's not showing up. Maybe because you munge the email address?

Kent Johnson 10:11 PM on 16 Jan 2008

Your content is UTF-8, you should set that in the content-type header or in a meta tag to ensure that it displays correctly. On this page, the m-dash after "typographic challenge" doesn't display correctly with the default encoding. (Ah, sweet irony!)

Jay Graves 10:18 PM on 16 Jan 2008

Nevermind. Gravatar is working now.
I'm pretty sure this was my pre-assigned one.

susan senator 6:48 AM on 17 Jan 2008

I have nothing to say, I just wanted to see what I was.

Ned Batchelder 6:55 AM on 17 Jan 2008

Jay & Susan: as they say in kindergarten, "You get what you get and you don't get upset!", but amended with "or you go to and upload whatever pic you like". And yes, Jay, that is exactly the muffin picture I used.

Kent: thanks, that's precisely the sort of problem I knew would creep in. It's being fixed even as I type this..

Gustaf Erikson 7:45 AM on 17 Jan 2008

Ned: shame on reddit for not grokking the fragment identifier, but sometimes you have to bend to the wind so as not to break. As for the person who cannot equate comments with reactions, the back of my hand to him ;)

Interesting to see you're using static HTML rendering, I'm doing the same with blosxom and somehow I find it more satisfying than running dynamically.

Josh 11:28 AM on 17 Jan 2008

Another person eager to find out what my gravatar is!

Shawn Wheatley 12:05 PM on 17 Jan 2008

Sad to see that trying to highlight your post titles is still "weird", at least in Firefox (try it... it seems to highlight right-to-left for some reason?) but I'm glad to see post titles in the page (useful when I your posts) & comments on the same page. Over, I like it! Also curious to see what my avatar will be, since I don't have a "real" Gravatar.

susan senator 12:09 PM on 17 Jan 2008

Can you make the pictures change each time, so that this time I have a different picture?

Ned Batchelder 1:04 PM on 17 Jan 2008

I could make them different each time, but I like having the same person be represented by the same picture each time. It helps to follow the flow of a conversation, no?

susan senator 2:18 PM on 17 Jan 2008

Okay, then, please give me a more fitting flower. I am no white daisy!

Paul Downs 2:46 PM on 17 Jan 2008

Oh what will I be today?

Paul Downs 2:47 PM on 17 Jan 2008

Cool. How did it know?

susan senator 2:50 PM on 17 Jan 2008

And by the way I can't use that link to your site in the reactor email message; it just sits there. Hey Paul, that is just like you! See? Ned, I want a poppy or a delphinium, not a stupid white daisy (no offense to the photographer).

Ned Batchelder 2:59 PM on 17 Jan 2008

OK, kids, settle down. I don't choose them! They are randomly assigned, and the only way to change them is to go to and upload a new photo. Don't make me stop this car! :)

Blake Winton 3:53 PM on 17 Jan 2008

I like the solution this guy came up with. It auto-generates something for you that looks a little like a face, again based on the email address, so it's consistent.

Also, I'm totally hoping for a blueberry muffin. ;)
(Edited to add: Dammit!)

susan senator 8:34 AM on 18 Jan 2008

Thanks for changing me to a bellydancer!!! Let's get married.

Eleanor Batchelder 10:18 AM on 18 Jan 2008

For the first time (in a few days?) my rss reader is reporting some of your old posts as unread, so they show up as duplicate lines in the RSS table of contents. Is this related to your changes, or something on my end?


Ned Batchelder 11:22 AM on 18 Jan 2008

Yeah, because the RSS feed moved and changed subtly, even though it is showing the same old stories, some RSS readers consider them new posts and will show them to you as unread. I had the same experience with Bloglines.

Jared 3:29 PM on 18 Jan 2008

Thanks for calling StaticGenerator a "piece of serendipity". I'm a little unclear though -- Did you end up using it?

Ned Batchelder 4:11 PM on 18 Jan 2008

I am using StaticGenerator. It's one of those tools that is small and only does one thing, but just nails it.

Dave St.Germain 9:21 PM on 18 Jan 2008

gravatar? what the F?!

Al 8:05 AM on 19 Jan 2008


I'm surprised that you wouldn't have jumped ship into a Django friendly host and fired up Coltrane. The strange blend of technologies you're using behind the site at the moment, just seems overtly complex.


Ned Batchelder 8:38 AM on 19 Jan 2008

Al, I can see how my choices here would seem odd and complex, and I'm certainly not trying to convince anyone to adopt them. Maybe I can help you understand some of the factors that went into the blender to produce this strange smoothie:

1) I am a reluctant technology adopter. Changing hosting providers has always felt like a drastic operation to me, and so I am hesitant to switch. In addition, many people seem to have trouble with Django on shared hosting providers, and I am not well-versed in the skills needed to diagnose and fix such problems, so that scared me off a bit. I know there are good providers with well-supported Django stacks, and I researched a few of those, but decided not to move just yet.

2) I doubt I will ever adopt an existing blog package, for a few reasons:

2a) I like writing my own software. It is enjoyable in its own right, and it helps me to learn about technology, whether it be Django, RSS, CSS, whatever.

2b) Having started with my own model of how this blog is put together, I would rather not try to fit it into someone else's model. Backward compatibility is very important to me. This means I want all of my blog posts to continue to exist at their existing URLs (or be redirected from their old URLs). Firing up Coltrane would likely involve a bunch of hacking to get it to accept my old posts, and serve them in the old way. If I'm going to be hacking, I'd rather hack my own stuff.

2c) With my own blog software, I can try out new ways of doing things. I think my spam prevention is better than Akismet, for example. The downside, of course, is that sometimes I do things worse than the norm, or over time, the norm shifts, and I have to play catch up.

So yes, this is a complex system. If I were starting my site and blog today from scratch, I would very likely make different choices.

Ned Batchelder 9:01 AM on 19 Jan 2008

One more thing: in terms of complexity, you don't even know the whole story. Reminiscent of the dirty fork sketch, I'll just say, "Good thing I didn't tell them about the Django-PHP middleware!"

Al 9:37 AM on 19 Jan 2008

I fully appreciate what you're saying regarding the stack, it's still a problem but there are some good providers. I suppose its much like Rails in that regard, you don't want to be using a back yard job or you'll be forever fighting against it; which is the opposite experience that they are meant to be in favour of.

Ned Batchelder 4:25 PM on 19 Jan 2008

Shawn: thanks for mentioning the weird selection of the post titles. I dug into it, and it turns out it was because they were divs set to display:inline and float:left (needlessly). Setting those back to display:block and float:none not only fixed the selection, but also a long standing spacing problem I complained about way back when I first set up this design.

Bob Congdon 2:06 PM on 21 Jan 2008

Ned, Just curious, why does the permalink have a PHPSESSID on it?

Ned Batchelder 3:26 PM on 21 Jan 2008

Bob, an interesting question. I was going to say I didn't see any PHPSESSID on the permalink, when I decided to try IE more intensely. There, I saw one permalink with a PHPSESSID, but most did not. Even the one I did see didn't have it the next time I tried it.

This page suggests it's because you have cookies disabled? That doesn't explain why I saw intermittent session ids, but when I disabled cookies I did get session ids on all local URLs. They also suggest a solution which I've just tried (adding some php config lines), and it seems to stop the behavior.

Does all this agree with your observations?

Add a comment:

Ignore this:
Leave this empty:
Name is required. Either email or web are required. Email won't be displayed and I won't spam you. Your web site won't be indexed by search engines.
Don't put anything here:
Leave this empty:
URLs auto-link and some tags are allowed: <a><b><i><p><br><pre>.