You can, of course, set a new one too, but the idea here (as with categories and tags) is that you can quickly find back an existing series and add the current post to it.
Also, as with tags, the expectation is that either a single series is being used, or if more than one series is in play for a post they'll be listed as a comma-separated list. The issue here is that while BlogMore supports this:
series:-Some series of posts-Some other series of posts-Yet another series of posts
the frontmatter-handling code in blogmore.el isn't very sophisticated at all; it doesn't actually handle it as actual YAML, instead just treating it as a set of key/value pairs separated by a colon.
At some point soon I want to give blogmore.el a revamp and base all of the frontmatter-handling code on something like yaml.el. I did do some experimenting last night to drop it in and handle proper lists. It worked well enough, but I abandoned the work as I realised I really wanted to start again from scratch and build blogmore.el from the bottom up using that package.
When I first added it it simply dumped all of the data available about posts within a blog, meaning it was possible to do all sorts of things with the data outside of BlogMore itself. Having done this, and used the result to good effect (and also having seen at least one person also make use of it), I got to thinking that I should probably expose some other data that's going to be helpful.
Given that blogmore.el needs to dive into things like available categories and tags, and given that I'd also like to add support there for the recently-added series support, I realised that dumping those values as JSON would also be helpful.
So this release extends the dump command, adding a set of sub-commands:
posts: dumps the data about all posts in the blog (this is the default if you just run blogmore dump, so keeping the command backward-compatible).
categories: dumps all categories as slug/title pairs.
tags: dumps all tags as slug/title pairs.
series: dumps all series as slug/title pairs.
For example, getting all categories from this blog:
[["agentic-afterthoughts","Agentic Afterthoughts"],["buying-the-steam-controller","Buying the Steam Controller"],["edinburgh-fringe-2023","Edinburgh Fringe 2023"],["reading-2bit-files-for-fun","Reading 2bit files (for fun)"],["swift-til","Swift TIL"],["the-great-github-copilot-meltdown-of-2026","The Great GitHub Copilot Meltdown of 2026"],["the-virgin-east-coast-saga","The Virgin East Coast Saga"],["emacs-d","~/.emacs.d"]]
While this data could have been gathered from the content of the dump of posts, this approach makes it far easier to work with and more accessible; simply put, it means there's less work for the user to do if they just want all the tags (for example). With this, and with a little bit of caching in the code (because this does require parsing all the posts every time), I think it will make for a better approach to category, tag and (when I add it) series completion while writing a post.
When I moved to Newcastle, as a student, back in 1986, I was introduced to many new things. So many new things. Different folk. Different accents. Different backgrounds. People from the south! But, as well as all the eye-opening things that student life had to throw at a working-class Yorkshire lad, there were also all the things that Tyneside had to offer too.
Without question, my absolute favourite discovery was the stottie. This became my go-to food, especially in my second and third years, when I was no longer in halls.
I left Newcastle in 1989 and never went back1, and sadly, have never had a stottie since. While I'm sure I could have found some niche place in the various places I've lived since, they're not a thing you find normally in Hampshire, Lincolnshire or Midlothian.
Meanwhile...
Earlier this week I was sat watching some TV and the cat was chilling on the sofa too. She's a ragdoll, a magnificent collection of floppy liquid floof. It occurred to me that she's not a cat that loafs, she stotties! Seriously, she sits there and just flows into a huge furry circle. I mentioned this to my partner, and then realised that I'd have to explain the concept, given that they're not familiar with the North East of England.
The ensuing conversation resulted in the idea that, to fix my wish to have a stottie again (after I'd done an Internet search for them around the Edinburgh area), I should just have a go at making them!
Which brings me to today. I attempted making a stottie and it actually wasn't a complete disaster.
While I've made plenty of bread in the past, I've never been too brilliant at it and, honestly, it's not something that really excites or interests me. For some reason though, making my own had never occurred to me. So, with some yeast, water, sugar and white pepper...
Plus some flour...
Which I threw together, along with some salt...
And then kneaded for about 10 minutes, then left to stand for an hour while I went for a walk.
I don't think it managed to rise quite as much as it should have, but it also didn't seem like enough of a disaster to stop there. Besides, the lack of faffing is sort of the trademark of a stottie, so I also decided this might be fine. I then gave it a bit more of a mix before cutting into two halves and getting it ready for the oven.
I think this was a step where I went a little wrong. I wanted to try and get the size and thickness I remember (and which you see in plenty of photos online), but I was somewhat hesitant when it came to flattening it out. I was concerned I'd made it too thin at this point anyway and it wouldn't rise much. I was wrong. Next time2 I think I'll flatten it a lot more.
Anyway, I threw both proto-stotties into the oven and about 20 minutes later I had something that was passable!
Neither was really quite the nicely-round shape I was hoping for, and both were quite a bit thicker than I would have liked too. But both were baked well, and looked and felt fine inside too, with the texture having the chewy density that I remember.
As for the taste: they were actually good! They made for good sarnie bread for a slightly late lunch, and also got finished off along with dinner.
Overall I would say that things didn't work out as well as I'd hoped, but for a first attempt they came out okay and tasted just fine. Now I know how I'd do things differently in the future, and it's also given me the confidence to have another go at some point.
As for the cat that inspired this, it's only fair I pay the cat tax.
This is the Internet after all.
I've travelled through plenty of times, but it's been 37 years, and counting, since I was last in toon. ↩
It's probably bad news if I have a Saturday afternoon and evening spare, a fully-charged laptop and a comfy sofa. It seems that when that happens, something like BlogMore v2.41.0 happens. This is a release where I've added two features that could be generally useful, but which I'm unlikely to use in my own blogs.
The first, which to be fair is one I might use (I've used it in documentation plenty of times over the years), is optional Mermaid support. This is off by default, so has no overhead if you don't turn it on. It is turned on by setting with_mermaid to true. Even with this enabled, the Mermaid third-party scripts only get included on pages that include a Mermaid diagram, reducing the overhead.
```mermaidgraph TD A[Start] --> B[Process] B --> C{Decision} C -->|Yes| D[Success] C -->|No| E[Fail]```
If Mermaid is enabled the resulting page will show this:
There are, of course, all sorts of diagrams that can be used and I'm not going to go into them here, or in the BlogMore docs; Mermaid is well known enough and well-documented enough that anyone turning this on is likely to know what they're doing, or where to go to find out what to do.
The second new feature, which I am almost certainly never going to need to use on my blog, is LaTeX-style maths support. As with Mermaid, this is off by default and has no overhead if not used. Even when turned on with the with_maths setting, the external scripts will only be pulled into pages that include maths markup.
To use either, when turned on, you use the usual $ or $$ convention for LaTeX-maths-in-Markdown:
You can make some fun images using:
$$
z_{n+1} = z_n^2 + c
$$
We can say $z_{n+1} = z_n^2 + c$ inline too.
The result of the above will be something like:
Note that some care has been taken to ensure that ordinary use of a $, in currency values for example, is left unaffected. This can't be guaranteed in every possible case, so keep this in mind when turning on with_maths. From what I have read this is a common issue when using such markup.
Both these features were fun to add, with me planning out the implementation with Antigravity, and having a back and forth a couple of times to address issues and get it all working "just so". I'm especially pleased with the fact that it's done in a way where there is no overhead, even when either feature is enabled, if a page isn't showing a diagram or maths markup.
A quick update carrying on from this morning's release: as mentioned towards the end of the post, there was a small problem with the lint command where it would raise an error if a page or post linked to any page related to the new series feature.
v2.40.1 fixes this. The linter now knows about the series feature and the URLs it creates.
It's hardly a novel feature, plenty of blog engines support this sort of thing; I felt it was high time I added it to BlogMore too. The idea is simple: while categories provide a method of having "sub-blogs" within a blog (they also provide their own feeds), and while tags let you group together posts that touch on related subjects, a series will let you stitch together a collection of posts as directly relating to each other.
Adding a post to a series is as simple as adding a series to the frontmatter of a post.
title:Five days with Copilotcategory:AItags:Python, AI, LLM, Copilot, GitHub, BlogMore, codingdate:2026-02-20 15:46:00 +0000series:Agentic Afterthoughts
With this done, when a reader is viewing an individual post that is within a series, some new navigation appears at the top and bottom of the post that lets them know about the series, and also offers them easy navigation to the previous and next posts.
Also, if the reader were to click on the series title, it will take them to an archive page for that series, where the posts are presented in the usual pagination format, but where they're also presented in series order. To be clear: series order is always chronological order.
To help encourage further post discovery, if one or more series are available, a new Series link appears at the top of the blog. This links to an index of every series available.
Sorted in alphabetical order, the list also shows how many posts are in each series and, if reading time is turned on, the total reading time will be shown.
Worth noting is the fact that a post doesn't have to be restricted to just one series. If you need a post to be in two or more series, you can provide the series as a list:
title:My post that crosses the streamscategory:Testingtags:BlogMore, Series, Testdate:2022-02-22 22:22:22 +2200series:-Experiments with blogging-Eating my own dog food-Testing thing
The post will then show navigation for every one of those series, and the post will be in each series' archive page.
Having added this, I've also updated the output of the dump command so that series (the series list as provided in the frontmatter), safe_series (the series list in their URL-friendly slug forms) and series_pair (a list of series title and slug pairs) properties are available.
As of the time of writing this, I have noticed one issue. The linter isn't currently aware of the URLs that are created as part of the series facility. So if you have a page or post that links to the index, or links to a particular series, there will be errors:
blogmore lint
Linting site in content...
ERROR: posts/2026/06/2026-06-06-blogmore-v2-40-0.md: Link points to non-existent internal path: /series/ (resolved to /series/)
ERROR: posts/2026/06/2026-06-06-blogmore-v2-40-0.md: Link points to non-existent internal path: /series/ (resolved to /series/)
ERROR: posts/2026/06/2026-06-06-blogmore-v2-40-0.md: Link points to non-existent internal path: /series/the-virgin-east-coast-saga/ (resolved to /series/the-virgin-east-coast-saga/)
Linting complete: 377 post(s), 4 page(s), 3 error(s), 0 warning(s) [0.45s].
This should be a straightforward fix which I'll make in a follow-up release.
BlogMorev2.39.0 has a couple of changes, one more or less cosmetic, the other a new feature that I probably should have added right near the start of the project.
First, the cosmetic: in pages and posts, when you use headings (#, ##, etc.), a ¶ is added to the end of each heading, along with some show-on-mouse-hover styling, to make it easy to grab the anchor of a particular section of a page1. A problem I'd noticed with this recently is that the ¶ shows up in the search text, and also in the content of all the feeds. While not a problem as such, it felt untidy.
So, with this release that particular ¶ character is stripped from the search index and from the feeds.
The second change is a facility that should be useful if you have legacy URLs that you really must have land on an actual page or post: redirection support.
This facility is provided by a new redirect_from frontmatter property. From now on, a page or a post can declare which URLs should be redirected to it. So, if you have a post that, given your current post location setup, would land at /2006/06/06/hello-world/, but in some other incarnation of your blog lived at /posts/2006-06-06-hello-world.html, you can now set this in the frontmatter:
redirect_from:/posts/2006-06-06-hello-world.html
and the old URL will be redirected to the new one. This is achieved by simply creating a very minimal HTML file at the old location, which contains a redirection. The content of the file will end up looking something like this:
<!DOCTYPE html><html><head><metacharset="utf-8"><title>Redirecting...</title><linkrel="canonical"href="https://example.com/2006/06/06/hello-world/"><metahttp-equiv="refresh"content="0; url=/2006/06/06/hello-world/"></head><body><p>Redirecting to <ahref="/2006/06/06/hello-world/">/2006/06/06/hello-world/</a>...</p></body></html>
If a blog has migrated between locations and/or generation tools over the years, and there are a number of different legacy URLs out there still pointing to a post you really want to keep readable to all, you can also redirect from multiple URLs:
While all of this would have been possible anyway, by creating the appropriate file, with the appropriate content, in the extras directory, this approach helps automate the process and also means that the redirection information lives with the page or post being redirected to.
BlogMore has been bumped to v2.38.0. This release includes a small cosmetic change to the stats page, and also adds a fairly big cosmetic feature with some comprehensive control.
First, the change to the stats page: here I've changed the formatting of numbers a little so that numbers that are in the thousands or higher get better formatting. So rather than a count of something being 1234 it'll now display as 1,234. Hardly a groundbreaking change, but something I'd omitted some time ago and yesterday evening it came to mind. This should make the stats page just a little easier on the eye.
The second change is a reasonably big one, with some extra configuration file and frontmatter additions.
BlogMore has long supported auto-generation of a table of contents in the body of a post by including a [TOC] shortcut. Generally I'm not a fan of using this approach, but I can see the utility. Yesterday evening I added a new approach to showing a table of contents that means you don't need to have the list of links within the post.
Starting with this version, if a page or post has one or more headings in it, a table of contents will appear in the "dead space" on the right-hand side of the page, like this:
This follows the same kind of style as is used for the year and month index in the archives page. However, whereas in the archives the index just disappears (by design) if you're on a smaller screen, this new table of contents will switch to being inline in the page or post, in a form that is collapsed:
If the user clicks on it, it expands:
Given that this is a fairly big cosmetic change that could affect many pages and posts on a blog, I've built in as much control as makes sense. This new ToC approach is on by default, but can be turned off. First off, there is a show_toc configuration file setting which controls if the feature should be on or off, by default, site-wide. It is set to true by default.
Because there might be times where you want to control this at the page or post level, there is also a show_toc frontmatter property too. This always overrides the global setting in the configuration file.
On top of this, I can imagine that someone1 might also want to have the right-side floating ToC, but never have the inline ToC showing on smaller displays. With this in mind I've also added a show_toc_inlineconfiguration option and frontmatter property. These just control if the inline version of the ToC will ever be shown. To be clear: if the ToC is disabled (either site-wide or via a specific page or post's frontmatter), this inline-specific setting is ignored -- the ToC will never show. But if show_toc is true then show_toc_inline controls if the inline ToC ever appears on smaller displays.
I fear I might have made it sound more complicated than it is. Apologies if that's the case. I'm confident that someone needing this level of control will make sense of it easily enough.
Also, just to be clear: the [TOC] shortcut is totally unaffected by any of this. If you have [TOC] in your post, that version of the table of contents will always be generated. I didn't think it made sense to override that explicit markup choice.
I've just released BlogMorev2.37.0. This is a small update that fixes a bug and also improves the way that warnings and errors are emitted.
The bugfix comes from yesterday's post where I noticed that the stats page was misreporting the number of tags on the blog. The cause of the problem was that, within reason, a single tag can be represented in a number of different ways. In the tags frontmatter you could write any of Python Coding, Python coding, python coding, Python-Coding, etc and they would all be seen as the tag python-coding. This gives some useful flexibility and also ensures that the actual tag is URL-safe.
The problem was that the stats page was counting the list of unique tags, as they were typed into posts, rather than the unique list of "made safe" tags. So that is now fixed, along with categories too.
The other main change in this release is that warnings and errors that might get printed during post parsing and other operations are now printed to stderr. Until now everything was simply printed to stdout, which was fine until I introduced the links
dump and main dumpcommands. With the addition of those commands, you're far more likely to want to redirect the output to a file. So if there's some sort of warning when parsing a post, that would get dropped into the middle of the JSON output (if using dump), resulting in a JSON file that can't be parsed.