Crypto Island


Source code for this blog

Posted 2021-03-03
Updated 2021-03-29
Tags: blog, github, hakyll, haskell

This site is built with Hakyll. I’ve had a great experience with that so far! Here I’ll do a quick overview of how I manage it in case you want to try something similar. Most of it is based on this tutorial, but I switched to self-hosting on a VPS rather than via Github Pages.


The master branch holds the production source code. I make a new branch like master-cssfixes or master-greatidea when starting any task that has a chance of failing, then merge back into master once I know it works. All my draft posts live on one drafts branch. When one is done I check it out onto master, then rebase drafts from there.


Each post is a folder with an like this and possibly some other files too: drawings, standalone scripts, etc. The post should contain links and instructions whenever you can do something non-obvious with the other files. I mainly write in Pandoc markdown, but you can use anything supported by Pandoc. Posting dates are based on the folder structure, and the rest is pulled from the markdown header. I date draft posts 2099/something, which pushes them to the top of the recent posts list and reminds me to fill in the actual posting date later.


To write I checkout the drafts branch, rebase from master if needed, and run It builds a local copy of the site, serves it at http://localhost:8000, and auto-updates it as I change things. The tag cloud, RSS feed, CSS, and recent posts list auto-update along with the post contents. The only thing that doesn’t auto-update is the Haskell code; if I edit that I have to kill and re-run the script. One other gotcha is that I have to disable caching in Chrome and Firefox to make sure I’m not looking at old versions of the CSS.

I commit the drafts often. Then when a post is done I:

To ensure that I don’t accidentally publish draft posts I have a pre-push hook as suggested here:

# .git/hooks/pre-push
if [[ `grep 'draft'` ]]; then 
  echo "You really don't want to push the drafts branch. Aborting."
  exit 1

I also remove them in and .gitignore:

# Just in case, remove accidentally-added draft posts
rm -rf posts/2099
# .gitignore