1238 Words

Reading time 6 min

A new website and blog

This is the first post on our new blog. Over the past two weeks, I (James) have re-done our website twice. First I migrated from a custom node.js site to Jekyll, and then from Jekyll to Hugo. This post both serves as a placeholder while I develop the styling of this blog, and as a place to jot down lessons learned in this process.

The old website

When we started this company, Craig put together a simple website using node.js. We’ve done tons of work using node, and it was straightforward to build the site. There were a few “interesting” tweaks to our usual sites, including setting up a twitter feed and integrating the site behind an nginx load balancer. But for the most part, we built it and let it run.

As time went by, the old website showed its deficiencies. First the twitter feed promptly broke, as twitter changed its API and terms of service and the twitter library we were using fell behind the curve. Then there was no easy way to keep content up to date. We had no section for blogging or posting research, and no way to document finished projects.

I had some free time recently and I wanted to research some recent trends in transportation but didn’t have an outlet for that work. So instead set out to redo our website.

The candidates

Since my biggest pain point with our old site was the desire to write blog posts, one simple solution would be to run WordPress or some other blog platform locally. Aside from issues with running a PHP/node/python/Elixir/Perl server that would barely be used, blogging packages are for blogging by multiple, independent users. We don’t need a browser-based editor, CMS features, user management, or themes.

The next option considered were the static site generators. Last June I finished a project in Elixir (with a front end written in ClojureScript!), and I wanted to get back into it. However, I couldn’t find any mature, well-used static site generators in Elixir.

In searching for an Elixir static site generator, I discovered that the Elixir School website actually uses Jekyll. It says so right there in the source code on github. Jekyll is the default site generator for GitHub repository docs, and is very active—over 3,700 closed issues and invariably the most recent commit happened today!

So I put in the work to switch to a Jekyll-based site. Jekyll did everything I wanted it to do, and the conversion went pretty well, all told. But there were pain points. First, I didn’t like Ruby, nor did I like what I saw in the few issues I browsed while tracking down bugs. But I eventually bailed on Jekyll because of the limitations of the Liquid template engine. I was getting fed up working around the limitations of the limited functionality and logic, and then threw in the towel when I discovered a problem I hit (no not in boolean logic) was first reported in 2012, and a complete fix posted over two years ago, with no action by the Liquid team, not even a close/reject of the pull request.

Straw, meet camel’s back.

I rage quit Jekyll right after finishing the site, but right before writing my first blog post. I pushed up the site, and immediately got to work on a Hugo port.

Hugo

This site is running on Hugo. I’ve been wanting to learn Go for a while, and I considered Hugo a few years ago, but never got out of the starting blocks. After wrestling with Jekyll, and with a clear goal in mind, this time around jumping into Hugo and Go was fairly simple.

Hugo is much more amenable to my style of programming in almost every way. It is super fast, with page re-renders happening almost right away after a save; the auto-reloading of the webpage in the browser is turned on by default; and the templating language uses Go Templates, which is really good.

The biggest issue for my development process was the lack of a decent Dockerfile. Going with the punk rock DIY spirit, I tried but failed to build hugo inside of a Dockerfile. The stumbling block was supporting Sass templates. It seems that the go-libsass project links Go with C++. In Alpine Linux (which I use for my Dockerfiles) linking C++ is touchy, meaning the code would sometimes run without problems, or it would segfault for no reason.

Up Arrow, enter, crash, repeat, until it magically works!

Luckily I discovered a decent set of Dockerfiles in the klakegg/hugo repository. The key insight seemed to be using a Docker Alpine image with a custom version of glibc linked in (frolvlad/alpine-glibc). Copying this approach, I was able to set up a Dockerfile for Hugo. I’m still not super pleased with it in that I am downloading the binary Hugo file rather than compiling it locally, but it runs without crashing, which is 100% better than what I had.

I’ve found switching from Jekyll to Hugo that Hugo seems to prefer having everything in files. For example, Jekyll recommends using data files to set up site-wide navigation https://jekyllrb.com/docs/step-by-step/06-data-files/. The first cut was to copy the data files from Jekyll style to Hugo style. But gradually I grokked the Hugo idea that everything is a Page. I learned how to automatically generate menu items from the content of the pages and site sections itself. Now instead of a separate data file (that has to be maintained), I am building my menu by including config data in the head of each content file (_index.md, post.md, etc).

For example, for this blog section, I have the following directory tree:

content
├── about
│   ├── crindt.md
│   ├── crindt.png
│   ├── _index.md
│   ├── jmarca.md
│   └── jmarca.png
├── blog
│   ├── first_post.md
│   └── _index.md
...

Then the top of each _index.md file contains a data to indicate how to include it in the navigation menu:

---
color: grey-dark
icon: book
icon_type: solid
Title: Blog
weight: 2
menu:
  main:
    name: blog
---

The menu entry is picked up automatically by Hugo. If I don’t want a section in the navigation menu, I don’t have to add the menu entry, or I can use a name other than “main”. These items are referenced in my navbar code as follows:

<div class="navbar-menu">
  <div class="navbar-start">
    {{ range .Page.Site.Menus.main }}

...

Pretty simple.

I can also add a menu: main: type entry to the top of the blog posts, which I can then use to generate drop-down menus if I want under the parent “blog” entry. Lots of interesting features to explore.

Finally, from what I’ve seen by using the template functions, Go is a reasonable, functional-type programming language. The templates have lots of functions, including a regex matcher I sorely missed in Liquid. Now I can write code like:

{{ else if (findRE "(?i)github" .icon 1 )  }}
{{ readFile "/themes/activimetrics/resources/svgs/github.svg" | safeHTML }}

The future

Now that this website has been updated, I hope that this blog will be regularly updated with transportation-related content. But if the past is prologue, I’ll most likely be inspired to write short code-related blog posts. We’ll see. Most important is the fact that the content is now here, on the Activimetrics web server. It just makes no sense to me to put our content somewhere else, like facebook, instagram, or Wordpress.

See you in future posts.