So I knew going in that the theme I had chosen, m10c, was pretty barebones. I went with it, still, because it was clean, lightweight, no JS whatsoever, and had a sidebar. That being said, I also knew going in that I was going to mod the heck out of this thing to get to where I wanted it to be. I suppose I just wasn’t expecting to need to start at that this quickly.

But. If I want to get people’s attention, if I want to get an audience, then I definitely needed something a bit lot more than the default.

And I think I found made it.

Note: Most all of this is specific to the m10c theme, but the basic precepts can be used to modify any Hugo theme. And there’s at least one bit of useful code down there, too.

Favicons

So obviously a website without a favicon is quite boring. Can’t make for bookmarks that catch the attention, nor does it stand out in your list of way too many tabs (don’t deny it; we all do it). Thankfully the m10c theme makes it quite simple … at least for the basic single favicon. All it takes is your favicon.ico file in the /static directory and the following line in config.json:

"favicon": "/favicon.ico",

And with that, we now have a lovely favicon!

Now I’m aware there are actually an array of differently sized favicons that different browsers and OSes can use. Unfortunately utilizing those isn’t a built-in feature in m10c, at least as far as I can tell, so implementing that will take significantly more time. I think that’ll be something fun to revisit later.

Title Separator

So it irked me a bit that the separator used for the window title with this theme is a non-configurable //. Not that it looks bad, really, but it’s just not what I want to go for. Thankfully that’s an easy fix. I just popped into the baseof.html file (making my own copy, ofc) and made a small change. But, whilst I was there, I figured might as well make it a config parameter just in case I want to tinker with it again later.

3<head>
4    <title>{{ if .IsHome }}{{ .Site.Title }}{{ else }}{{ .Title }} {{ .Site.Params.separator | default "//" }} {{ .Site.Title }}{{ end }}</title>
5    <link rel="shortcut icon" href="{{ .Site.Params.favicon | default "/favicon.ico" }}" />

That was an easy fix!

Expanding the list pages

So the home page is a bit … plain. Nothing but list of the posts. No hints at what may lie within. No tags. No description. Just a list of the post. Oh, and the name of the blog, which is also on the sidebar. Redundancy! Unnecessary redundancy.

Obviously that just won’t do!

First things first: Reducing redundancy!

So looking at the default list.html template for this theme it was easy to find the culprit … on line three.

1{{ define "main" }}
2    <article>
3        <h1>{{ .Title }}</h1>
4        <ul class="posts-list">

Now I want to leave this line intact for all the other places that this template is used, which is quite a few. It’s only on the home page that it’s undesired. Thankfully Hugo has a built-in page variable, .IsHome. With a couple small additions we can clean this up!

1{{ define "main" }}
2    <article>
3        {{ if not .IsHome }}
4        <h1>{{ .Title }}</h1>
5        {{- end }}
6        <ul class="posts-list">

Tags!

For this I took a look at the default blog post page (single.html), being that it displays the post’s tags, and borrowed a few lines to splice into my newly modified list.html, borrowing the separator that the list already uses from a few lines up. Thankfully it did exactly what I had hoped … at least the second try. The first time I unthinkingly skipped the {{- with .Params.tags }} line (and closing {{- end }}), which caused a critical error when it encountered my first post … a post without tags. Note to self: pay more attention to those things!

13    <span class="posts-list-item-separator">-</span>
14    {{ partial "icon.html" (dict "ctx" $ "name" "clock") }}
15    {{ .ReadingTime }} min read
16    {{- with .Params.tags }}
17    <span class="posts-list-item-separator">-</span>
18    <div>
19        {{ partial "icon.html" (dict "ctx" $ "name" "tag") }}
20        {{- range . -}}
21            {{ with $.Site.GetPage (printf "/%s/%s" "tags" . ) }}
22                <a class="tag" href="{{ .Permalink }}">{{ .Title }}</a>
23            {{- end }}
24        {{- end }}
25    </div>
26    {{- end }}
27</span>

Already looking better, but not good enough just yet!

Tag Visibility!

With my current color scheme I noticed that the tags are very difficult to read, and if it’s difficult for me it’s likely unreadable to others. Obviously that isn’t something I want. I did find it odd that the theme’s colouring scheme doesn’t use your specified colors for those tags, but that doesn’t matter to the creative (and/or stubborn)!

After a bit of searching I found the location I was looking for. _tag.scss. And, as I thought, the colour values were hardcoded. Not for long, though! A few changes and we’re good to go!

 7white-space: nowrap;
 8background: $darkest-color;
 9transition: color 0.35s, background 0.35s;
10
11&:hover {
12    transition: color 0.25s, background 0.05s;
13    background: $primary-color;
14    color: $light-color
15}

Note: The $<color> variables I used here were set in a linked .scss file and just pull the ones this theme uses that are set in the site parameters.

Summaries!

After all, what better way to get people to want to read than to give them a preview of what lies within? For this one I had to look things up in the official documentation for Hugo for what all page variables exist and, thankfully, found exactly what I needed. .Summary. Now the only thing left is to decide where I thought it looked best. I tried it both above and below the bar that displays the post’s date, reading length, and tags, and found that below was far more aesthetically pleasing … as well as putting the tags in a more visible place as I’ve a feeling those are more important here.

27    </span>
28    <p>{{ .Summary }}</p> 
29</li>

And now we have something that may catch the attention! But we can do better!

Summaries (cont.)

Doing this doesn’t seem to make much distinction between the end of a blog post and just the end of the summary. Obviously we want to make sure people know there’s more to read … if there’s more to read. Thankfully for us, Hugo has another useful variable, .Truncated, that we can use for some simple logic.

27    </span>
28    <p>{{ .Summary }}{{ if .Truncated }} <a href="{{ .Permalink }}">Keep Reading...</a>{{ end }}</p>
29</li>

Still, though, there’s more we can do here.

Summaries (expanded)

The fact that the summaries tend to get a bit mashed together did bother me no small bit. Took me a bit of digging, mostly because I didn’t even know where to start looking, to find the solution. The very simple solution. Just one line (per blog post). Yeah … it was that simple. All I had to do was add this line where I wanted the ‘summary’ portion to end:

<!--more-->

Perfect! For now …

Tag Cloud

So I always liked the idea of these, but far too few of the more simplistic themes have them. So, of course, my only recourse is to make (or borrow) one of my own!

My starting point was the code I found here: https://www.sidorenko.io/post/2017/07/nice-tagcloud-with-hugo/.

As I read through it I did find it quite messy, though I’m sure that’s because it was adapted by others at least one time before I got my mitts on it. Of course, knowing what I’ve been learning about Hugo, the first thing I did with it was to make a partial template of it … after cleaning it up to my own satisfaction. For others who want to implement it, here you go:

 1{{ if gt ( len .Site.Taxonomies.tags ) 0 }}
 2    {{ $fontSizeMax := 2.0 }}
 3    {{ $fontSizeMin := 1.0 }}
 4    {{ $fontUnit    := "rem" }}    
 5    {{ $fontSpread  := sub $fontSizeMax $fontSizeMin }}
 6    {{ $spreadMax   := add (len (index .Site.Taxonomies.tags.ByCount 0).Pages) 1 }}
 7    {{ $spreadMin   := len (index .Site.Taxonomies.tags.ByCount.Reverse 0).Pages }}
 8    {{ $spread      := sub $spreadMax $spreadMin }}
 9    {{ $fontStep    := div $fontSpread $spread }}
10
11    <div id="tag-cloud" style="padding: 15px 15px ; border-top: 1px solid">
12        {{ range $name, $taxonomy := $.Site.Taxonomies.tags }}
13            {{ $count := len $taxonomy.Pages }}
14            {{ $weight := div (sub (math.Log $count) (math.Log $spreadMin)) (sub (math.Log $spreadMax) (math.Log $spreadMin)) }}
15            {{ $fontSize := add $fontSizeMin ( mul ( sub $fontSizeMax $fontSizeMin ) $weight ) }}
16            {{ $url := print ( relLangURL "/tags/" ) ( urlize $name ) }}
17            <a href="{{ $url }}" style="font-size:{{ print $fontSize $fontUnit }}">{{ $name }}</a>
18        {{ end }}
19    </div>
20{{ end }}

With this new partial template, which I simply named tagCloud.html, I could stick it just about anywhere … so might as well use up all that empty space at the bottom of the sidebar. For this I just had to reopen the baseof.html file and apply the proper inclusion:

42    {{- end }}
43    {{ partial "tagCloud.html" . }}
44</header>

Make sure to include the . at the end of that {{ partial }} shortcode! If you don’t do that it won’t pass in the site parameters that it needs and it’ll fail quite spectacularly. Don’t ask how long it took me to learn (how to fix) this. Seriously. Don’t. >.<

The dreaded 404, aka ‘how did you end up here?’

Prettifying the 404

This one was easy enough. Just copied over the 404.html file and had some fun with it. Too much fun.

Fixing the 404 … or trying to, anyways.

So in my reading about SEO and the like I stumbled upon a mention that Hugo doesn’t handle 404 errors correctly if you hit the 404.html page directly. And surely enough, testing it out in Firefox confirmed that that is, indeed, the case.

Now you may think that this doesn’t matter, and typically I’d agree with that thought, but apparently the dark magic that is a search engine doesn’t like these and they are considered a ‘soft 404’. In case you’re unaware, and I was before looking into this, a ‘soft 404’ is when you’re on a page that should return a 404 error, and shows the expected 404 page, but actually returns a 200 status code, aka that the page was reached successfully. Obviously this is undesired, even if it only happens when you’re hitting the url of your own 404.html page. Now I’d normally not care about such a thing because who tries to access that file directly?

Oh. That’s right. Mindless search engine bots. And search engines ding you for it. Because they’re stupid.

Unfortunately, as of yet, I have yet to find a way to have the 404.html page itself actually return a 404 error when hosted on GitHub Pages. So, as we can’t really fix the soft error, might as well do what we can to try to prevent those pesky bots from finding it!

Domo Arigato, Mr. Roboto!

robots.txt to the rescue! And your sitemap, but we’ll get to that next. Unfortunately Hugo doesn’t create a robots file by default. Thankfully having it generate one is as simple as adding the following line to your config:

{
    "enableRobotsTXT": "true",
}

After a quick check … still nothing. Apparently the m10c theme doesn’t even include a base robots.txt file. Should be easy enough to fix. Just create a robots.txt file in the layouts directly (same place your 404.html page is, incidentally) with the following lines:

User-agent: *
Disallow: 404.html
Disallow: /404/

Compile the site again, and … victory!

I did check to make sure the sitemap excluded those pages and, thankfully, it does that by default.

Are we done yet?

Yes, yes we are. For now. I’m sure I’ll tweak more things here or there, but for the moment I feel this is at a good enough place that I can leave it as is for a while.

Now with all these changes, perhaps I’ll fork this theme, put all my personal changes in that fork, then share it with others. That will be down the road, though. I’d definitely want to clean things up further as it isn’t polished to my satisfaction just yet. It works, and for now I’m satisfied with it.

I hope you’re all satisfied with it too.

If not, feel free to let me know.
There’s even a comment box down there so you can!