New build, who dis?
It's been quite some time since this site was initially created, and while I planned to do so entirely from scratch it seemed silly to create some homebrew setup just for templating. This led to me using Flask, and I've not touched it since. I have on multiple occasions meant to move, but Flask has been simple and pretty bullet proof, so it's only now that I'm taking the jump to Hugo.
I fully expect this to be pretty simple painless, but figured I would document the process just in case anything interesting cropped up.
Get Hugo Set Up
Quickfire round, not much to see here:
Get HugoCreate a new site
hugo new site averybiteydinosaur;
cd averybiteydinosaur;
Grab a basic prebuilt theme
git clone https://github.com/theNewDynamic/gohugo-theme-ananke.git themes/ananke
echo "theme = 'ananke'" >> hugo.toml
Start the server
hugo server
And we're up and running
Move Stuff Over
First I'm following the documents to create a new post
hugo new content content/posts/test.md
This gives me a markdown file with some prepopulated values for title, publication and draft status. I quickly check that I can also create new html files with Hugo too, which look almost the same as the markdown files. I add in some basic tags to make sure everything works as expected, and when it does we're off to the races
All my posts on the old site are basically pure HTML, just with a little bit of handlebars/flask flavour. So they look something like this:
{% extends "base.html" %}
{% block header %}
<script src="/static/js/highlight/highlight.min.js" async></script>
<link rel="stylesheet" href="/static/js/highlight/styles/rainbow.min.css">
{% endblock %}
{% block content %}
<article>
<h1>Quick and Dirty K-Anonymity Password Checking</h1>
<section>
...
More HTML and stuff
...
</section>
</article>
{% endblock %}
So I can just grab everything between the section tags and throw it into a HTML file and as long as I add in a little "header" above it just works. I grab the smallest article and do just that:
Excellent
It's worth noting at this point I'm running the server with --buildDrafts and --disableFastRender flags as this lets me see my drafts as posts and update in realtime
A quick scp and 5 minutes of manual editing later I have all my old articles across. The highlighting for code is immediatly and rather obviously missing (I've done nothing with any JS) as are the images, but otherwise we're pretty much up and running.
I fix the images first. On the old machine they're all under ~/.virtualenvs/website/app/images and checking Hugo docs I can see that I'm able to paste my static directory over the top of Hugo's (currently empty) static directory, then do a quick find on /static/images and replace with /images to be up and running again.
Theme Swap
First things first I need a new theme that has a dark mode and the first one I spot is "paper, so I grab that
git clone https://github.com/nanxiaobei/hugo-paper themes/paper
I then update hugo.toml to use the new theme, start the server and hit an error (finally some excitement!)
The error is a parsing issue with the partial template footer.html, more specifically "endif" is not defined and a quick flick through the previous theme identifies that the block should have been closed with end not endif and checking the github I can see that a recent pull request is the culprit. I excise those lines run the server again and we're back up and running in dark mode.
Custom Theme
Now that I can finally remove my sunglasses it's time to create my own theme so that my previous websites style is used, so a little research of the templating documentation is called for.
Looks like the first thing to do is set up a baseof.html which will then be used as the starting point for every other page. On my old site this was done with (simplified):
<body>
<main>
{% block content %}{% endblock %}
</main>
</body>
In short have a header element with a link back to the main page, and then whatever the actual page content was went in the {% block content %}. With Hugo it's fairly similar, but this would be modified to:
<body>
<main>
{{ block "main" .}}{{ end }}
</main>
</body>
In my header I'm using an automatically generated link to the homepage
<a id="home-link" href="{{ url_for('index') }}">
which becomes
<a id="home-link" href=""{{ `` | absURL }}"">
and so on.
I also to my horror find that I've hardcoded in several links which remain pointing at my old website (as I'm currently testing on localhost:1313), but a quick find and replace takes care of these too. Finally after a little more clean up I'm at the point where the website is mostly recognisable as its previous self
For the moment the {{ block "main" .}} is being replaced with the themes pre-existing pages, one iterating over all articles with links for the homepage, and a seperate main for the single page articles themselves. This is why the top title has a weird square background behind it, as well as a host of other little issues, but for the moment I'm setting my sights on the code highlighting.
On my old website I used highlightjs saved locally to do highlighting. This runs js to check all the code blocks, and then add in span elements which are given classes depending on the code in question. These span elements are then highlighted by another CSS file which is created just for this purpose. Originally this was loaded on a case by case basis as not all posts had code, and nor did the main page, however for now adding a couple of lines to my header is a dirty workaround to get it up and running again.
<script src="/js/highlight/highlight.min.js" async=""></script>
<link rel="stylesheet" href="/js/highlight/styles/rainbow.min.css">
Finally once that's done I'm swapping out the layout files single.html and list.html
For single.html a quick replacement using the title to get back in the format my old css was expecting.
{{ define "main" }}
<article>
<h1>
{{ with .Params.title }}
{{ . }}
{{ end }}
</h1>
<section>{{ .Content }}</section>
</article>
{{ end }}
For list.html, a little more work. We check for all regular pages, then iterate through them, using the title inside the "template" html from my old site. The one sticking point is that on my old site I had a tagline which was used, but a quick search shows I can add this into the posts, alongside the title, date and draft status, so that's what I do with .Params.tagLine
{{ define "main" }}
{{ $pages := union .RegularPages .Sections }}
{{ if .IsHome }}
{{ $pages = where site.RegularPages "Type" "in" site.Params.mainSections }}
{{ end }}
{{ $paginator := .Paginate $pages }}
{{ range $page := $paginator.Pages}}
<a class="card-link" href="{{ .Permalink}}">
<section>
<h1>{{ .Title }}</h1>
<p>{{ .Params.tagLine }}</p>
</section>
</a>
{{ end }}
{{ end }}
That's it, the site looks the same, loads marginally more quickly, but I don't need to bring in a python virtual environment I can just clone a git repo, point to it with nginx and I'm up and running on any new host. Boom.