---
title: "Blog revamp"
description: "I redid the blog and made my own static site generator"
date: "2025-01-02"
draft: false
tags: []
---
Hello again three people reading this blog. The three being me, the bot gestalt consciousness that seems to have noticed this blog, and a British person named Josh a decade after this post is published. It's been a bit, more than the normal a bit in fact. There are two reasons for that, 1) I've been busy when I had blog article topics rattling in my head and 2) I wanted to finish this revamp first. Anyways onto some highlights of making the new site.
(Sorry if you happen to be using a feed reader on my blog, I probably messed up your feed a bit)
## Making the static site generator
### Inspiration
The reason I decided to make my own static site generator is because I came across [this](https://abhinavsarkar.net/posts/static-site-generator-using-shake/) blog article describing a setup in [Haskell](https://www.haskell.org/) (which is a language I have some interest in) using [Shake](https://shakebuild.com/), [Pandoc](https://pandoc.org/) and [Mustache](http://mustache.github.io/). It gave enough info that I was able to get an MVP version up relatively easily.
### Modifications
However I wasn't satisfied with that initial version for a few reasons.
#### Refactoring the code into multiple files
While the original blog gave a single file setup I found modifying it kinda annoying for reasons I can't put my finger on and have now forgotten. Regardless I split things up into five files.
- `Main.hs` entrypoint into the program and where various things come toegether to actually describe the program.
- `Utilities.hs` various utility functions I didn't consider appropriate for Main.
- `Templates.hs` functions related to application of the Mustache templates.
- `Config.h` some configuration constants including where files which should just be copied over are, where posts are located, what misc pages are present and where to dump all the output.
- `Types.hs` a centralized place where I put all the type definitions that were needed for various reasons
#### Adding in robots.txt
This is actually the last addition I made but it's also the simplest, in `Config.hs` I added `"robots.txt"` to the `assetGlobs` list (that list is where all the files which get simply copied over are).
#### Adding a Web Feed
To add a output for a Web Feed I needed to pass all the post objects to a template which generates the feed. So I did that.
> Uuuh more details?
... Fine the generator (named PSB), goes through and reads all the files in the posts directory to generate all the html and what not. In addition to converting markdown/typst into html it also grabs meta data and that output and the metadata all gets packaged into a `Post` type. All of those post types are put into a list and the list is passed to the code that generates the RSS feed.
(the sass above was sponsored by "having someone read my post before publishing and them correctly pointing out that I'm not explaining enough")
#### Removing the posts page
More details on this when I get to describing building the site but I realized that the way things were shaking out that it made no sense to have a separate posts page so I removed the code for it from the static site generator.
#### Adding in Typst support
Here's the pain in the ass one I decided to do. I like [Typst](https://typst.app/), it makes making my documents and math homework pretty, easy. Also Pandoc added support to it semi-recently and learning that partially inspired me to make this. However adding it into the static site generator required that I handle dispatching to appropriate Actions depending on the file extension. In addition I had to read from a separate yaml file because Pandoc doesn't support grabbing Typst Metadata.
Wanna know what the worst part is? I'm probably never going to use that functionality for an actual article... yes seriously. This project took long enough that in the back of by dumb brain I realized that
> Wait if they're adding in [HTML support to Typst](https://github.com/typst/typst/issues/721) that might break things for me when Pandoc downstreams their features... Fuck
So yeah... More on that when I discuss what I'm probably going to change in future.
#### Making a github action out of it
I refuse to accept any downgrade in my own long term convenience as such it was imperative that I be able to have pushing/merging in a repo be equivalent to rebuilding and publishing the site. First things first I needed to containerize my static site generator. As such I wrote this `Dockerfile`
```dockerfile
FROM haskell
RUN mkdir -p /github/workspace
RUN cabal update
COPY ./psb.cabal /mnt
WORKDIR /mnt
RUN cabal build --only-dependencies
COPY . /mnt
RUN cabal build
WORKDIR /github/workspace
RUN export folder=$(ls /mnt/dist-newstyle/build/x86_64-linux) && mv /mnt/dist-newstyle/build/x86_64-linux/"$folder"/psb-0.1.0.0/x/psb/build/psb/psb /mnt/psb
ENTRYPOINT ["/mnt/psb", "build"]
```
Anyways if you think it's a little weird that I separated out copying my cabal file into the container and building dependencies then yeah it is weird. The reason for that is that docker caches the result of each line of the dockerfile being evaluated and I rarely change my cabal file so by copying that in and building dependencies first I don't need to rebuild pandoc every time I want to rebuild the docker container on my machine. Reason I set the working directory to `/github/workspace` is because I wasn't sure if github did that for me and also it made sense to have a clean working directory in the event I use this for something else regardless. Finally we have that wacky RUN command, the reason for the wackiness is because I don't want to hard code the ghc version into the dockerfile and this was the easiest solution for avoiding that.
Lastly you might be wondering why I didn't split building the container psb out from running it in the dockerfile like I tend to do for other cases where that's a thing. The reasoning is simple, there's no Haskell container that uses Alpine/Musl libc and I don't want to set one up myself and I kinda don't care about having a separate stage if I can't get it down to just musl libc and SSL certs so fuck it just make a chonky container image.
After publishing this I will probably make a github workflow to build the container because right now site build times in the CI are obnoxiously long due to github rebuilding it every single time.
Asside from the dockerfile I also had to write a `action.yml`
```yml
# https://docs.github.com/en/actions/sharing-automations/creating-actions/metadata-syntax-for-github-actions
name: 'psb'
description: 'Use PSB to build static a static site'
runs:
using: 'docker'
image: 'Dockerfile'
```
Nothing interesting
## Making the static site
Unfortunately I forgot details on making the layout what I wanted so won't be writing about that.
### Light and dark theming
This site now has dark and light themed versions and will be whichver version you indicated in your browser and/or OS settings. I considered adding a button to let you toggle over between the two in the vein of [this blog post](https://www.joshwcomeau.com/react/dark-mode/) however I decided that the hit to performance for people on iffy/slow connections wasn't worth it. That said I do have an idea that allows for a button without having consequenses for people with iffy connections but I'm not going to implement it on this site due to how complicated it would be. However I do intend to make a demo and write a blog post on that.
### Picking colors
Picking colors was annoying because I wanted colors with good contrast so this site would be reasonable but I also wanted to use colors other than black and white. Doing that in RGB color space is annoyingly difficult to accomplish but I perservered and convergent evolutioned my way to colors which are similar to the default colors for links on the light theme and more interesting colors on the dark theme. This was an even more interesting problem when I had navigation elements that were text which were a different color from the normal links. Outside of code snippets I did somewhat fail at adding colors though.
### Icons
The navigation icons for this site were picked off the internet looking for a house icon and an RSS icon. Additionally in the footer I'm using [github's official svg logo](https://brand.github.com/foundations/logo)*, asterisk due to the css I added.
#### The CSS I added
I wanted the logos to respond to light/dark theming so I mucked around with the xml a bit to add classes to all the svg elements and set the colors in style tag(s). The style tag(s) set the coloring based on some [CSS custom properties](https://developer.mozilla.org/en-US/docs/Web/CSS/--*) and the properties are set by some CSS imports.
##### Black boxes go brrrr
The problem with that approach is that while the CSS is loading in your icons will have all the coloring be black which for reasons I will get to in a moment will lead to the every icon being a black square for a moment. This isn't great, what makes things worse is that imports
1) block the css below them until they're done
2) have to be at the top of whatever CSS you're writing
However I was able to come up with a mildly cursed solution to this
```xml
...
```
having imports at the top is fine just gotta have it at the top of a different styling context that immediately follows the one you want to put the imports at the bottom of *taps head*. Also they default to being blue colored because blue has decent contrast in both the dark and light themes and doesn't imply that there's been an error like red would.
#### How the icons appear on the site
I didn't want to have inline SVG so I needed a different way to show SVGs, the way I did that was to use `