Goodbye Ikiwiki, hello Hakyll!

Posted on March 18, 2018 with tags tech.

For a while now, I was somewhat unhappy with Ikiwiki, for very “important” reasons.

First, it’s written in Perl, and I haven’t written serious Perl for around 20 years (and that was not serious code). So, me extending it if needed is unlikely, and in all my years of using it I haven’t touched anything except the config file.

Second, and these the real reasons, Ikiwiki is too complex. The templating system is oh-so-verbose. I tried to move to Bootstrap for the styling of my blog (I don’t have time myself to learn enough CSS for responsive, nice and clean sites), but editing the default page template was giving me head-aches. Its wiki origins mean tight integration with the source repository, and the software automatically committing stuff to git as it needed (e.g. new tag pages, calendar updates, etc.) which is overhead for what should basically be a static web site.

So, in the interest of throwing the baby with the bathwater, I said let’s give Hakyll a go. It’s written in Haskell, so everything will be good, right?

And it is indeed. It’s so bare-bones that doing anything non-trivial (as in not just a plain page) requires writing code. The exercise of having a home-page/blog was, during the past week as I worked on converting to it, a programming exercise. Which is quite strange in itself, but for me it works - another excuse for Haskell.

Now, Ikiwiki is a real wiki engine, so didn’t I lose too much by moving to Hakyll, which is just static site generator? No, I actually stopped using the “live” functionality of Ikiwiki (its cgi-bin script) a long while ago, as I disabled the commenting functionality; there was just too much spam. And live editing of pages was never needed for my use-case.

This migration resulted in some downsides, though:

  • I haven’t yet, and probably will never import the ~100 or so comments that I had on the old pages; as said, I stopped this a long while ago (around 2013), so…
  • I reorganised the URLs, and a lot of my old posts were not conforming to any scheme, so posts up until mid-2016 do not have the right redirects; I’ll possibly fix this sometimes soon. Posts newer than that date already had date in the URL, and these have a generic redirection in place.
  • Hakyll doesn’t include the tags in the atom/rss feeds “categories”, so this is a downgrade from before
  • Because Hakyll is more extensible, I can use canned stuff (e.g. Bootstrap, Font Awesome) more easily, which means bigger site; the previous one was really trivial in terms of size.

Internally (for my self), there are a few more issues: Ikiwiki came with a lot of real functionality, that is now missing; as a trivial example, shortcuts like [[!wiki Foobar]], which I now have to replicate.

But with all the above said, there are good parts as well. The entire site is responsive design now, and both old and future posts that include images will be much nicer behaving on non-large-desktop-viewing case. Instead of ~60 lines of (non-commented-out) configuration, I now have 200 lines of Haskell code (ignoring comments, etc.); this is a net win, right?

On top of that, because of the lack of built-in things, I had to learn how to use Hakyll, so now I can (and already did) much more customisation to the html output; random example: for linking to internal pictures, I have a simple macro:

$pic("xxx.jpg", "alt-text")$

which knows to look for xxx.jpg in the right place, relative to the current page URL, and all this results in a custom HTML code, rather than what the markdown engine would do by default. Case in point, and this is not hard-coded in the source of this page, but dynamically expanded from the above example (and escaped), the result is:

Another good part is that, given how bare-bones Hakyll is, if you look for “How to do foo in Hakyll”, you don’t get as a result “Use this plugin”, but rather - here’s the code how to do it.

I’ll have some more work to do before I’m happy with the end state, but - as change for the sake of change goes - this was fun stuff.