My current work laptop has a Touch Bar, and I think I will miss it a little when I get my next laptop that doesn’t have one. Having the ability to adjust the brightness and volume using a slider is much nicer than frantically pressing buttons. Oh, and also the ability to replace buttons without being stuck with the predefined glyphs. I replaced the Siri button with the Lock Screen button, which I use all the time, and it’s nice being able to see the proper Lock Screen glyph for it.

That said, those are probably the only nice things about it, and I would probably think otherwise if I wasn’t using an external keyboard with function keys. I’m certainly not using the Touch Bar for anything else, even while using the laptop keyboard.

Keep forgetting that making a permalink to a highlighted bit of text on a web-page is a thing. Made such a link in Vivaldi by highlighting the text and selecting “Copy Link to Highlight” from the context menu. Worked like a charm.

Working on Jira ticket number CLC-1836. The numerical congruity has not gone unappreciated.

New path day. This was little more than a goats track last time I was around here, but was recently widened to something a little more “official.”

A narrow dirt path winds through a lush green patch of tall trees on either side.

Tools And Libraries I Use For Building Web-Apps In Go

I think I’ve settled on a goto set of tools and libraries for building web-apps in Go. It used to be that I would turn to Buffalo for these sorts of projects, which is sort of a “Ruby on Rails but for Go” type of web framework. But I get the sense that Buffalo is no longer being maintained. And although it was easy to get a project up and running, it was a little difficult to go beyond the CRUD-like layouts that it would generate (or it didn’t motivate me enough to do so). Plus, all that JavaScript bundling… ugh!

Huge pain to upgrade any of that.Since I’ve moved away from Buffalo, I’m now left to do more of the work up-front, but I think it helps me to be a little more deliberate in how I build something. And after getting burned with Buffalo shutting down, I think it’s was time to consider a mix of tools and libraries that would give me the greatest level of code stability while still being relatively quick to get something up and running.

So, here’s my goto list of tools and libraries for building web-apps in Go.

  • HTTP Routing: For this, I use Fiber. I suppose using Go’s builtin HTTP router is probably the best approach, but I do like the utility Fiber gives for doing a lot of the things that go beyond what the standard library provides, such as session management and template rendering. Speaking of…
  • Server Side Templating: Nothing fancy here. I just use Go’s template engine via Fiber’s Render integration. It has pretty much all I need, so I don’t really look at anything else.
  • Database: If I need one, then I’ll first take a look at Sqlite. I use the modernc.org Sqlite driver, as it doesn’t require CGo, making deployments easier (more on that later). If I need something a bit larger, I tend to go with PostgreSQL using the pgx driver. I would also like to use StormDB if I could, but it doesn’t play well with how I like to deploy things, so I tend to avoid that nowadays.
  • Database ORM: I don’t really use an ORM (too much PTSD from using the various Java ORMs), but I do use sqlc to generate the Go code that interacts with the database. It’s not perfect, and it does require some glue code which is tedious to write. But what it does it does really well, and it’s better than writing all that SQL marshalling code from scratch.
  • Database Migration: I’ve tried using golang-migrate before, and we do use it at work for PostgreSQL databases, but it doesn’t work well with the modernc.org Sqlite driver. So I ended up writing my own. But if it makes sense to use golang-migrate, I will.
  • JavaScript: I try to keep my JavaScript usage to a minimum, favouring vanilla JavaScript if I only need a few things. For anything else, I usually turn to Stimulus.js, which adds just enough “magic” for the slightly more involved pieces of front-end logic. I’m also looking at HTMX, and have tried it for a few things, but I’ve yet to use it for a complete project. I use esbuild if I need to bundle my JavaScript, but I’m trying to go “builderless” for most things nowadays, relying on import maps and just serving the JavaScript as is.
  • CSS: Much like JavaScript, I still prefer to use vanilla CSS served directly for most things. I tend to start new projects by importing SimpleCSS by Kev Quirk. It makes the HTML look good right out of the gate, but it does make each project look a little “samey” but that’s up to me to address.
  • Live Reloading: I’ve only recently been a convert to live reloading. I did use it when I was bundling JavaScript, but since moving away from that, plus doing most things server-side anyway, I needed something that would build the entire app. I’ve started using Air for this, and it’s… fine. There are certain things that I don’t like about it — particularly that it tends to favour configuration over convention — but it does the job.
  • Deployment: Finally, when I’m ready to deploy something, I do so using Dokku running on a Linux server. I bundle the app in a Docker container, mainly using a Go builder image, and a scratch image for the run-time container (this scratch container has nothing else in it, not even libc, which is why I use the modernc.org Sqlite driver). All I need to do is run git push, and Dokku does the rest. Dokku also makes it easy to provision PostgreSQL databases with automated backups, and HTTPS certificates using Lets Encrypt. Deploying something new does involve logging into the remote server to run some commands, but having been burned by PaaS providers that are either too pricy, or not pricy enough to stay in business, I’ve found this setup to be the most stable way to host apps.

So, that’s my setup. It’s a collection that’s geared towards keeping the code low maintenance, even if it may come at the cost of scalability. I can’t tell you anything about that myself: I’m not running anything that has more than a couple of users anyway, and most things I’m running are only being used by myself. But I think that’s a problem for later, should it ever arise.

I may never have a site as popular as those I read. I may never be in a situation where I can just rattle off a domain as if it was a business card. But it’s nice to have the option to do so. And, for me at least, it’s probably the best answer I can give when asked by someone “where is the best place to find you online," in lieu of giving out some social media handle. And I think, on the whole, that’s a good thing.

I don’t have a blog post today. The well’s been pretty dry all week if I’m honest. Usually at times like these, I hold off posting until the evening, hoping that something worth writing about will come by before the day’s end. We’ll see if that happens today. But if not… well, there’s this. 🤷

📺 Office Space (1999)

Title: Office Space Metadata: 1999 - Mike Judge Score: Good Review: Definitely worthy of it's cult following. Plus now I get all the movie references.

It’s a shame XML namespaces are not as widely used as they probably should be. I still see XML documents that escape nested XML documents as if they were strings, something XML namespaces were meant to be a solution for.

There’s code spelunking, which can be rather interesting. Where you explore the depths of code and decisions past made and wonder at why it is and how it all works.

Then there’s Jira spelunking, where you’re just fighting with your rock pick.

Reading about all the annoying permission notifications in MacOS Sequoias, I wonder how Apple devs actually experience this. Would they be using tools that would require them to record their screen as part of their job? And if so, are they experiencing any of these monthly notifications?

Might be that they’re using all in-house software for anything that would do this. I hear Apple’s pretty famous for doing so — going as so far as making an iOS app to order from Cafe Macs. And since Apple trusts software from Apple, it might be that they aren’t seeing these notifications nearly as often as their customers, who can’t run such privileged software themselves1.

I guess this is a roundabout way of say that maybe employees from Apple, up and down the org chart, need to run more third-party software on their work machines. That way they can get the full “experience” of using software stuck with throwing up a notification every month to do it’s job.

In any case, I think I’ll hold out on upgrading to MacOS Sequoias for the foreseeable future.


  1. It’s either that, or they are seeing these notifications and are told to just deal with it, which is probably worse. ↩︎

I made a different version of this image earlier today. Glad I found the discipline to do what needed to be done, giving me the opportunity to change it to this:

Auto-generated description: A mock-up of a reminder for a tax return due on 24 September 2024, with options to Mark Complete or Snooze, with a mouse cursor hovering over the Mark Complete option, giving the sense that the user will click it.

Made an update to one of my projects today that’s been going on for 11 years, way back when I was still learning Go. Might be one of the oldest projects I’m still maintaining. Lots of Java-isms in there.

This week’s earworms, two tracks by Lee Rosevere: Should I Run, and Midnight Runner. 🎵

Album cover for Should I Run, by Lee Rosevere. It depicts a person holding a guitar is standing on a reflective surface with a colourful, abstract background. Album cover for Midnight Runner, by Lee Rosevere.  It depicts a retro-style video game cartridge, similar to that used for Atari 7600 games, which features the title 'Synthergy' with artwork depicting a futuristic cityscape and a large planet in the background.

🧑‍💻 New post on TIL Computer: HTMX And POST Redirects

Just one of those days when I’m reminded that no matter how you think your users will use your system, there’s always someone that’ll push it to the breaking point. It’s also one of those days where I learnt that you can be a member of up to 113 groups in Active Directory.

Ok, this is strange. My work MacBook screen occasionally freezes when I interact with windows. It can’t be the screen as the mouse cursor moves just fine. But when I type or scroll inside a window, it just stops refreshing for a few seconds. Interestingly, the second display doesn’t have this issue.

Clip sharing is now available in Pocketcasts for Android! I was looking forward to this feature since I heard it was coming (this was why I was poking around About screens). Here’s my inaugural clip: a segment of Sharp Tech that I absolutely agree with. 🎙️

Weekly Update - 22 Sept 2024

No preface today. Let’s move on to the update.

Cyber Burger

Cyber Burger now has sound!

I started added some basic sound effects to the laser and the items flying across the screen.  They may change, depending on how I find them after a while, but it’s a start. I do like how Pico-8 makes these easy to make: select a waveform, then just draw out the pitch and volume graphically:

The laser fire sound effect, shown in the Pico-8 sound editor.

I also improved how items are spawned. Instead of the item types being completely random, they’re now taken from a list, which gets refilled and shuffled once it’s empty. This smoothes out the chance of seeing a particular item — no more waiting around for a bun bottoms to start your burger — while still making things random enough to be fun. The item types are distributed evenly, so every type will show up once per cycle. Maybe I’ll change this, but probably not, as it seems to be working reasonably well at the moment.

The Y location is now quantised a little so that items don’t completely overlap each other by a pixel or two. They can still be located on exactly the same Y position which… is not great — I may need to take a look at that. But the slice spacing between each item looks good. Also, items now spawn in from the left as well as the right.

Lastly, I changed how demerits work. The previous version was not adding any when the player made a mistake. This made them pretty useless, and the game felt quite easy. So now, whenever the player catches an item in the basket that they weren’t suppose to, they get a demerit. If their burger gets too large, then get 2 demerits. To balance things out, the player now has 6 demerit points instead of 3, and every completed burger would remove one demerit until the player has zero again. I think this will require some more rebalancing, but it makes play a little more interesting.

Not sure what I’ll work on next. I’ll need to finish (or redo) the sounds, and then come up with some more tasks to do. I’m thinking either working on the difficulty curve, making things harder as the game progresses; adding power-ups and power-downs; or working on the start screen and menu. More on either of these in the future.

Blogging Tool

For my “extracurricular” activity this week, I spend some more time on Blogging Tool. I added the notion of jobs, which are essentially background tasks for long running processes. These can be monitored from within the Jobs section, which is accessible from the main nav:

The new Jobs section, showing a job in progress.
Once completed, jobs can link to any resource — file or gallery — that they produced.

I’m recording jobs in the Sqlite3 database, including the ones that are currently running. Jobs have the ability to report progress by updating the “summary” message, which would update the job record in the database. I’m generally not too keen on having the database act as storage for something that could be updated quite frequently, but the alternative was keeping this progress information in memory or deploying something like Redis, both I felt were worse. Besides, I’m curious as to how well Sqlite3 handles status updates from a running job like this. I’m not expecting jobs to be updating there status too rapidly anyway, so it should be fine.

The Image App now with the Load URL and Send To Blog options.

The Image App got a few changes as well. It’s now possible to import an image from a URL (this is done within the browser so is subject to all the cross-origin rules that entails). I added this just so that I can touch up my own images that I already uploaded to Micro.blog, without having to download the image first. Speaking of, there’s now an option to send a processed image to a blog directly from the app, saving yet another download step. I’ve got this configured to Micro.blog but it uses Micropub to do this so it could, in theory, be any blogging system that supports that API.

The New Upload Zip app.
Complete with upload progress bar for slow upload connections (like mine).

The last thing that was added is the ability to upload a Zip file of images to a Micropub endpoint, and start creating a gallery. This has been a feature that I wanted for a while. It always took me ages to prepare a photo gallery in Micro.blog. I know there are apps which help here, but they’re for iOS and just don’t fit my workflow. Now, whenever I want to add a photo gallery, I can select the images from Google photos, download them as a Zip file, then directly upload them to Micro.blog in one hit. The upload can take as long as it needs to (this uses the new jobs system as well), and once they’re done, Blogging Tool will create a gallery for me so I can write the captions. To be able to do this without clicking around as much as I did is rather exciting.

This is not a new screen, but shows the gallery created once the images are uploaded.

Or at least it will be, when I find out how I can get large uploads working. Uploading a 27 MB Zip file in development was not an issue, but when I deployed it to my Dokku server and try it for real, I kept getting 502 errors. I’m not sure what’s causing these yet: both Nginx and Blogging Tool have been configured to accept files much larger than this, and there are no logs in either to suggest a problem. There might be a timeout somewhere that needs to be raised. In any case, hopefully this is the last hurdle I need to clear to get this working. Anyway, that’s all for this week. Oh, actually, one more thing: while working on the UI for the Upload Zip screen, I found that I never got around to changing the instructions on the Transcode Audio screen after copying and pasting the HTML from the New Gallery screen:

That's not what this screen is for!

Just goes to show how little I pay attention to this copy, even while working on my own apps. 😛

And that swoop-o-meter just keeps going up. We’re up to 4 noisy miners now. 👷‍♂️