Creating Hugo and Netlify Powered Website From Scratch - Part 3 - Displaying Content

2018-01-17

In the first part I’ve shown how to bootstrap hello world for Hugo website. After that in previous the post I’ve shown the process of deploying that website to live. Since we now have both parts done and the website is up and running it’s time to add some content there.

Hugo Structure

I’ve shown a creation of basic Hugo site and fresh theme. Default structure for these two will look something like this:

.
├── archetypes
│   └── default.md
├── config.toml
├── content
├── data
├── layouts
├── static
└── themes
    └──mega-T                   # Or your theme name
        ├── LICENSE.md
        ├── archetypes
        │   └── default.md
        ├── layouts
        │   ├── 404.html
        │   ├── _default
        │   │   ├── list.html   # Listing posts
        │   │   └── single.html # Single post
        │   ├── index.html      # Home page
        │   └── partials        # These will keep our templates DRY
        │       ├── footer.html
        │       └── header.html
        ├── static
        │   ├── css
        │   └── js
        └── theme.toml

While I’ll be talking mainly about creating blog and blog posts in here, same rules apply for all sort of content. It’s up to yourself how to name it. It can be anything you’d like, sections, recipes, portfolios and so on. The main idea here is that accessing our baseURL will load the template from layouts/index.html which is our homepage. What we need to do now is create some content. This either can be done manually (not advising that though) or we can run:

$ hugo new post/my-first-post.md

This will create a new folder and markdown file in /content folder. The idea here is similar to any other static site generator. And markdown will be similar to anyone ever tried the GitHub docs. To see the website live:

$ hugo -D server

But since our theme is still empty trying to access the newly created post will return 404.

Creating single page template for post

If you are like me (and any other human being) you are addicted to instant gratification. So to fulfil that hunger I’m going to start with a template for the post itself. Let’s add a little bit of content first to the content/post/my-first-post.md Under the header simply type in some content we want to see on the page.

---
title: "My First Post"
date: 2018-01-13T14:50:10Z
draft: false # set to false, so that netlify compiles it
---
## Intro
Hello to my blog. This is my first post!!!

Now with content in place, we can start the template. First, we will reuse the previously created header and footer. Open up themes/<your-theme-name>/layouts/_default/single.html and add:

{{ partial "header" . }}
    <h1>{{ .Title }}</h1>
    {{ .Content }}
{{ partial "footer" . }}

The variables are self-explanatory here. Hugo magic will pick them up and add the needed values from our markdown. Now visit http://localhost:1313/post/my-first-post and enjoy the achievement. There are some gotchas here. If you started your server before modifying the template you might need to restart it. Same goes for any template edit. If you feel that changes are not applied - restart. Another place to trip down here is to forget the -D flag while launching the server. By default any new content will be in a draft state, -D makes sure they are rendered out locally.

Listing available posts

Now that we saw something on the screen we need to make sure we can see the list of the posts available. Wouldn’t expect our website users to just guess your post name URL’s, wouldn’t we? Wouldn’t it be nice to just list them somehow? Guess what we can. As we’ve seen before single.html is responsible for showing the single content, so it’s quite obvious what the list.html does. Idea is that URL’s mimic the directory structure and the folders will try to load list.html allowing us to display the list of content we have there. Open the themes/<your-theme-name>/layouts/_default/list.html and do the similar thing to the single.html, reuse the header and footer. We will also create a list of links:

{{ partial "header" . }}
    {{ range .Pages }}
        <li>
            <a href="{{ .URL }}">{{ .Title }}</a>
        </li>
    {{ end }}
{{ partial "footer" . }}

In here we are accessing one of the Hugo provided template variables .Pages. Then using Golang template iteration to loop through the pages available in the current content directory. Computer science 101 here. Now if you go to http://localhost:1313/post you’ll see a simple list of links.

Creating navbar

While we can navigate the website with URL’s having navigation bar is super handy as well. There are few different ways to achieve it in Hugo. I’ll stick with the Lazy Blogger approach. The first step is to add this to your config.toml:

sectionPagesMenu = "main"

We can name it anything we want, but "main" will do. Since the project is not too big we can place the menu in our /themes/<your-theme-name>/layouts/partials/header.html. Add:

....
  <body>
    <header>
      <nav>
        <a href="/">Home</a>
        {{ range .Site.Menus.main }}
          <a href="{{.URL}}">{{ .Name }}</a>
        {{ end }}
      </nav>
    </header>

Now going to the http://localhost:1313/ will show the list of links at the top. Try navigating around and it should stay there.

What’s next?

That’s pretty much all you need to create the website! Just commit and push to the GitHub again. And let Netlify handle the rest! While we have the main functionality working you might want to make some changes to CSS and markup to feel yours. Also, I suggest looking at Hugo docs for variables and other bits and pieces. And getting a quick look into Golang Templates will help you if needed.

While I am a terminal addict and like editing and writing in my source code that might not always be the case. Sometimes for lazy evenings, I’d like to have GUI. And guess what? Netlify provides you with headless CMS which takes just a couple of lines to integrate. That’s what I’m planning on showing next in these series.