Hugo Site Configure
In this post, we will see how we can create and configure our Hugo blog to our needs. This guide assumes, that Hugo is already installed in your system.
We will use a certain theme as an example, but the same principles apply to almost every theme.
We must also note that Hugo is somewhat tied to the theme you have, so if you want to change it, some changes will need to be made, mostly on the top config file, and less on the markdown content.
Create a Site
Create a new site with the name TestSite
:
hugo new site TestSite
and change directory in the newly created directory:
cd TestSite
If you list the directories it should have the following structure:
user@hostname ~/TestSite$ ls -l
archetypes
config.toml
content
data
layouts
resources
static
themes
Archetype Configuration
In the archetypes/default.md
file there are the default metadata generated when creating a new page. The default are:
---
title: "{{ replace .Name "-" " " | title }}"
date: {{ .Date }}
draft: true
---
We can change the draft
option to false
, in order to publish all new posts:
---
title: "{{ replace .Name "-" " " | title }}"
date: {{ .Date }}
draft: false
---
Initialize Git repo
Initialize a Git repository in order to keep changes and have version control, by executing inside the site directory:
git init
git add .
git commit -m "First commit"
git branch -M main
Download & Install a Theme
Find a theme
Find a theme in the Hugo Themes page and download it from GitHub.
Download a theme
For example if we choose the hyde-hyde theme, the Download button redirects us to its GitHub page.
We can then copy the HTTPS link for cloning and instead of cloning it directly in the themes
directory, we add it as a submodule in order to be able to fetch new changes and updates from the repo:
git submodule add https://github.com/htr3n/hyde-hyde.git themes/hyde-hyde
Update config file
Then, add the theme to the site configuration:
echo theme = \"hyde-hyde\" >> config.toml
Add a Post
We can manually create content files, that follow this format content/<CATEGORY>/<FILE>.<FORMAT>
, and give them metadata using the new
command:
hugo new posts/my-first-post.md
And add some content to the page using MarkDown:
echo "# My First Post \nThis is my first post." >> content/posts/my-first-post.md
Edit config file
Usually themes come with an exampleSite
directory that contains a basic example site and its config file. We can open it to configure the theme based on this:
cat themes/hyde-hyde/exampleSite/config.toml
or we can replace it completely as we have nothing important yet and we can select what configuration we want to keep:
cp themes/hyde-hyde/exampleSite/config.toml .
Add a Page
Create a page for the site, e.g. the About page:
hugo new about.md
And add some content to the page using MarkDown:
echo "# About \nThis is the about page." >> content/about.md
Configure the Menu
Configure themes (Style)
Create a new style.css
in the static
directory of the site, like:
vim static/style.css
and add any custom css rule you want from the theme, like:
body.dark-theme {
/* dark theme colors */
--background: #292a2d;
--header: #59114f;
}
this way we don’t have to build the theme.
Categorize Posts
Hugo has the feature of taxonomies that support two basic ones: tags, categories. We can use these 2 default ones, or we can create new taxonomies by defining them in the config.toml
file.
In order to populate the categories taxonomy, in every post’s front matter you add the following for yaml
front matter:
categories:
- Development
- Scripting
and for toml
front matter:
categories = ["Development", "Scripting"]
The next thing we need is a template that Hugo will use to display the /categories
page. We can place this template in the layouts/_default
directory and add a terms.html
template. Usually the themes provide one that we can use, so we can copy it:
mkdir layouts/_default
cp themes/hello-friend/layouts/_default/terms.html layouts/_default
Syntax Highlighter
Hugo uses Chroma
as the default syntax highlighter. In order to configure it we have to add this option to config.toml
:
pygmentsUseClasses=true
Then in order to generate a new style for Chroma
, we use the following command:
hugo gen chromastyles --style=monokai > style.css
we can find all the available styles at the Chroma Style Galler.
Create Social Icons Layout
We will create a new social media icon layout that is used by some themes. We will create a social-icons.html
template in layout/partials
:
mkdir layouts/partials
touch layouts/partials/social-icons.html
and we will add the following:
{{ range . -}}
<a
href="{{ .url | safeURL }}"
target="_blank"
rel="noopener me"
title="{{ .name | humanize }}"
style="margin-left:0.5em"
>{{ partial "svg.html" . }}</a
>
{{- end -}}
This template takes all the parameters from the main configuration file (config.toml
) and creates an svg list with the corresponding icon names in the layouts/partials/svg.html
file.
We can edit config.toml
in order to specify which social icons we want:
[params]
# ...
# Social Icons
[[params.social]]
name = "github"
url = "https://github.com/"
[[params.social]]
name = "twitter"
url = "https://twitter.com/"
[[params.social]]
name = "linkedin"
url = "https://www.linkedin.com/"
Then we will create the svg.html
template in layout/partials
, that will have all the svg icons based on the name of the social app:
touch layouts/partials/svg.html
and we will add the following:
{{- if (eq .name "codepen") -}}
<svg
xmlns="http://www.w3.org/2000/svg"
class="feather"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<polygon points="12 2 22 8.5 22 15.5 12 22 2 15.5 2 8.5 12 2"></polygon>
<line x1="12" y1="22" x2="12" y2="15.5"></line>
<polyline points="22 8.5 12 15.5 2 8.5"></polyline>
<polyline points="2 15.5 12 8.5 22 15.5"></polyline>
<line x1="12" y1="2" x2="12" y2="8.5"></line>
</svg>
{{- else if (eq .name "facebook") -}}
<svg
xmlns="http://www.w3.org/2000/svg"
class="feather"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<path
d="M18 2h-3a5 5 0 0 0-5 5v3H7v4h3v8h4v-8h3l1-4h-4V7a1 1 0 0 1 1-1h3z"
></path>
</svg>
{{- else if (eq .name "github") -}}
<!-- ... -->
Now we can use this template in another layout we want. We want to add a list of social media icons in our footer, so we copy the themes footer.html
template in layout/partials
:
cp themes/hello-friend/layouts/partials/footer.html layouts/partials
and we can add it anywhere we want like this:
{{- with .Site.Params.social }}
<div id="social-icons">{{ partialCached "social-icons.html" . }}</div>
{{- end }}
Create Social Icons Shortcode
If we want to use the same social media icons template in a specific page e.g. the About page, we can create a custom shortcode that has the same function as the social-icons.html
layout.
We will first create a new social media icon shortcode. We will create a social-shortcode.html
template in layout/shortcodes
:
mkdir shortcodes
touch layouts/shortcodes/social-shortcode.html
and we will add the following:
<div id="socials">
{{ range $.Page.Site.Params.social -}}
<a
href="{{ .url | safeURL }}"
target="_blank"
rel="noopener me"
title="{{ .name | humanize }}"
style="margin-left:0.5em"
>{{ partial "svg-large.html" . }}</a
>
{{- end -}}
</div>
It is the same function but we just wrap the link tags with a div
because we will use it directly in the Markdown content.
We will also create optionally a new svg.html
file that will have the same icons but with larger dimensions, so we create the svg-large.html
template in layout/partials
:
touch layouts/partials/svg-large.html
and we will add:
{{- if (eq .name "codepen") -}}
<svg
xmlns="http://www.w3.org/2000/svg"
class="feather"
width="56"
height="56"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<polygon points="12 2 22 8.5 22 15.5 12 22 2 15.5 2 8.5 12 2"></polygon>
<line x1="12" y1="22" x2="12" y2="15.5"></line>
<polyline points="22 8.5 12 15.5 2 8.5"></polyline>
<polyline points="2 15.5 12 8.5 22 15.5"></polyline>
<line x1="12" y1="2" x2="12" y2="8.5"></line>
</svg>
{{- else if (eq .name "facebook") -}}
<svg
xmlns="http://www.w3.org/2000/svg"
class="feather"
width="56"
height="56"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<path
d="M18 2h-3a5 5 0 0 0-5 5v3H7v4h3v8h4v-8h3l1-4h-4V7a1 1 0 0 1 1-1h3z"
></path>
</svg>
{{- else if (eq .name "github") -}}
<!-- ... -->
w we can use this template in any page we want. We want to add a list of social media icons in our About page, so we open:
vim content/about.md
and we can add the shortcode, using the name of the files without the .html
suffix: