While publishing my dissertation online and putting together the Parkour Clinic site over the summer, I got increasingly familiar with the Hugo static site generator. I’d first set myself up with Hugo when I decided to scrap my previous personal training site, and move the few blog posts I had there over to a personal blog instead. 1 At the time I just picked a Hugo theme, dropped it in, exported my blog posts from Squarespace into markdown, and left it ticking away as it was.
Eventually, though, I started tinkering with the theme I was using, extending the templates provided to customise how my blog was running. Likewise, when it came time to create Parkour Clinic, I knew I wanted to be able to use template partials to handle things like a navigation bar, that could be updated in one place but included on all the pages across the site. The last time I had properly built a site for myself from scratch had been almost twenty years ago; I remembered well the pain of changing one navigation menu URL and having to go change it by hand across dozens of html files. No thanks.
My ongoing experience of getting more comfortable with Hugo’s templating sparked an idea for another problem I was trying to solve at the same time - how did I want to create and store my patient clinical notes for Parkour Clinic?
I’d been thinking about this for a while. All my sports therapy work placements to date had essentially used hard copies of forms filled out by hand and kept in a filing cabinet - I didn’t have the space (or printer toner) for that. Neither did I want to use Word or similar to actually create the notes - I’ve gotten used to the speed and simplicity of writing in markdown. Besides, there wasn’t really anything beyond the occasional table or image that I need to include in a patient’s notes that needed fancier layout abilities than markdown provides.
But, I didn’t really want to just have a directory of .md files on my hard drive - it’d be nice to have some interconnectivity between these notes, so I could flip between them quickly or sort and group them in various ways (by date or by patient name, for example). And I wanted the markdown processed when viewing, so it’s easier to read, and be able to print the formatted document to PDF or similar if I needed to share it with a patient.
Solutions for clinics are out there - Cliniko seemed to be a popular one I saw a lot while researching - but I didn’t want to pay for a service like this, as I’m aiming to keep the costs of Parkour Clinic as low as possible since I’m not really monetising it. I could use a markdown based notes app, like Bear, but this would tie me in to their ecosystem (even if just a bit, as it’s fairly easy to export from something like Bear), and I was a bit iffy about sending off all my patient info to some cloud server somewhere.
So I built my own!
Hugo clinic notes theme
Hugo Clinic Notes is a theme for Hugo that lets you create markdown based patient notes, and then view them on a site running on Hugo’s bundled local web server. It’s been on my GitHub for a little while but just got accepted onto the Hugo themes repository, where you can try a demo and find instructions for downloading it. 2
Admittedly this is probably for quite a niche audience of those who 1) run some kind of clinic/service that keeps records like this and 2) is nerdy enough to want to work in markdown and on a local web server, but if that’s you and you’re looking for a relatively easy and free way to run a patient records system this might do the job. You can customise the forms included or just delete them outright and use your own designs, and there’s a number of views and ways to get to the document you want.
There are some nice little additions I’m quite proud of, like the use of @media print
CSS media queries to remove the top and bottom navigations when printing any document (useful for creating PDFs of your completed forms to send to patients), or the way you can include table of contents based on markdown headings in the top navigation by just changing a setting in the yaml front matter. Oh, and the way the loop logic on the list-all-patients-by-name index page only create alphabet headers for letters that actually have patients under them. Man, that one took a while… 3
Here’s a couple hints: it’s just in a browser, so use the good ol’ Cmd / Ctrl + F
find command to search text for the bits you need. It’s all just markdown under the hood so I also suggest using Git or another version control system to kind of ‘lock-in’ each form as you complete it or make edits to one, to create a really nice paper trail of patient records over time. 4 If you want to get really advanced, I’ve even set up macros with Keyboard Maestro to gather input from prompts and then use Hugo commands at the terminal to create new forms with the correct patient name/date/time for an appointment and open them for editing in my markdown editor… But that’s up to you.
Like I said, this one is probably solely for me. But, building it was hugely rewarding, and I’ve been using it for a couple months now with my Parkour Clinic appointments where it’s solved my problem of patient notes storage practically perfectly. If nothing else, it shows how useful a tool like Hugo can be for putting a graphical frontend on a very simple backend.
- Why pick Hugo, over the growing number of other static site generators available these days? To be honest, it was just because my wife used Hugo for her own blog and it was useful to be able to lean over to her on the sofa and point at bits of code while going “WHY ISN’T THIS WORKING”. ↩︎
- I didn’t quite appreciate the time frame between submitting the theme to the Hugo repo and it getting accepted, so after a few weeks of radio silence I kind of thought it was a nice way of saying “your theme isn’t accepted and we’re just going to leave it until we all quietly forget about it”, so it was a nice surprise to get the email notification saying it was approved. ↩︎
- And required learning about scratch! ↩︎
- Just keep it local - I wouldn’t recommend syncing to a service like GitHub, even a private repo, for confidentiality reasons. ↩︎