I'm sitting in the airport. Time enough for some fun scripting.
Currently, to create a new blog post, I mkdir public/blog/2025/01/11
.
Then, create index.html
.
Then copy the prior day's index.html
to the new file.
Then update the dates.
Then add an entry to public/blog/index.html
to list the new post.
That's fine and all. I want things as simple as possible to keep daily uploads sustainable.
One feature I'm interested in is "Next" and "Previous" links. But that adds a lot of steps.
How can I add that feature without requiring more daily work?
I can do a tiny bit of JavaScript that inspects the current date from the URL and links to the previous and next. But how would that JS know that there is no "Next" if it occurred today? Sometimes I publish my post at like 11PM ET, sometimes earlier. I could build in generous delay... The "Next" is omitted unless the browser's current day is over 24 hours ahead of the current page's URL. That would supply the behavior for most posts most of the time. And it would omit the behavior when things are recent and ambiguous. Of course, if I ever miss a day, then it will be broken.
The JavaScript could send a request to check the presence of the next day's post...
That will be more up-to-date at the cost of an extra HEAD
request per page load,
a fallback to nothing in the absence of network-enabled JavaScript on the user agent,
and just generally being gross.
It also will be unable to deal with the case of me missing a day.
No, we want a static solution.
So, I'm tempted to write a script for this that I run at blog-post-creation-time. If I go through the trouble of doing that, then I should at least script a few related things too.
Requirements:
index.html
file.blog/index.html
accordingly.The implementation is complicated by a few things:
public/
directly, for fun.
No separate "build step" from a source directory to a build directory.
This means the script must create and modify files in-place.
We want to avoid creating a full-fledged general-purpose parser or handrolling our own template language. So we'll use a simple set of strings that can be easily find/replaced.
A normal post will have:
<a href="/blog/2025/01/09">Previous</a> <a href="/blog/2025/01/11">Next</a>
The first post will only have the "Next" case. The most recent post will only have the "Previous" case.
We'll hardcode the first post so that it isn't a concern. We just need a simple string to find the previous case and update it. I propose:
<s>Next</s>
One benefit of this method, though a bit ugly,
is to retain a design characteristic I like about this site so far:
structural links are _always_ in the same place.
The use could click "Next" from the beginning of the blog to the end without moving their mouse.
Same for previous in reverse.
The space consumed by "Blah" is the same as "Blah".
Another benefit of this method is that we can do a global find replace over all the files in public/blog
.
We don't have to try to calculate the last post based on dates or anything like that.
Aside: We'll add an assert to confirm that there is only ever 1 instance of that string anywhere,
i.e. that I didn't toss it into anywhere like my demonstration of "Blah" above.
Now, when I run this script, I will likely either input the year, month, and day, or have that picked up from the environment. So the value to put in to replace the previous post's struck-through "Next" is today's date as given or observed. What value do I put into today's "Previous" link?
I can't assume that I've posted daily. (Though that is my goal!)
The best bet is probably to determine which file the struck-through "Next" was found in, and use that file's location to construct the link.
So, we arrive at the following algorithm (after a one-time manual setup phase):
A very interesting thing I'm noticing now that I've done the one-time manual setup of the initial links is that Google Chrome (on MacOS) is somehow debouncing the clicks of "Next" such that if you click too fast, then it won't actually click. You have to pause briefly between each click in order to continue following the links. Safari does not do this. It lets you pound "Next" from beginning to end as fast as you want. The Google Chrome behavior raises some intersting concerns about the "structural link locations always the same" design pattern I hinted at above: Maybe you should move structural links around, in order to force the user to move the mouse to them, in order to prevent the user from thinking that your dumb links don't work when they click them! Chrome puts the onus on the developer to help the user not feel confused or blame the developer for the misbehavior! Obviously, Chrome is debouncing like this to prevent accidental double-click situations by the elderly or otherwise dexterity-challenged. I would argue this may be more the duty of the operating system than of the browser...
With the algorithm determined, what language do I want to implement this script in?
Any language will do. Nothing tricky is required. I'll go with Rust, since I've enjoyed learning that recently.
Aaaaand that concludes my idle airport time for the day. More on the Rust implementation tomorrow!