Installing Hugo

If you’re running Debian or Ubuntu, you can just install the hugo package with apt. Check the link to determine exactly which version this will install - it varies based on Sass/SCSS support. I’ll be installing from source, which requires Go version 1.11+.

To install, it’s as simple as cloning the repository and installing it via Go.

git clone https://github.com/gohugoio/hugo.git
cd hugo
go install --tags extended

Creating a Site

To create a new site, use the command hugo new site <name>. I’ll create mine mirroring my domain: gingerbread.space.

Adding a Theme

I’ll add a theme as a git submodule. There are lots of themes available to use at https://themes.gohugo.io/, and I’ll use Shell.

To install, we need to initialize the new site folder as a git repository, clone the theme, and add the theme to the config.toml file.

cd house.gingerbread.space
git init
git submodule add https://github.com/panr/hugo-theme-terminal.git themes/terminal
echo theme = \"terminal\" >> config.toml

Basic Customization

The config.toml file will require variations based on the theme in use, so here’s an example of how to get started with the Shell theme.

baseURL = "https://gingerbread.space"
languageCode = "en-us"
theme = "terminal"
paginate = 5

[params]
    # dir name of your main content (default is `content/posts`).
    # the list of set content will show up on your index page (baseurl).
    contentTypeName = "blog"

    # ["orange", "blue", "red", "green", "pink"]
    themeColor = "blue"

    # if you set this to 0, only submenu trigger will be visible
    showMenuItems = 3

    # show selector to switch language
    showLanguageSelector = false

    # set theme to full screen width
    fullWidthTheme = false

    # center theme with default width
    centerTheme = true

    # if your resource directory contains an image called `cover.(jpg|png|webp)`,
    # then the file will be used as a cover automatically.
    # With this option you don't have to put the `cover` param in a front-matter.
    autoCover = false

    # set post to show the last updated
    # If you use git, you can set `enableGitInfo` to `true` and then post will automatically get the last updated
    showLastUpdated = true

    # set a custom favicon (default is a `themeColor` square)
    # favicon = "favicon.ico"

    # Provide a string as a prefix for the last update date. By default, it looks like this: 2020-xx-xx [Updated: 2020-xx-xx] :: Author
    # updatedDatePrefix = "Updated"

    # set all headings to their default size (depending on browser settings)
    # it's set to `true` by default
    # oneHeadingSize = false


[params.twitter]
    # set Twitter handles for Twitter cards
    # see https://developer.twitter.com/en/docs/tweets/optimize-with-cards/guides/getting-started#card-and-content-attribution
    # do not include @
    creator = "aidan-gbm"
    # site = ""

[languages]
    [languages.en]
        languageName = "English"
        title = "The Gingerbread House"
        subtitle = "A portfolio and collection of programming, hacking, and other random notes."
        owner = "theGingerbreadMan"
        keywords = ""
        copyright = ""
        menuMore = "Show more"
        readMore = "Read more"
        readOtherPosts = "Read other posts"
        newerPosts = "Newer posts"
        olderPosts = "Older posts"
        missingContentMessage = "Page not found..."
        missingBackButtonLabel = "Back to home page"

    [languages.en.params.logo]
        logoText = "theGingerbreadHouse"
        logoHomeLink = "/"

    [languages.en.menu]
        [[languages.en.menu.main]]
            identifier = "bio"
            name = "Bio"
            url = "/bio"

        [[languages.en.menu.main]]
            identifier = "blog"
            name = "Blog"
            url = "/blog"

        [[languages.en.menu.main]]
            identifier = "writeups"
            name = "Writeups"
            url = "/writeups"

Add Content

To create a new content page, I’ll use the hugo new <archetype>/<title>.md command. The following example will use the archetype file in archetypes/blog.md, or archetypes/default.md if that doesn’t exist.

hugo new blog/creating-a-hugo-site.md

Sections

I like splitting up different types of posts and articles by category. In Hugo you can use taxonomies, but to me those seem like extended tags. For my purposes, I’ll use sections. It’s super easy to set up - just create a new directory nested under the content directory and add an _index.md file. For example, my HackTheBox section is nested under content/writeups/htb/_index.md. All of the posts will just be markdown files in the htb directory, and I’ll use a super simple index template:

---
title: "CTFs"
---

This gives me the .Title variable to use in templates when working with a .Section variable. I’ll add some custom code to the layouts/_default/list.html template which will create a page at https://gingerbread.space/writeups that lists all available sub-sections.

<!-- Check if this page has any sub-sections -->
{{ if (eq (len $.Sections) 0) }}
    <!-- If there aren't any, make links for each post in this section -->
    {{ range .Paginator.Pages }}
    <div class="post on-list">
        <!-- Snip - Post Info -->
    </div>
    {{ end }}
{{ else }}
    <!-- If there are, list the sub-sections with links -->
    {{ range .Sections }}
    <div class="on-list">
        <h1 class="post-title">
            <a href="{{ .Permalink }}">{{ .Title | markdownify }}</a>
        </h1>
    </div>
    {{ end }}
{{ end }}

Deploying the Site

The hugo server command will run the server on http://localhost:1313/. The following flags modify build options:

  • -D include content marked as draft
  • -F include content with publishdate in the future
  • -t theme to use (from /themes/NAME/)

Running hugo without the server parameter will output files to the ./public/ directory unless otherwise specified by the -d flag.