It's a static site
I ran a few WordPress sites back in high school and I was never very thrilled by the experience. The site was kind of slow, unless you installed one of those random “WordPress caching” plugins that usually did their job, but sometimes broke things. Every half a year or so, I'd update my WordPress installation (the alternative was facing exposure to unpatched exploits) and pray my plugins worked and the formatting didn't break. I'd try to tweak the look of our site, but there was so much CSS and so many plugins that I had a hard time figuring out what files I needed to touch. And eventually one of my sites got hacked, probably due to some PHP/WordPress vulnerability.
I'm sure WordPress has gotten better since then, but when I decided to start a blog earlier this year, I knew I wanted to make it a static site. I simply didn't want the additional features that server-side code offers; I had always preferred Git to a content management system, and leaving the problem of comments and comment spam to a third party (like Disqus) seemed like a good idea anyways. Plus, static sites are simple to host, fast, secure, and easy to configure.
So, my site is powered by the Hugo static site generator, and is hosted on GitHub pages. And not only is my site static; it's also:
I'm also proud to say that this site displays both and
Here's my experience with making this happen:
This was the easy one; Hugo, out-of-the-box, runs Chroma during the build step. This turns markdown code blocks directly into properly styled HTML, obviating the need for something like highlight.js that runs client-side upon page load. I only encountered one minor inconvenience: the theme I chose (Cactus) included another implementation of code highlighting, done client-side, that both added bloat to the site and interfered with Chroma's styling. It took me around half an hour to remove this “feature” from the theme.
Getting server-side LaTeX rendering was much more cumbersome, because the tools I needed were node.js-based and therefore didn't play well with the Hugo ecosystem (which is basically a single executable written in Go). The mathjax-node-page package essentially emulates (on the server) the processing that would've been done client-side by the MathJax library, which is exactly what I needed. Unfortunately, I couldn't find any post-build hook feature in Hugo, so I had no way of calling this library after Hugo was done with its part of the build. Currently I'm working around this with the following monstrosity of a Makefile:
Where the second line finds all HTML files from the Hugo output and runs
mathjax-node-page on them…highly inefficient. Thankfully it parallelizes well (note the
-P 16 flag passed to
xargs) so what would've taken 20 seconds serially now only takes around 2. Meanwhile the
hugo step currently takes around 40ms, so it's about 2% of the overall build time…definitely not taking advantage of Hugo's fast builds right now. Someday I might try to write a fancier Makefile that only runs
mathjax-node-page on HTML files that have been changed, but for now I think a 2 second build is fine.