WordPress to ClassicPress

As I mentioned in my recent Blog Questions Challenge, I recently switched my blog from WordPress, which it had been running on for over 20 years of its 26 year history, to ClassicPress.1 I’m aware that I’m not the only person for whom ClassicPress might be a better fit than WordPress2, so I figured I should share the process by which I undertook the change.

Switching from WordPress to ClassicPress

Switching from WordPress to ClassicPress should be a non-destructive, 100% reversible process, but (even though I’ve got solid backups) I wasn’t ready to trust that, so I decided to operate on a copy of my site. I’m glad I did, because there were a couple of teething issues I needed to tackle before I could launch.

1. Duplicating the site

I took a simple approach to duplicating the site: (1) I copied the site directory, and (2) I copied the database, and (3) I set up a new subdomain to use for testing. Here’s how I did each step:

1.1. Copying the site directory

This should’ve been simple, but a du -sh revealed that my /wp-content/uploads directory is massive (I should look into that) and I didn’t want to clone it. And I didn’t want r need to clone my /wp-content/cache directory either. So I ran:

  1. rsync -av --exclude=wp-content ./old-site-directory/ ./new-site-directory/ to copy everything except wp-content, and then
  2. rsync -av --exclude=uploads --exclude=cache ./old-site-directory/wp-content/ ./new-site-directory/wp-content/ to copy wp-content except the uploads and cache subdirectories, and then finally
  3. ln -s ./old-site-directory/wp-content/uploads ./new-site-directory/wp-content/uploads to symlink the uploads directory, sharing it between the two sites

1.2. Copying the database

I just piped mysqldump into mysql to clone from one database to the other:

mysqldump -uUSERNAME -p --lock-tables=false old-site-database | mysql -uUSERNAME -p new-site-database

I edited DB_NAME in wp-config.php in the new site’s directory to point it at the new database.

Screenshot from nano, editing wp-config.php. The constant defintions for DB_NAME, DB_USER, and DB_PASSWORD are highlighted with the text 'change these!'.
If you’re going to clone your WordPress site before converting to ClassicPress, you’ll want to be comfortable editing your wp-config.php.

1.3. Setting up a new subdomain

My DNS is already configured with a wildcard to point (almost) all *.danq.me subdomains to this server already. I decided to use the name classicpress-testing.danq.me as my temporary/test domain name. To keep any “changes” to my cloned site to a minimum, I overrode the domain name in my wp-config.php rather than in my database, by adding the following lines:

define('WP_HOME','https://classicpress-testing.danq.me');
define('WP_SITEURL','https://classicpress-testing.danq.me');

Because I use Caddy/FrankenPHP as my webserver3, configuration was really easy: I just copied the relevant part of my Caddyfile (actually an include), changed the domain name and the root, and it just worked, even provisioning me out a LetsEncrypt SSL certificate. Magical4.

2. Switching the duplicate to ClassicPress

Now that I had a duplicate copy of my blog running at https://classicpress-testing.danq.me/, it was time to switch it to ClassicPress. I started by switching my wp-admin colour scheme to a different one in my cloned site, so it’d be immediately visually-obvious to me if I’d accidentally switched and was editing the “wrong” site (I also made sure I was logged-out of my primary, live site, so I was confident I wouldn’t break anything while I was experimenting!).

ClassicPress provides a migration plugin which checks for common problems and then switches your site from WordPress to ClassicPress, so I installed it and ran it. It said that everything was okay except for my (custom) theme and a my self-built plugins, which it understandably couldn’t check compatibility of. It recommended that I install Twenty Seventeen – the last WordPress default theme to not require the block editor – but I didn’t do so: I was confident that my theme would work anyway… and if it didn’t, I’d want to fix it rather than switch theme!

ClassicPress migration plugin showing a series of green checks: everything's good to go.
I failed to take a screenshot of the actual process, but it looked broadly like this.

And then… it all broke.

3. Fixing what broke

After swiftly doing a safety-check that my live site was still intact, I started trying to work out why my site wasn’t broken. Debugging a ClassicPress PHP issue is functionally identical to debugging a similar WordPress issue, for obvious reasons: check the logs, work out what’s broken, realise it’s a plugin, disable that plugin while you investigate further, etc.

ClassicPress reporting 'There has been a critical error on this website.'
Yeah, I should have expected this. And I did.

In my case, the “blocking” issues were:

  • Jetpack: this plugin does not play nicely with ClassicPress, presumably because it fails if it’s unable to register a block. Fortunately, I wasn’t actually using Jetpack for anything other than for VaultPress (which has saved my butt on at least one occasion and whose praises I sing), so I uninstalled Jetpack and installed the standalone plugin version of VaultPress instead, which worked fine.
  • EWWW Image Optimizer: I use this plugin to pregenerate WebP variants of my images, which I then serve using webserver rules. It’s not a complex job, and I should probably integrate the feature into my theme at some point, but for now I use this plugin. Version 8.0.0 of the plugin doesn’t work on ClassicPress 2.3.1, so I used WP-CLI to downgrade to the last version that does (7.7.0), and then it worked fine.
  • Dan’s Geocaching Log Reposter: a self-made plugin that copies my logs from geocaching websites stopped working properly, which I think is because ClassicPress is doing a more-aggressive job than WordPress at nonce validation on admin REST endpoints? I put a quick hack into my plugin to work around it, but I’ll need to look into this properly at some point.
  • Some other bits of my stack, e.g. CapsulePress (my Gemini/Spartan/Nex server), have their own copies of my database credentials, because I’ve been too lazy to centralise them into environment variables, and needed updating (but not until live switchover time).

Everything else worked fine, as far as I’ve determined in the weeks that have followed. My other plugins, which include Advanced Editor Tools (I should probably look into Enriched Editor), Antispam Bee, Google Authenticator, IndieAuth, Post Kinds, Post Snippets, Regenerate Thumbnails, Syndication Links, Webmention, WebSub, and WP-SCSS all “just worked”.

4. Completing the switchover

I ran the two sites in-parallel for a couple of weeks, with the ClassicPress one as a “read only” version (so I didn’t pollute my uploads directory!), but it was pretty unnecessary because it all worked pretty seamlessly, despite my complex stack of custom code. When I wanted to switch for-real, all I needed to do was swap the domain names over in my Caddyfile and edit the wp-config.php of my ClassicPress installation: step 1.3, but in reverse!

If you hadn’t been told5, you probably wouldn’t have even known I’d made a change: I suppress basically all infrastructure-identifying headers from my server output as a matter of course, and ClassicPress and WordPress are functionally-interchangeable from a front-end perspective6.

So what’s difference?

From my experience, here are the differences I’ve discovered since switching from WordPress to ClassicPress:

The good stuff

  • 😅 ClassicPress has no Gutenberg/block editor. This would absolutely be a showstopper for many people, and that’s fine: I have nothing against the block editor (I use it basically every day elsewhere!), but I’ve never really used it on danq.me and don’t feel the need to change that! My theme, my workflow, and my custom plugins are all geared around the perfectly-good “classic” editor, and so getting a more-lightweight CMS by removing a feature I wasn’t using anyway falls somewhere between neutral and a blessing.
  • The backend is fast again! One of the changes the ClassicPress team have been working on applying to WordPress is to strip out jQuery and other redundancies from the backend, and I love how much faster and lighter my editor interface is as a result. (With caveat; see below!)
  • 🔌Virtually everything “just works”. With the few exceptions described above, everything works exactly as it does under WordPress. Which is what you’d hope for a fork that’s mostly “WordPress, but without the block editor”, right, but it’s still reassuring (and, for me, an essential feature). There are a few “new” features to do with paging through posts and the media library and they’re fine, I suppose, but not by themselves worth switching for (though it might be nice to backport them into WordPress!).

The bad stuff

  • 🏷️ Adding tags to posts takes a step backwards. A side-effect of dropping jQuery is the partial loss of the autocomplete feature when selecting tags to add to a post. You still get a partial autocomplete, but not after typing a comma: you need to press enter to submit the tag you were writing and then start typing them next, which frankly sucks. This is because they’re relying on a <datalist>, which isn’t as full-featured as the Javascript solution WordPress employs. This bugs me almost enough to be a showstopper, but I gather it’s getting fixed in a near-future version.
  • 🗺️ You’re in uncharted territory when things go wrong. One great benefit of WordPress is the side-effects of its ubiquity. If you have a query or a problem you can throw a stone at your favourite search engine and get a million answers… and some of them will even be right! If you have a problem in ClassicPress and it’s not shared with (or you’re not sure if it’s shared with) WordPress… you’re mostly on your own. The forums are good and friendly, but if you want a quick answer to something, you’re likely to have to roll your sleeves up and open some source code. I don’t mind this at all – when I first started using WordPress, this was the case, too! – but it might be a showstopper for some folks.

In summary: I’m enjoying using ClassicPress, even where there are rough edges. For me, 99% of my experience with it is identical to how I used WordPress anyway, it’s relatively lightweight and fast, and it’s easy enough to switch back if I change my mind.

Footnotes

1 It saddens me that I have to keep clarifying this, but I feel like I do: my switch from WordPress to ClassicPress is absolutely nothing to do with any drama in the WordPress space that’s going on right now: in fact, I’d been planning to try it out since before any of the drama appeared. I appreciate that some people making a similar switch, including folks who use this blog post as a guide, might have different motivations to me, and that’s fine too. Personally, I think that ditching an installation of open-source WordPress based on your interpretation of what’s going on in the ecosystem is… short-sighted? But hey: the joy of open source is you can – and should! – do what you want. Anyway: the short of it is – the desire to change from WordPress to ClassicPress was, for me, 100% a technical decision and 0% a political one. And I’ll thank you for leaving any of your drama at the door if you slide into my comments, ta!

2 Matt recently described ClassicPress as “the last decent fork attempt for WordPress”, and I absolutely agree. There’s been a spate of forks and reimplementations recently. I’ve looked into many of them and been… very much underwhelmed. Want my hot take? Sure, here you go: AspirePress is all lofty ideas and no deliverables. FreeWP seems to be the same, but somehow without the lofty ideas. ForkPress is a ghost. Speaking of ghosts, Ghost isn’t a WordPress fork; they have got some cool ideas though. b2evolution is even less a WordPress fork but it’s pretty cool in its own right. I’m not sure what clamPress is trying to achieve but I’ve not given it a serious look. So yeah: ClassicPress is, in my mind, the only WordPress fork even worth consideration at this point, and as I describe in this blog post: it’s not for everybody.

3 I switched from Nginx over the winter and it’s been just magical: I really love Caddy’s minimal approach to production configuration. The only thing I’ve been able to fault it on is that it’s not capable of setting up client-side SSL certificate authentication on a path, only on an entire domain, which meant I needed to reimplement the authentication mechanism I use on a small part of my (non-blog) internal infrastructure.

4 To be fair, it wouldn’t have been hard if I’d still be using Nginx, because I’d set up Certbot to use DNS-based vertification to issue me wildcard SSL certificates. But doing this in Caddy still felt magical.

5 And assuming you don’t religiously check my colophon page.

6 Indeed, I wouldn’t have considered a switch to ClassicPress in the first place if it wasn’t a closely-aligned-enough fork that I retained the ability to flip-flop between the two to my heart’s content! I’ve loved WordPress for over two decades; that’s not going to change any time soon… and if e.g. ClassicPress ceased tracking WordPress releases and the fork diverged too far for my comfort, I’d probably switch back to regular old WordPress!

× × ×

Frustrating At Scale

This is a repost promoting content originally published elsewhere. See more things Dan's reposted.

Large companies find HTML & CSS frustrating “at scale” because the web is a fundamentally anti-capitalist mashup art experiment, designed to give consumers all the power.

This. This is what I needed to be reminded, today.

When somebody complains that the Web is hard to scale, they’re already working against the grain of the Web.

At its simplest – and the way we used to use it – a website is a collection of .html files, one of which might have a special name so the webserver knows to put it first.

Writing HTML is punk rock. A “platform” is the tool of the establishment.

Thanks, Mia.

Queers make the world a safer place

This is a repost promoting content originally published elsewhere. See more things Dan's reposted.

A straight white guy friend was complaining about not being able to find any gaming groups for WoW that weren’t full of MAGA assholes. He said he keeps joining guilds with older (60+) casual gamers like himself because he can’t keep up with the kids, and he’ll start to make friends, but then they will reveal themselves to be Trump-lovers. He asked, “What am I doing wrong?”

This was about 3 months ago. Now, he tells me he joined a guild labeled as LGBTQ-friendly and has made several new cool friends.

He mentioned that there are many women and PoC in the group too, and “Everyone’s so nice on dungeon runs, telling people they did a good job and being supportive, sharing loot.”

I didn’t tell him that this is what the whole world would be like without patriarchal toxic masculinity, because I think he figured it out himself.

I’ve plucked out the highlights, but the deeper moral is in the full anecdote. I especially loved “…furries are like lichen…”. 😆

BBC News RSS… your way!

It turns out my series of efforts to improve the BBC News RSS feeds are more-popular than I thought. People keep asking for variants of them, and it’s probably time I stopped hosting the resulting feeds on my NAS (which does a good job, but it’s in a highly-kickable place right under my desk).

Screenshot of BBC News RSS Feeds (that don't suck!).
The new site isn’t pretty. But it works.

So I’ve launched BBC-Feeds.DanQ.dev. On a 20-minute schedule, it generates both UK and World editions of the BBC News feeds, filtered to remove iPlayer, Sounds, app “nudges”, duplicates, and other junk, and optionally with the sports news filtered out too.

The entire thing is open source under an ultra-permissive license, so you can run your own copy if you don’t want to use mine.

Enjoy!

BBC News RSS… with the sport?

Earlier today, somebody called Allan commented on the latest in my series of several blog posts about how I mutilate manipulate the RSS feeds of BBC News to work around their (many, and increasingly so) various shortcomings, specifically:

  1. Their inclusion of non-news content such as plugs for iPlayer and their apps,
  2. Their repeating of identical news stories with marginally-different GUIDs, and
  3. All of the sports news, which I don’t care about one jot.

Well, it turns out that some people want #3: the sport. But still don’t want the other two.

FreshRSS screenshot with many unread items, but focussing on a feed called "BBC News (with sport)" and showing a story titled: 'How England Golf's yellow cards are tackling blight of slow play'
Some people actually want to read this crap, apparently.

I shan’t be subscribing to this RSS feed, and I can’t promise I’ll fix it if it gets broken. But if “without the crap, but with the sports” is the way you like your BBC News RSS feed, I’ve got you covered:

So there you go, Allan, and anybody in a similar position. I hope that fulfils your need for sports news… without the crap.

×

Sabbatical Lesson #1: Boundaries

Today was my first day back at work after three months of paid leave1. I’d meant to write about the overall experience of my sabbatical and the things I gained from it before I returned, but I’m glad I didn’t because one of the lessons only crystallised this morning.

A French Bulldog wearing a teal jumper pulls away at her red lead as she walks down a dirt path between gardens. Freezing fog hangs in the air up ahead.
This is about the point on the way back from the school run at which I pull out my phone and see what’s happening in the world or at work. But not today.

My typical work schedule sees me wake up some time before 06:30 so I can check my notifications, formulate my to-do list for the day, and so on, before the kids get up. Then I can focus on getting them full of breakfast, dressed, and to school, and when I come back to my desk I’ve already got my day planned-out. It’s always felt like a good way to bookend my day, and it leans into my “early bird” propensities2.

Over the last few years, I’ve made a habit of pulling out my phone and checking for any new work Slack conversations while on the way back after dropping the kids at school. By this point it’s about 08:45 which is approximately the time of day that all of my immediate teammates – who span five timezones – have all checked-in. This, of course, required that I was signed in to work Slack on my personal phone, but I’d come to legitimise this bit of undisciplined work/life-balance interaction by virtue of the fact that, for example, walking the dog home from the school run was “downtime” anyway. What harm could it do to start doing “work” things ten minutes early?

Dan, wearing a purple t-shirt, looks at the camera while pointing at the centre of three computer screens which share a cluttered desk, each of which shows a stylised image version of the Automattic Creed.
Here. Here is where work happens (or, y’know, anywhere I take my work laptop to… but the crucial thing is that work has a time and a place, and it doesn’t include “while walking the dog home after dropping the kids at school”).

But walking the dog isn’t “downtime”. It’s personal time. When I’m looking at your phone and thinking about work I’m actively choosing not to be looking at the beautiful countryside that I’m fortunate enough to be able to enjoy each morning, and not to be thinking about… whatever I might like to be thinking about! By blurring my work/life-balance I’m curtailing my own freedom, and that’s bad for both my work and personal lives!

My colleague Kyle recently returned from six months of parental leave and shared some wisdom with me, which I’ll attempt to paraphrase here:

It takes some time at a new job before you learn all of the optimisations you might benefit from making to your life. This particular workflow. That particular notetaking strategy. By the time you’ve come up with the best answers for you, there’s too much inertia to overcome for you to meaningfully enact personal change.

Coming back from an extended period of leave provides the opportunity to “reboot” the way you work. You’re still informed by all of your previous experience, but you’re newly blessed with a clean slate within which to implement new frameworks.

He’s right. I’ve experienced this phenomenon when changing roles within an organisation, but there’s an even stronger opportunity, without parallel, to “reboot” your way of working when returning from a sabbatical. I’ve got several things I’d like to try on this second chapter at Automattic. But the first one is that I’m not connecting my personal phone to my work Slack account.

Footnotes

1 My employers’ sabbatical benefit is truly an epic perk.

2 Mysteriously, and without warning, at about the age of 30 I switched from being a “night owl” to being an “early bird”, becoming a fun piece of anecdotal evidence against the idea that a person’s preference is genetic or otherwise locked-in at or soon after birth. As I’ve put it since: “I’ve become one of those chirpy, energetic ‘morning people’ that I used to hate so much when I was younger.”.

× ×

James Acaster’s Classic Scrapes

Book cover of James Acaster's Classic Scrapes.On the flight over to Trinidad I finished reading James Acaster’s Classic Scrapes by James Acaster, which I received as part of our family’s traditional Christmas Eve book exchange. I’m a big fan of his stand-up work (and I maintain that his 2018 serialised show Repertoire is among of the most artfully-crafted pieces of live comedy ever written) and clearly JTA recalled this fact when giving me this book.

Many of the stories in Classic Scrapes have featured in his work before, in various forms, and I found myself occasionally recognising one and wondering if I’d accidentally skipped back a chapter. It helps a lot to read them in Acaster’s “voice” – imagining his delivery – because they’re clearly written to be enjoyed in that way. In the first few chapters the book struggled to “grab” me, and it wasn’t until I started hearing it as if I were listening in to James’s internal monologue that it gave me my first laugh-out-loud moment.

After that, though, it got easier to enjoy each and every tall tale told. Acaster’s masterful callback humour ties together anecdotes about giant letter Ws, repeated car crashes, and the failures of his band (and, I suppose, almost everything else in his life, at some point or another), across different chapters, which is fun and refreshing and adds a new dimension to each that wouldn’t be experienced in isolation.

A further ongoing concept seems to be a certain idolisation of Dave Gorman, whose Are You Dave Gorman? and Googlewhack storytelling style was clearly an inspiration. In these, of course, a series of (mis)adventures with a common theme or mission becomes a vehicle for a personal arc within which the absurdity of the situations described is made accessible and believable. But with James Acaster’s self-deprecating style, this is delivered as a negative self-portrayal: somebody who doesn’t live up to their idea of their own hero, and becomes a parody of themselves for trying. It’s fun, but perhaps not for everybody (I tried to explain to Ruth why I’d laughed out loud at something but then needed to explain to her who Dave Gorman is and why that matters.)

A fun read if you enjoy Acaster’s comedic style.

×

Entitled by Kate Manne

Book cover: Entitled by Kate Manne. Subtitle: How Male Privilege Hurts Women. Shows a picture of two playing cards; the King of Diamonds sits atop, mostly-covering the Queen of Hearts beneath.I just finished reading Kate Manne‘s Entitled. I can’t remember where I first heard about it or why I opted to buy a copy, but it had been sitting in my to-read pile for a while and so I picked it up last month to read over the festive period.

The book takes a pop-sci dive into research around male entitlement and the near-universal influence of patriarchal ideology. It’s an often bleak and sometimes uncomfortable read: Kate Manne draws a line connecting the most egregious and widely-reported abuses of power by men to much-more-commonplace “everyday” offences, many of which are routinely overlooked or dismissed. The examples she provides are a sad reminder of quite how deeply-embedded into our collective subconscious (regardless of our genders) are our ideas of gender roles and expectations.

It’s feels somewhat chastening to see oneself in some of those examples, whether by my own assumed entitlement or merely by complicity with problematic social norms. We’ve doubtless all done it, at some point or another, though, and we don’t make progress towards a better world by feeling sorry for ourselves. By half way through the book I was looking for action points that never came; instead, the author (eventually) lays out what she’s doing and leaves the reader to make their own decisions.

The vast majority of the book is pretty bleak, and it takes until the final chapter before it reaches anything approximating hope (although the author refrains from classifying it as such), using Manne’s then-imminent parenthood as a vehicle. She finishes by talking about the lessons she hopes to impart to her daughter about how to thrive in this world, which seems less-optimistic than discussing, perhaps, how to improve the world for everybody, but is still the closest thing it delivers to answering “what can we do about this?”.

But I suppose that’s the message in this book: male entitlement is a product of our endemic patriarchy and, try as we might, it’s not going away any time soon. Instead, we should be picking our battles: producing a generation of women and girls who are better-equipped to understand and demand their moral rights and of men and boys who try to work against, rather than exploit, the unfair advantages they’re afforded at the expense of other genders.

That I’d hoped to come to the end of the book with a more feel-good outlook betrays the fact that I’d like there to be some kind of magical quick fix to a problem that I’ve certainly helped perpetuate. There isn’t, and that’s a let down after the book’s uncomfortable ride (not a let down on the part of the book, of course: a let down on the part of the world). The sadness that comes from reading it is magnified by the fact that since its publication in 2020, many parts of the Western world and especially Manne’s own USA have gotten worse, not better, at tackling the issue of male entitlement.

But wishful thinking doesn’t dismantle the patriarchy, and I was pleased to get to the back cover with a slightly sharper focus on the small areas in which I might be able to help fight for a better future. A good read, so long as you can tolerate the discomfort that may come from casting a critical lens over a society that you’ve been part of (arguably it could be even-more-important if you can’t tolerate such a discomfort, but that’s another story).

(In 2025 I’m going to try blogging about the books I read, in addition to whatever else I write about. Expect an eclectic mix of fiction and non-fiction, probably with a few lapses where I forget to write about something until well after I’m deep into what follows it and then forget to say anything about it ever.)

×

Moving Three Rings’ Servers

Yesterday, I fulfilled the primary Three Rings objective I set for myself when I kicked off my sabbatical twelve weeks ago and migrated the entire application to a new hosting provider (making a stack of related improvements along the way).

Network diagram but with entities having faces and named Chungus, Atul, Summer, Gwen, Alice, Astrid, and Demmy.
If you ignore the smiley faces and names my 10-year-old annotated it with, this diagram’s a reasonably-accurate representation of what each of our three production server clusters look like.

I did some work on this project during my Three Rings-focussed International Volunteer Day last week, but it feels like I’ve been working on it for much longer than that. And it feels like it… because I have been.

Months prior, I was comparing different providers and their relative merits, making sure that our (quirky and specific) needs could be met. Weeks beforehand, I was running a “dry run” every four or five days, streamlining the process of moving the ~450GB1 of live data while minimising downtime. Days before the event felt like the countdown for a rocket launch, with final preparations underway: reducing DNS time-to-lives, ensuring users knew about our downtime window, and generally fitting in a little time to panic.

Terminal screenshot showing a directory listing of a logs directory with several gzipped logfiles with different date-stamped suffixes, and the contents of the logrotate configuration file that produced them.
I made reference on International Volunteer Day to how we needed to configure logrotate. When you’re building architecture for a system as gnarly as Three Rings, there’s about a billion tools that need such careful tweaking2.
The whole operation was amazingly successful. We’d announced an at-risk period of up to six hours and I was anticipating it taking three… but the whole thing was completed within a downtime window of just two and a half hours. And I fully credit all of the preparation time. It turns out that “measure twice, cut once” is a sensible strategy3.

It’s challenging to pull off a “big”, intensive operation like this in an entirely voluntary operation. I’m not saying I couldn’t have done it were I not on sabbatical, but it’d certainly have been harder and riskier.

But then, I also couldn’t have done it without the kickass team of volunteers I’ve surrounded myself with. I guess the real success story here is in the power of a well-aligned team and in volunteer effort.

Footnotes

1 Three Rings‘ user data is represented by a little under 70GB of MariaDB databases plus about 380GB of organisational storage: volunteer photos, files, email attachments, and the like. Certainly not massive by comparison to, say, social media sites, search engines, and larger eCommerce platforms… but large enough that moving it takes a little planning!

2 Okay, a billion tools to configure? That’s an exaggeration. Especially now: since the architectural changes I’ve put in place this week, for example, production app server builds of Three Rings no require a custom-compiled build of Nginx (yes, this really was something we used to need).

3 Which you’d think I’d have realised with my more-successful recent second attempt at secret-cabinet-making.

× ×

99 Days of Blogging

With this post, for the first time ever1, I’ve blogged for 99 consecutive days!2

Calendar showing Sunday 25 August through Sunday 1 December inclusive, with a coloured "spot" on each day with a size corresponding to the number of posts made on that day, broken into a pie chart showing the proportion of different post kinds.
The dots are sized based on the number of posts and broken-down by post kind: articles are blue, notes are green, checkins are orange, reposts are purple, and replies are red3.
I didn’t set out with the aim of getting to a hundred4, as I might well manage tomorrow, but after a while I began to think it a real possibility. In particular, when a few different factors came together:

Previous long streaks have sometimes been aided by pre-writing posts in bulk and then scheduling them to come out one-a-day6. I mostly don’t do that any more: when a post is “ready”, it gets published.

I didn’t want to make a “this is my 100th day of consecutive blogging” on the 100th day. That attaches too much weight to the nice round number. But I wanted to post to acknowledge that I’m going to make it to 100 days of consecutive blogging… so long as I can think of something worth saying tomorrow. I guess we’ll all have to wait and see.

Footnotes

1 Given that I’ve been blogging for over 26 years, that I’m still finding noteworthy blogging “firsts” is pretty cool, I think

2 My previous record “streak” was only 37 days, so there’s quite a leap there.

3 A massive 219 posts are represented over the last 99 days: that’s an average of over 2 a day!

4 This isn’t an attempt at #100DaysToOffload; I already achieved that this year as it does not require consecutive days. But it’s a cool challenge anyway.

5 My site’s backed by WordPress, but the mobile wp-admin isn’t the best and my site’s so-customised that apps like Jetpack mangle my metadata.

6 As you might now, I consider myself to be the primary audience for my blog: everybody else comes second. That’s why I don’t collect any webstats! When I used to collect webstats, I would sometimes pre-write and “schedule” posts, but without them it just feels pointless to do so!

×

Sadder Than Fiction

Duration

Podcast Version

This post is also available as a podcast. Listen here, download for later, or subscribe wherever you consume podcasts.

On a number of occasions over the first two decades of this century I’ve attempted to write a particular short story with a science fiction/alternate history feel. Now, I’ve given up on it, and that’s… fine.

Fiction

The story’s taken several forms over the years, but the theme’s always been the same: a crazy narrative spun by an isolated society turns out, incredibly, to be true. But ultimately the people who discover that fact choose to keep it a secret because the flawed lie they live in is preferable to the instability and chaos that they fear could result. It taps into ideas about conspiracy theories, hidden worlds, and the choices we make when we have to choose between living authentically or living comfortably.

Screenshot from Obsidian, showing a Writing folder containing Suicide of a Time Traveller, Compression, Everybody Remembers That Show, and (selected) The Korean Incident.
Guess this Obsidian note is off to the “Never” folder, now.

In its most-concrete form, the story covered the political aftermath of the capture by the DPRK of a fishing boat that (allegedly) drifted into North Korean waters1. The North Korea of the story represents the country at its most isolationist and mysterious, and the captured trawler crew are surprised to experience at Pyongyang a socialist utopia supported by futuristic technology. It turns out that North Korea’s in-universe propaganda is true: they really are an advanced self-reliant nation whose message of peace is being distorted by Western imperialist leaders. Insofar as the truth is known in the West, it’s suppressed for fear that the Korean model represents a democratic, post-scarcity future that threatens to undermine the power of the oligarchs of the world.

When the boat and those aboard it are repatriated with the assumption that they will act as ambassadors to the outside world, the crew are subjected to interrogations and cajoling by their home nations. They mustn’t talk about what they saw North of the 38th parallel, they’re told, with threats of imprisonment and violence if they do and financial inducements offered for their compliance. But in the end, the most-effective message for getting the wayward fisherfolk on side is their realisation that the world isn’t ready for the truth. In a dialogue between the imprisoned seafarers, they agree that they should take the bribes and return quietly to their families, not for their own sake but because they believe that telling their story would lead to a terrible war between two equally-matched parties: a small nation armed with futuristic sci-fi weapons, on one side, and the might of the nuclear superpowers of the rest of the world.

As the sun sets behind growing clouds, a small fishing vessel flying a red flag glides across a moderately-smooth ocean.

As a final twist, it’s revealed that the captain of the vessel was actually a spy, aware of the truth the entire time, who allowed the boat to go off-course with an aim of gathering information on the North Korean situation. The story finishes with the captain, having been instrumental in persuading their crew not to share what they saw, wavering in their confidence, and possibly being implied to be the author of the story.

Re-reading my notes and drafted content, I’ve got to admit that it’s got a certain feel of… Dr. Strangelove discovers Wakanda? Or maybe more like the Pueblo incident set in the world of They Live.2 It might’ve been fun to finish, someday, but now it’s not.

Sadder

That nod to Dr. Strangelove is apt, because my aim was to write something which looked farcically at the nature of political competition on a global scale, in a world in which the zaniest possible conspiracy theory turned out to be true. Strangelove used the existence of a Project Sundial-style doomsday device as the surprise truth; I was using the idea that DPRK propaganda might actually be more-honest than the narratives of its rivals3.

George C. Scott playing General Turgidson in Dr. Strangelove.
“Gee, I wish we had one of them doomsday machines,” was funnier when nuclear annihilation was the only existential threat we were routinely talking about. Nowadays saying it sounds like it carries a bit of Farnsworth’s dejected “I don’t want to live on this planet anymore” energy.

In my off-and-on-again long-running effort to pen the story, I last made any real effort back in around 2015-2016. Since then, the entire concept hasn’t been funny any more. Today, the story would be less farce than lampoonery, and not in a good way.

When I first envisaged the concept of the story, researching conspiracy theories meant laughing at Flat Earthers and picking holes in the arguments of the proponents of a “moon landing hoax”. For the most part, conspiracy theories seemed ridiculous, but not dangerous4. But somewhere along the way from then to now, conspiracy theories started becoming more… mainstream?

Woman wearing a tinfoil hat, thinking "if it looks like a duck and it quacks like a duck, it's probably... part of Bill Gates' secret drone army, delivering microchips for the Reptilians to put into our vaccines!"
Don’tcha miss when conspiracy theorists were mostly harmless idiots?

And that made the story… not fun, any more. Convicted felon Donald Trump loves to claim that a deep state cabal of leftists and big tech companies are suppressing his voice. Or that immigrants are eating pets. Or that the announcement of Osama bin Laden’s death was timed carefully so that people would watch news about that rather than Trump’s show Celebrity Apprentice5.

It turns out that my comedy villain – the leader of the “free” world who leverages enormous power to lie to and manipulate everybody – isn’t a laughing matter any more.

Perhaps I should try my hand at writing bleak, dystopian fiction instead.

Footnotes

1 Like this incident in 2009, perhaps, although there are lots of similar examples before and since.

2 In my notes somewhere I’ve got a concept that I never explored for the story which was that North Korea is under the control of a benevolent alien species trying to uplift humanity, while much of the rest of the developed world is under the influence of a malicious alien species who’re using their position to push humans to terraform Earth into something more-suited to their needs. So maybe like The Forge of God but with a climate change message? I never really worked on this idea though because it felt like I was weaving too many concepts into one tiny narrative.

3 Both are bonkers-crazy ideas, but Project Sundial is, sadly, more-believable: Kurzgesagt did a fun video about it recently.

4 Obviously I know there are exceptions and I’m speaking from a position of privilege. For a long while, for example, conspiracy theories relating to holocaust denialism have caused real harm to people. And of course there’s for a long while been actual damage caused by folks who (loudly) subscribe to false beliefs about HIV, or 9/11, or Sandy Hook, and countless others.

5 This is the kind of conspiracy theory that should be funny: idiot who bitches about claimed birthplace of president annoys that president enough that he times a battle with a wanted terrorist, so that the terrorist’s death will coincide with the timeslot of the idiot’s TV programme. But somehow, the way that politics has gone lately, especially in the USA, means that it’s not funny any more. Easily-disprovable conspiracy theories were amusing when they were the territory of crazy fringe groups; once they get tens of thousands of (armed, militant) believers, they go from being an amusement to being a dangerous cult.

× × × ×

Hour of Ambiguity

Here in my hotel room, high above Barcelona, I woke up. It was still dark outside, so I looked to my phone – sitting in its charging cradle – as a bedside clock. It told me that the time was 02:30 (01:30 back home), and that the sun would rise at 07:17.

But how long would it be, until then?

Daylight savings time is harmonised across Europe by EU Directive 2000/84/EC1, but for all the good this harmonisation achieves it does not perfectly remove every ambiguity from questions like this. That it’s 02:30 doesn’t by itself tell me whether or not tonight’s daylight savings change has been applied!

It could be 00:30 UTC, and still half an hour until the clocks go back, or it could be 01:30 UTC, and the clocks went back half an hour ago. I exist in the “hour of uncertainty”, a brief period that happens once every year2. Right now, I don’t know what time it is.

I remember when it first started to become commonplace to expect digital devices to change their clocks twice a year on your behalf. You’d boot your PC on a morning and it’d pop up a dialog box to let you know what it had done: a helpful affordance that existed primarily, I assume, to discourage you from making the exact same change yourself, duplicating the effort and multiplying the problem. Once, I stayed up late on last Saturday in March to see what happened if the computer was running at the time, and sure enough, the helpful popup appeared as the clocks leapt forward, skipping over sixty minutes in an instant, keeping them like leftovers to be gorged upon later.

Computers don’t do that for us anymore. They still change their clocks, but they do it silently, thanklessly, while we sleep, and we generally don’t give it a second thought.

That helpful dialog that computers used to have had a secondary purpose. Maybe we should bring it back. Not as a popup – heaven knows we’ve got enough of those – but just a subtle subtext at the bottom of the clock screens on our phones. “Daylight savings: clock will change in 30 minutes” or “Daylight savings: clock changed 30 minutes ago”. Such a message could appear for, say, six hours or so before and after our strange biannual ritual, and we might find ourselves more-aware as a result.

Of course, I suppose I could have added UTC to my world clock. Collapsed the waveform. Dispelled the ambiguity. Or just allowed myself to doze off and let the unsleeping computers do their thing while I rested. But instead I typed this, watching as the clock reached 02:59 and then to 02:00. I’d started writing during summertime; I’d finished after it ended, a few minutes… earlier?

Daylight savings time remains a crazy concept.

Footnotes

1 Why yes, I am the kind of nerd who didn’t have to look that up. Why do you ask?

2 In places that observe a one-hour shift for summertime.

How I Learned to Enjoy Pickled Onion Monster Munch

Duration

Podcast Version

This post is also available as a podcast. Listen here, download for later, or subscribe wherever you consume podcasts.

Right in time for International Crisp Sandwich Day (St. Crispin’s Day) tomorrow, I’ve taught myself to enjoy Pickled Onion Monster Munch.

Three jars of homemade pickled eggs; one in each of a chilli-spiced vinegar, balsamic vinegar, and white vinegar.
You might reasonably have assumed I’d have already enjoyed pickled onion crisps. After all, I not only enjoy actual pickled onions but also the far more “acquired taste” of pickled eggs, shown.

There’s a need for somebody… anybody… to eat Pickled Onion Monster Munch in our household, because we have a bit of an oversupply. In order to reliably get both of the other flavours that people like (Roast Beef and Flamin’ Hot, respectively), we end up buying multipacks that also contain Pickled Onion flavour, and these unwanted extras pile up in the snack cupboard until we happen to have a houseguest that we can palm them off onto.

Snack cupboard next to a 12-pack of Monster Munch featuring three flavours: Roast Beef, Flamin' Hot, and Pickled Onion.
Yes, I’m aware that there are multipacks of individual flavours, but none of our local supermarkets seem to stock multipacks of Flamin’ Hot, which is objectively the best flavour of Monster Munch and anybody who claims otherwise is wrong.

My entire life, I’ve claimed not to like pickled onion flavour crisps. As a kid, I would only eat salt & vinegar and ready salted flavours, eventually expanding my palate into “meaty” flavours like chicken and roast beef (although never, absolutely never, prawn cocktail). Later, I’d come to also enjoy cheese & onion and variants thereof, and it’s from this that I realise that I’m probably being somewhat irrational.

Because if you think about it: if you want to make a “pickled onion” flavour crisp, what flavouring ingredients would you use? It turns out that most crisp manufacturers use a particular mixture of (a) the ingredient that makes salt & vinegar crisps taste “vinegary” and (b) the ingredient that makes cheese & onion crisps taste “onioney”. So in summary:

  1. I like pickled onions.
  2. I like salt & vinegar crisps, which include an ingredient to make them taste vinegary.
  3. I like cheese & onion crisps, which include an ingredient to make them taste onioney.
  4. Therefore, I ought to like pickled onion crisps, which use two ingredients I like to try to emulate a food I like.
A packet of Pickled Onion Monster Munch, held in a hand.
I should like this. Right?

Maybe that deliberate and conscious thought process is all I need? Maybe that’s it, and just having gone through the reasoning, I will now like pickled onion crisps!

Conveniently, I have a cupboard in my kitchen containing approximately one billion packets of Pickled Onion Monster Munch. So let’s try it out.

The first time I’ve tried a pickled onion flavour crisp in almost 30 years, captured on camera for your amusement.

It turns out they’re okay!

They’re not going to dethrone either of the other two flavours of Monster Munch that we routinely restock on, but at least now I’m in a position where I can do something about our oversupply.

And all it took was stopping to think rationally about it. If only everything were so simple.

× × ×

Nex in CapsulePress

I’ve added Nex support to CapsulePress!

What does that mean?

Screenshot showing DanQ.me homepage via Nex, in Lagrange browser.
Here’s how nex://danq.me/ looks in my favourite desktop Gemini/smolweb browser Lagrange.

Nex is a lightweight Internet protocol reminiscent to me of Spartan (which CapsulePress also supports), but even more lightweight. Without even affordances like host identification, MIME types, response codes, or the expectation that Gemtext might be supported by the client, it’s perhaps more like Gopher than it is like Gemini.

It comes from the ever-entertaining smolweb hub of Nightfall City, whose Web interface clearly states at the top of every page the command you could have run to see that content over the Nex protocol. Lagrange added support for Nex almost a year ago and it’s such a lightweight protocol that I was quickly able to adapt CapsulePress’s implementation of Spartan to support Nex, too.

require 'gserver'
require 'word_wrap'
require 'word_wrap/core_ext'

class NexServer < GServer
  def initialize
    super(
      (ENV['NEX_PORT'] ? ENV['NEX_PORT'].to_i                           : 1900),
      (ENV['NEX_HOST']                                                 || '0.0.0.0'),
      (ENV['NEX_MAX_CONNECTIONS'] ? ENV['NEX_MAX_CONNECTIONS'].to_i : 4)
    )
  end

  def handle(io, req)
    puts "Nex: handling"
    io.print "\r\n"
    req = '/' if req == ''
    if response = CapsulePress.handle(req, 'nex')
      io.print response[:body].wrap(79)
    else
      io.print "Document not found\r\n"
    end
  end

  def serve(io)
    puts "Nex: client connected"
    req = io.gets.strip
    handle(io, req)
  end
end
This is genuinely the entirety of my implementation of my Nex server, atop CapsulePress. And it’s mostly boilerplate.

Why, you might ask? Well, the reasons are the same as all the other standards supported by CapsulePress:

  1. The smolweb is awesome.
  2. Making WordPress into a CMS things it was never meant to do is sorta my jam.
  3. It was a quick win while I waited for the pharmacist to shoot me up with 5G microchips my ‘flu and Covid boosters.

If you want to add Nex onto your CapsulePress, just git pull the latest version, ensure TCP port 1900 isn’t firewalled, and don’t add USE_NEX=false to your environment. That’s all!

×