Over eight years ago I turned off commenting on my site owing to the amount of spam that Movable Type was having to cope with. Six years later I moved over to using Django retaining the 2,902 existing comments, but didn’t make it possible to post new ones. Now I have.
I don’t know how much people post comments these days but I used to like reading them, so we’ll see. For now comments will be available on all blog posts (including this one!), with the form disappearing after thirty days to reduce the “attack surface” for spammers. We’ll see how that goes.
I did like getting comments on old posts, which happened when they were found via search engines. My most-visited-from-Google posts these days are some of my notes from books and it was always nice to hear when they were helpful. Keeping comments open forever also meant getting comments like Stewart Brand’s on my notes for his book How Buildings Learn, and this one from Alex Cotton discovering his grandfather mentioned in one of my posts.
Another attempt to avoid spam is using hCaptcha – an alternative to Google’s reCAPTURE which has probably annoyed you several times this week alone. Unfortunately hCapture is no less annoying, possibly more so given that its photos of American vehicles and infrastructure seem even more confusing than Google’s. “Select all the trucks? Is that a bit of a truck? Does a fire engine count as a truck? What about a school bus?” Hopefully it’s not too onerous. We’ll see.
On the off-chance anyone’s interested enough, there’s also a new RSS feed that only includes comments posted across this site.
Those are the main points. If you’re interested in a few technical details, read on, otherwise you’ve probably got better things to do.
§ Hello nerd! When I migrated the site from Movable Type to Django I used django-contrib-comments to store all the existing comments in case I ever wanted to start adding new ones. It used to be part of Django but was separated off years ago and is now kept up-to-date but largely unchanging. It works pretty well – I also use it on Pepys’ Diary which now has nearly 90,000 comments. Another app, django-comments-xtd, adds further features on top of the original; I used that successfully on a client’s site a while back but it’s more than I need here.
When doing the Movable Type to Django migration I did get as far as ensuring the form for adding new comments worked, but not as far as thinking about spam and moderation. So, once I checked that the until-now-hidden form still worked it seemed like there wasn’t much to do. Unsurprisingly I underestimated the fiddly nature of it all and it took longer than expected. Welcome to web development.
First I added the ability to have comments tested by Akismet for spamminess, which usually works pretty well. The little pykismet3 library saved me some time although it still took a while to get things (hopefully) working.
When I first heard about hCaptcha I couldn’t see any already-built ways to integrate it with Django, so assumed I’d have to adapt something that used reCAPTCHA. But by the time I got round to working on this I noticed the new django-hcaptcha app by Andrej Zbín. Again, it’s only small but it saved me some time. People sharing stuff like this makes me happy.
So, in terms of preventing spam we have:
- Akismet testing for spamminess
- django-contrib-comment’s currently-turned-off ability to have me approve comments before publication, either if the blog post is more than n days old, or as a blanket rule
We’ll see how all that goes.
Setting up and rationalising all the ways comments can be disabled was quite annoying. There’s:
- A system-wide code setting to disable/enable commenting
- A per-blog setting to disable/enable comments on all of its posts
- A per-post setting to disable/enable comments on each one
- A system-wide “disable comments after n days setting”
Figuring out the precedence of those wasn’t too bad but still. I even wrote tests as if I’m a real developer.
The RSS feed for comments is, like the others on this site, generated using Django’s syndication framework. As with the other feeds I’m making life harder for myself by adding the
<content:encoded> element which I’m pretty sure used to be required in order to include the entire post/comment content but I’m not sure it is now. I think
<description> can contain everything? Anyway, old habits, etc, so I continued with my much modified feed-generation code.
Thanks to django-contrib-comment it’s easy to set things up so I receive an email whenever a new comment is posted but who wants more email, especially if it might contain lots of spam? So I created two further RSS feeds solely for my use:
- One feed that’s the same as the public comments feed, but with links to edit or delete the comment.
- Another feed that’s all unpublished comments, which should be those Akismet thinks are spam, with links to edit or publish them.
I’m more likely to read those when I’m not sitting at my computer – I try to avoid email at other times – so that should work. I guess I could add them to a channel in my private Slack and receive notifications too…
All in all it took longer than expected. I thought it’d be maybe a couple of days’ work and I greatly enjoyed it at first. Tinkering with one’s own website is, I guess, like making your own kit car, or building a shed, or some other constructive hobby. But after a while it dragged on, every completed task generating one more. You can see the GitHub issue where I added further tasks (after “Also:”) the more I worked on it. This was exactly why you should never build your own website from scratch. It was one of those Zeno’s paradox development marches that never seems to end. Every day a couple of hours of tinkering left me no closer to finishing.
And yet here we are. Take that Zeno.