But why ?
Why would I create a Hugo theme ?
Well, I wanted to blog using Hugo, I found the iris theme and I liked it. But I didn’t understand how to customize it to my needs. Therefore, I decided to create my own theme to learn how Hugo works and make (or at least try) to make a nice blog.
Let’s start
I started by creating a new Hugo site with the Hugo CLI. Then I created a new theme with the Hugo CLI. The hardest thing is to pick a name for the theme, I chose Deutalion because it sounds cool.
|
|
How does a theme work ?
You have the following files and folders in a theme:
|
|
The types of page
There are three main types of page:
- The homepage
- The list of all your posts
- A single post
For each of these you’ll have 1 .md
file with the content and one template file where you’ll put the HTML code to display the content.
Here are the path of the .md files and the corresponding template files:
|
|
The template files used to display these pages are stored in the layout/_defaults
folder of the theme.
You can also see in the layout folder the partials
folder: this is where you put the HTML code that you want to reuse in your theme. For example, you can put the head
and navbar
in partials and then include them in your baseof.html file.
The baseof.html file is the base file of your theme. You can think of it as the skeleton for every page.
One key concept in Hugo is a block, you can define blocks in your baseof.html file and then override them in your template files. For example, you can define a block named main
in your baseof.html file and then override it in your listof.
Here is for example my baseof.html file:
|
|
Here I’m defining an HTML document, then I copy-paste the head in the document with {{-partial "head.html" . -}}
in order to have the same head in all the pages. I do the same with the footer
and the navbar
. Then I define a block named main
.
Because every template uses the baseof.html file, you can define a main block in baseof and then override it in the list or single template.
Here is the single.html template
|
|
Here I’m overriding the main block, and I’m adding the title and the content of the page. The {{ .Variable }}
is Hugo syntax (in fact it’s go template syntax) that allows you to access the variable of the page. For example, the title of the page is stored in the .Title
variable. You can define your own variables in the .md file of the page using front-matter. You also have access to a page context where all these variables are defined.
Customizing the rendering
You can add a custom way to render code block. In your content file you can add a code block like this:
|
|
And you can add a custom way to render this code block using the render-hook in the themes/deutalion/_default/_markup/
file.
Here is mine for all the codes included in my content.
|
|
This use a figure, with a figurecaption (the header displaying the language and the copy button) and the code highlighted by Hugo using {{ highlight .Inner .Type }}
.
I added a bit of JavaScript to make the copy button work.
|
|
Emphasizing inline code
You might like to have a different style for inline code. You can do that by adding a bit of CSS in theme/yourtheme/static/css/tailwind.css
:
|
|
Conclusion
A theme is made using reusable component (partials). For each page on your website, you have 1 content file, and it’s corresponding template file used to generate the final HTML. All the template use the baseof.html file as a skeleton you can override the blocks defined in it. You can add custom rendering for links, code blocks, etc. using the render-hook.