26 posts tagged “site-upgrades”
2026
Last month I added a feature I call beats to this blog, pulling in some of my other content from external sources and including it on the homepage, search and various archive pages on the site.
On any given day these frequently outnumber my regular posts. They were looking a little bit thin and were lacking any form of explanation beyond a link, so I've added the ability to annotate them with a "note" which now shows up as part of their display.
Here's what that looks like for the content I published yesterday:

I've also updated the /atom/everything/ Atom feed to include any beats that I've attached notes to.
Writing about Agentic Engineering Patterns
I’ve started a new project to collect and document Agentic Engineering Patterns—coding practices and patterns to help get the best results out of this new era of coding agent development we find ourselves entering.
[... 554 words]Adding TILs, releases, museums, tools and research to my blog
I’ve been wanting to add indications of my various other online activities to my blog for a while now. I just turned on a new feature I’m calling “beats” (after story beats, naming this was hard!) which adds five new types of content to my site, all corresponding to activity elsewhere.
[... 614 words]I've long been resistant to the idea of accepting sponsorship for my blog. I value my credibility as an independent voice, and I don't want to risk compromising that reputation.
Then I learned about Troy Hunt's approach to sponsorship, which he first wrote about in 2016. Troy runs with a simple text row in the page banner - no JavaScript, no cookies, unobtrusive while providing value to the sponsor. I can live with that!
Accepting sponsorship in this way helps me maintain my independence while offsetting the opportunity cost of not taking a full-time job.
To start with I'm selling sponsorship by the week. Sponsors get that unobtrusive banner across my blog and also their sponsored message at the top of my newsletter.

I will not write content in exchange for sponsorship. I hope the sponsors I work with understand that my credibility as an independent voice is a key reason I have an audience, and compromising that trust would be bad for everyone.
Freeman & Forrest helped me set up and sell my first slots. Thanks also to Theo Browne for helping me think through my approach.
2025
How I automate my Substack newsletter with content from my blog
I sent out my weekly-ish Substack newsletter this morning and took the opportunity to record a YouTube video demonstrating my process and describing the different components that make it work. There’s a lot of digital duct tape involved, taking the content from Django+Heroku+PostgreSQL to GitHub Actions to SQLite+Datasette+Fly.io to JavaScript+Observable and finally to Substack.
[... 1,345 words]A few months ago I added a tool to my blog for bulk-applying tags to old content. It works as an extension to my existing search interface, letting me run searches and then quickly apply a tag to relevant results.
Since adding this I've been much more aggressive in categorizing my older content, including adding new tags when I spot an interesting trend that warrants its own page.
Today I added system-prompts and applied it to 41 existing posts that talk about system prompts for LLM systems, including a bunch that directly quote system prompts that have been deliberately published or leaked.
Other tags I've added recently include press-quotes for times I've been quoted in the press, agent-definitions for my ongoing collection of different ways people define "agents" and paper-review for posts where I review an academic paper.
I've added a Disclosures section to my about page, listing my various sources of income and the companies that directly sponsor my work or have supported it in the recent past.
I do not receive any compensation writing about specific topics on this blog - no sponsored content! I plan to continue this policy. If I ever change this I will disclose that both here and in the post itself. [...]
I see my credibility as one of my most valuable assets, so it's important to be transparent about how financial interests may influence my writing here.
I took inspiration from Molly White's disclosures page.
Subscribe to my sponsors-only monthly newsletter
I’ve never liked the idea of charging for my content. I get enormous value from putting all of my writing and research out there for free.
So I’m trying something a little different: pay me to send you less.
I’m starting a sponsors-only monthly newsletter featuring just my heavily curated and edited highlights. If you only have ten minutes, what are the most important things not to miss from the last month?
Don’t want to pay? That’s fine, you can continue to follow my firehose for free!
Anyone who sponsors me for $10/month (or $50/month or more) on GitHub sponsors will receive my new newsletter on approximately the last day of the month. I’ll be sending out the first edition next week.
This blog and my newsletter will continue at their same breakneck pace. Paying subscribers can get a lower volume of stuff.
I'm cautiously optimistic that this could work. I've never liked the idea of business models that incentivize me to publish less. This feels like it encourages me to do what I'm doing already while giving people a rational reason to support my work, at a relatively small incremental cost to myself.
Fun fact: there's no rule that says you can't create a new blog today and backfill (and backdate) it with your writing from other platforms or sources, even going back many years.
I'd love to see more people do this!
(Inspired by this tweet by John F. Wu introducing his new blog. I did this myself when I relaunched this blog back in 2017.)
I've added a new content type to my blog: notes. These join my existing types: entries, bookmarks and quotations.
A note is a little bit like a bookmark without a link. They're for short form writing - thoughts or images that don't warrant a full entry with a title. The kind of things I used to post to Twitter, but that don't feel right to cross-post to multiple social networks (Mastodon and Bluesky, for example.)
I was partly inspired by Molly White's short thoughts, notes, links, and musings.
I've been thinking about this for a while, but the amount of work involved in modifying all of the parts of my site that handle the three different content types was daunting. Then this evening I tried running my blog's source code (using files-to-prompt and LLM) through the new Gemini 2.5 Pro:
files-to-prompt . -e py -c | \
llm -m gemini-2.5-pro-exp-03-25 -s \
'I want to add a new type of content called a Note,
similar to quotation and bookmark and entry but it
only has a markdown text body. Output all of the
code I need to add for that feature and tell me
which files to add the code to.'Gemini gave me a detailed 13 step plan covering all of the tedious changes I'd been avoiding having to figure out!
The code is in this PR, which touched 18 different files. The whole project took around 45 minutes start to finish.
(I used Claude to brainstorm names for the feature - I had it come up with possible nouns and then "rank those by least pretentious to most pretentious", and "notes" came out on top.)
This is now far too long for a note and should really be upgraded to an entry, but I need to post a first note to make sure everything is working as it should.
2024
OpenAI DevDay 2024 live blog
I’m at OpenAI DevDay in San Francisco, and I’m trying something new: a live blog, where this entry will be updated with new notes during the event.
[... 68 words]New blog feature: Support for markdown in quotations. Another incremental improvement to my blog. I've been collecting quotations here since 2006 - I now render them using Markdown (previously they were just plain text). Here's one example. The full set of 920 (and counting) quotations can be explored using this search filter.
Tags with descriptions. Tiny new feature on my blog: I can now add optional descriptions to my tag pages, for example on datasette and sqlite-utils and prompt-injection.
I built this feature on a live call this morning as an unplanned demonstration of GitHub's new Copilot Workspace feature, where you can run a prompt against a repository and have it plan, implement and file a pull request implementing a change to the code.
My prompt was:
Add a feature that lets me add a description to my tag pages, stored in the database table for tags and visible on the /tags/x/ page at the top
It wasn't as compelling a demo as I expected: Copilot Workspace currently has to stream an entire copy of each file it modifies, which can take a long time if your codebase includes several large files that need to be changed.
It did create a working implementation on its first try, though I had given it an extra tip not to forget the database migration. I ended up making a bunch of changes myself before I shipped it, listed in the pull request.
I've been using Copilot Workspace quite a bit recently as a code explanation tool - I'll prompt it to e.g. "add architecture documentation to the README" on a random repository not owned by me, then read its initial plan to see what it's figured out without going all the way through to the implementation and PR phases. Example in this tweet where I figured out the rough design of the Jina AI Reader API for this post.
A homepage redesign for my blog’s 22nd birthday
This blog is 22 years old today! I wrote up a whole bunch of higlights for the 20th birthday a couple of years ago. Today I’m celebrating with something a bit smaller: I finally redesigned the homepage.
[... 314 words]Blogmarks that use markdown. I needed to attach a correction to an older blogmark (my 20-year old name for short-form links with commentary on my blog) today - but the commentary field has always been text, not HTML, so I didn't have a way to add the necessary link.
This motivated me to finally add optional Markdown support for blogmarks to my blog's custom Django CMS. I then went through and added inline code markup to a bunch of different older posts, and built this Django SQL Dashboard to keep track of which posts I had updated.
2023
Semi-automating a Substack newsletter with an Observable notebook
I recently started sending out a weekly-ish email newsletter consisting of content from my blog. I’ve mostly automated that, using an Observable Notebook to generate the HTML. Here’s how that system works.
[... 2,520 words]2017
Getting the blog back together
Getting this blog up and running again has turned out to be one of those side-projects that keeps threatening to fall down a rabbit hole.
[... 160 words]2004
1000th Blogmark
I just posted my 1000th blogmark. I can’t emphasize enough how much of an impact this 15 minute hack has had on both my browsing and my blogging habits. While I still tend to leave browser windows open for days at a time, I now at least have a procedure for getting rid of the ones that still interest me. More importantly, having blogmarks has eliminated the temptation to write a full blog entry (with quotation) just to share a link. This has dramatically reduced my posting rate, but has meant that when I do post an entry I usually have something moderately interesting to say.
[... 181 words]2003
More blogmark tweaks
I’m up to 110 blogmarks now, and from my point of view they’re the single most useful feature I’ve added to this site in a long time. I’ve modified my day archive pages to show the blogmarks added on that day, and I’m considering adding them to individual entry pages as well so that an entry is displayed along with the blogmarks added while that entry was at the top of my blog. The idea there is that I could aim to blogmark “related items” for the top entry, although obviously unrelated sites would end up in there as well.
[... 204 words]Blogmarks
This entry was going to be another list of links, together with a note about how much I really needed to set up a separate link blog. Then I realised that it would make more sense just to set one up so that’s exactly what I’ve done. I still need to implement the archive but it’s getting dark so I’m posting this and heading home.
[... 211 words]New anti-comment-spam measure
I’ve added a new anti-comment-spam measure to this site. The majority of comment spam exists for one reason and one reason only to increase the Google PageRank of the site linked from the spam and specifically to increase its ranking for the term used in the link. This is why so many comment spams include links like this: Cheap Viagra.
[... 268 words]Signing comments on blogs
Adrian Holovaty has implemented reserved comment names in his blog, a feature that prevents anyone apart from him from using the names “Adrian”, “Adrian H.” or “Adrian Holovaty” when posting a comment. François Nonnenmacher suggests extending the idea to allow people to “confirm” their authorship of comments on any blog using a TrackBack sent to their site that in turn causes them to be sent an alert email, which they can then use to confirm their comment. I like his idea of authentication based on URLs (email addresses are no good; they should not be publically displayed for fear of spam harvesters) but I think I’ve come up with an alternative authentication scheme that removes the need for the user to manually confirm authorship. This is pretty complicated, so bare with me.
[... 762 words]Small design tweak, big difference
I’ve changed from using the day as the principle heading on the front page to using the title of each post instead. This is quite a minor alteration, but I expect it to have a relatively large impact on my blogging habits. For the past year I have treated my blog as a daily endeavour, thanks almost entirely to the way the site was layed out. This was intentional; when I orginally launched blog I made the decision to keep each entry as part of an ongoing narrative, with no individual entry titles and permalinks to entries in the context of the day they were posted.
[... 270 words]Category specific RSS feeds
I frequently check the Python Programmer Weblogs page for an addition to my daily blogging fix. It’s a simple but very effective idea: Subscribe an aggregator to a bunch of feeds about a similar topic and publish the results for all to see. I’m one of the more prolific bloggers of the ones listed there, and since I tend to post a whole bunch of entries in a relatively narrow timeframe my stuff often appears in a big lump on the front page of the site. I’ve been feeling slightly guilty about this, as most of my posts have nothing to do with Python at all. So I’ve finally got my act together and knocked out RSS feeds for individual blog categories.
[... 150 words]2002
Pingback implemented
I’ve implemented PingBack on my blog. PingBack is a system for tracking who is linking to your blog in a controlled way, based on a post by Stuart a few months ago. The idea is that when you link to a PingBack enabled blog you (or your blogging tool) should send an XML-RPC “ping” to that blog’s PingBack server telling it where you have linked to and where you linked from. The PingBack server can then grab your page, check that the link is there and extract a title and short description from the blog. The system is an alternative to (and was inspired by) MoveableType’s TrackBack feature. Stuart and I are actively developing the idea and will be releasing code and documentation to help other people experiment with the system in the near future.
Fixed validation again
The road to validity is frought with peril. I’ve just fixed another small group of errors that were preventing this page from validating (after spotting the ominous W3C validator in today’s user-agent logs). This time is was a couple of forgotten </p> tags and an unescaped ampersand.
[... 242 words]




