From Wordpress to Static Site Generator



This blog has been online for 20 years, and I've tried to spend a lot more time writing content than fiddling with the toolchain or theme for it, because too many blogs never see the light of day because the theme is somehow never ready. It started life on Textpattern, spent a few years on Serendipity, and ended up in 2011 migrated to Wordpress. I've been meaning to do something else with it for quite a few years, after all I've rescued a LOT of abandoned websites in my time (it was my literal job for a while), and I'm a HUGE docs-as-code fan. But with around 1100 posts and 400 or so additional resources, never mind a few other pages, it seemed like a big job with small returns. Then came wp2shell, my trusty LAMP stack on a Digital Ocean droplet was compromised, and I realised I could either rebuild that setup afresh - or build something else.

The other big difference between doing this migration project in 2026 rather than for example 2021 is that AI assistants are here and they actually assist. I am mostly using Claude and it was a big help. I'm sometimes quite AI-sceptic but this sort of task is a perfect use case for an AI assistant because:
  • I already have the skills for this, so I've a reasonable handle on what a good process looks like and I can probably unstick problems as they happen
  • It's all pretty mainstream; Wordpress is huge and has a lot of supporting internet information in its training data, static site generators are not rocket science, Pelican has good docs, and the rest is just Python/HTML/CSS
  • The whole thing is very, very repetitive due to the size of the content
  • The stakes are low. I'm not sure every post on this blog was even loaded in the last 5 years, if something comes out of the process not quite right, nobody dies. (In actual fact I'm pretty sure that Claude also fixed quite a few things that were broken in the 2008 or 2011 migrations!)

The starting point was: I want a static site, I really dislike GitHub Pages although I'm prepared to have the repo on GitHub, and I've got a backup from before the exploits (thank you Jetpack/VaultPress). One thing that put me off doing this in the past was not having a good solution for comments, which have been such an incredible part of the blogging journey. I'm still heartbroken about not having them, but we live in a post-commenting world and so the site is purely my own content now. I would like to do more in the ActivityPub space and foster more conversations on other platforms in the future.

Pelican the Static Site Generator

Pelican is a stable, reasonably featureful static site generator written in Python. I feel like I should love Hugo but somehow, I never quite do - and I write a LOT more Python than Go these days so just in terms of muscle memory, a Python stack makes sense. Also this setup means I can write blog content in ReStructuredText and put it in source control - which makes me unreasonably happy.

Pelican has functionality to import from a Wordpress export so I used that as a starting point. I also had a full backup of my Wordpress site that was dipped into by both me and Claude to rescue quite a lot of different content, links, photos, lost formatting and all sorts. Big shout out to my patient husband Kevin who sorted out which photo was being referred to in which blog post in all of 2009! Predictably, some of the content was broken from the export (did I mention there was a lot of content?) so I just threw Pelican's attempt at content into a folder for safekeeping and picked out a few articles at a time to add into the site.

Pelican also has themes so I picked the graymill theme and by removing the sidebar and tweaking the colours, the site started to take shape. I based the new site pretty closely on the old site, with a few blog posts plus some other resources on the main homepage. This is where Claude really came into its own with me just prompting to remove display fields, support multiple content types, reformat all the content to use excerpts, change the fonts, build a top navigation bar .... and it more or less happening by magic. In theory I've been a web developer but I'm a server-side specialist for a reason and this came together much more quickly than I had imagined it could.

Content Migration

This part was not as much of a problem as I imagined, especially once I decided that nobody would miss a few broken things!! With Claude to keep track of progress and do all the reformatting, I just spent a couple of hours answering questions about what was fixable or not, or figuring out how something should be fixed. I got 1000 posts across in the first attempt. The others mostly made it in later instalments, with a mix of syntax errors from either the previous platforms or the importer tool, and quite a lot of broken links and missing images - most of which had been broken for 15 years!

I also have a lot of content related to things I've done elsewhere. I write for other outlets and in the past gave quite a lot of conference talks, so there are videos and various digital content types all over the place. One fun fact about this section on the previous site is that it used a plugin which pre-dated custom post types in Wordpress.... yes, this Wordpress setup was OLD!! This secondary content type was much more difficult because I had used so many different plugins and shortcodes and who knows what else over the years. The slides were split between noti.st, SpeakerDeck, and Slideshare and some of the embeds were completely lost in migration and had to be reconstructed.

All in all, it was this part where Claude really shone - my grep/sed/awk game is pretty good and as a vim user, the macro is my friend, but there was just such a lot of stuff! This is a classic case of something that probably would never have happened at all if I hadn't had assistance of one form or another. I'm also not very [insert word meaning houseproud but for blogs] about my website - it's mine, it's not perfect, but there are things here and if they're useful to you as well as me then I'm happy.

Hosted on Cloudflare Pages

My DNS has been resolving at Cloudflare for years, I was always determined that if I was ever on the front page of Hacker News then my website was NOT going down (it didn't happen, but never say that I was not prepared!). I liked the bits of their platform I'd already used, a little bit of workers, some D1, the caching for the old website. So I looked up their Cloudflare Pages platform and it was very easy to set up and seems to work well. Again, not much more to say but I'm quietly impressed! I also turned on the analytics which are short-retention and fairly minimal but have been perfect for looking at what is still returning 404 and fixing it!

Reflections on the New Normal

I resisted the urge to go back to a pink website with pink writing (Wayback Machine can vouch that this was my online presence a few iterations ago), and if you aren't paying a lot of attention or don't visit frequently, I think the main difference you'll notice on the new site is the loading time. It is FAST in comparison to the rather underpowered droplet if you hit page that wasn't cached. The content is all where it should be and I intend to keep adding to it.

Some things are very changed. My blogging workflow: vim and git rather than the Wordpress textarea (that new compose whatsit probably isn't new at all now but with some accessibility needs, I always used the classic editor). I also lost a lot of functionality in terms of plugins, scheduling, better post images and whatever else. I'm not sure how much that matters now, the atom and RSS feeds are still doing their thing and things don't seem to move so quickly that post timing really matters - it's mostly scraped and then served from there rather than here, anyway.

There are some other gaps here around the social cards, microformats, ActivityPub, and that sort of thing. Wordpress was doing some of that for me and I want to learn more about that and find out what I can do here.

The big loss is the comments. I might publish the ones that were already here - there was a period from about 2008 to 2013 where the comments were much more valuable than the blog content, as I started to really find my voice and gain real expertise to a point where kind friends didn't need to pop in and explain the rest of the post that I'd missed out. I miss those days, and those people, so much.

Finally, I'm glad my hand was forced into this upgrade. It made me evaluate my website and decide that my own content was important to me, and worth keeping. Having it as a static site makes a lot of sense now I write infrequently but the site is still fairly well-used - the long tail of traffic to different posts is really, really long! Writing should be easier in vim and pushing to git, because everything else in my life works that way and for a keyboard-only user, that's a very friendly user interface. In one way, the change was long overdue, but I choose to think that it came at the right time.


In: tech
Tags: #tech #wordpress #pelican #blog #ai