Modify Codeblock CSS in Hugo with Render Hooks

I use Hugo to build these blog pages as static html files. It’s pretty easy to use, and works well. And being written in Go, the templating already make sense.

Working with the command line a lot, I tend to show code rather than images. Hugo has a built-in codeblock renderer, which makes things pretty and colourful.

But I find the bash codeblocks a bit too garish, and hard to read. There are too many colours going on, and the commands themselves don’t scan well.

I really wanted to pick out the comands, and dial down any comment lines. In the past I’ve added a Terminal window style using css, so that’s going on here too.

Reading through the docs I found render hooks, that let you override default behaviour. And you can override for specific code languages. This is great because it’s really only the bash codeblocks I want to change.

In my layouts directory I have these templates:

Terminal

    
$ find layouts 
layouts
layouts/_default
layouts/_default/single.html
layouts/_default/rss.xml
layouts/_default/_markup
layouts/_default/_markup/render-link.html
layouts/_default/_markup/render-codeblock-bash.html
layouts/_default/_markup/render-codeblock.html
layouts/_default/baseof.html
layouts/_default/section.html
  

There are very few templates because I don’t use a theme, and have only a couple of page types. The render hooks sit right there in the layout templates.

The codeblock render hook overrides what Hugo would normally do. And by appending the language to the hook filename you can be specific.

In file layouts/_default/_markup/render-codeblock-bash.html I have:

1 <div class="mt-5 mb-5 mr-5 ml-5">
2  <p class="has-background-white-ter mt-4 mb-0 pt-2 pb-2 has-text-centered has-text-weight-semibold" style="font-size: 16px; border-radius: 15px 15px 0px 0px; border-style: solid; border-width: 1px 1px 0 1px; border-color: #c9c9c9;">Terminal</p>
3  <pre class="has-text-left mb-0 pt-0 pl-2 has-background-black" style="border-radius: 0px 0px 10px 10px; overflow-wrap: break-word; white-space: break-spaces; word-wrap: word-break; color: #c3c3c3;">
4    <code>
5 {{ $cmd := replaceRE `(\$ [[:print:]]+)` "<span  class=\"has-text-white\">$1</span>" .Inner }}
6 {{- replaceRE `(\# [[:print:]]+)` "<span  class=\"has-text-grey\">$1</span>" $cmd | safeHTML -}}
7    </code>
8  </pre>
9 </div>

On line 5 I add a class to pick out commands, they are any line starting with $. And I use the same pattern to darken any comment lines, any line starting with #. The rest of the codeblock text is off-white. This is all that’s required.

The css seems convoluted, but it makes lines break and wrap rather than run off to the right. I use Bulma for css classes, but any go-html templating works here.

Now every time I use the bash language on a codeblock, I automatically get a Terminal style window. But any other codeblock is rendered normally.

Which results in:

Terminal

    
# this is a comment
$ ls -1 
Makefile
archetypes
content
hugo.toml
layouts
  

posted by Doug Bridgens, on Apr 4 2025