Hugo Elliott

| website | hugo | Est reading time: 7 mins

Photo by Lanty at Unsplash

How to create a layout for individual blog pages for your static Hugo website

In our previous post we learnt how to set up a Hugo website and added a homepage. In this post we’ll create a layout for each individual blog post.

1. Housekeeping - Meta Data

Firstly a bit of housekeeping.

What we’re going to do is update the template for the meta data in each page in your blog. This means that when we write each blog post, we have a framework for the meta data ready to be filled out.

  • Delete the file project/archetypes/default.md
  • Create the file project/new-theme/archetypes/default.md

where new-theme is the name of your theme

Open and edit project/theme/archetypes/default.md adding

---
title: "{{ replace .Name "-" " " | title }}"
description: ""
date: {{ .Date }}
draft: false
authorName: ""
authorImageUrl: ""
featuredImageType: ""
featuredImageUrl: ""
featuredImageAltText: ""
featuredImageAttribute: ""
featuredImageAttributeUrl: ""
featuredImageOrganisation: ""
featuredImageOrganisationUrl: ""
tags: []
categories: []
---

This code adds new variables to your front matter. We’ll be using these later.

Some comments on the code above

a) Author Details - multi author support

  • This is also a very simple way of adding multi-author support to a blog
  • By adding author details in the front matter, I can easily change the details depending on who wrote the post
  • I could add the details of an author in the default.md so the markdown file is pre-populated

b) Featured image

  • I’m going to build a partial template (below) so that each post can have a featured image
  • The information for the featured image are be defined in the front matter

2. More Housekeeping - Updating the Navbar

Open and edit config.toml and add

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

This new menu parameter create a link in the navbar to the blog

3. Add a Single Page Layout

Currently the Hugo doesn’t know how to display a single blog post.

Create and edit layouts/blog/single.html adding

{{ define "main" }}
    <div class="container pt-3 pl-1 pr-1 pb-3">
        <h1 class="title">{{ .Title }}</h1>
        <div class="columns is-mobile">
            <div class="column is-narrow">
                <figure class="image is-48x48">
                    <img class="is-rounded" src="{{ .Params.authorimageurl }}" alt="{{ .Params.author }}">
                </figure>
            </div>
            <div class="column">
                <p class=""><strong>{{ .Params.authorname }}</strong></p>
                <p class="">
                    <!-- Place holder for Date and Tags -->
                </p>
            </div>
        </div>
        <!-- Place holder for a Featured Image -->
        <div class="content has-text-grey-darker mb-3">
            {{ .Content }}
        </div>
    </div>
{{ end }}

I’ve added a place holders for

  1. ‘Date and Tags’ that will appear below the author name, and a
  2. ‘Featured Image`

Now Hugo knows how to display a single blog post.x

4. Create a List Layout

At the moment Hugo doesn’t know how to display a list of blog posts.

Create and edit layouts/_default/list.html adding

{{ define "main" }}
    <div class="container">
        <div class="section">
            <div class="content">
                <h1>{{ .Title }}</h1>
                {{ .Content }}
                <ul>
                    {{ range .Pages }}
                    <li>
                        <a href="{{ .Permalink }}">{{ .Title }}</a>
                    </li>
                    {{ end }}
                </ul>
            </div>
        </div>
    </div>
{{ end }}

This template is in the /_defaults/ directory.

If there are no no other applicable templates Hugo will use this one to display a list.

Now navigate to http://localhost:1313/blog and the list page works but without any content, because we’ve not created any.

Hugo has done something clever and pluralised the title.

To get replace ‘Blogs’ with ‘Blog’ create and edit [project]/content/blog/new _index.md page.

hugo new blog/_index.md

I like to use Unsplash as the source of images for my blog. Where possible, I prefer to link to an image rather than download them.

To do this you need to create a Partial Template.

Create and edit layouts/partials/widgets/featuredimage.html adding

{{ $featuredImageType := .Params.featuredImageType }}
{{ $featuredImageUrl := .Params.featuredImageUrl }}
{{ $featuredImageAltText := .Params.featuredImageAltText }}
{{ $featuredImageAttribute := .Params.featuredImageAttribute }}
{{ $featuredImageAttributeUrl := .Params.featuredImageAttributeUrl }}
{{ $featuredImageOrganisation := .Params.featuredImageOrganisation }}
{{ $featuredImageOrganisationUrl := .Params.featuredImageOrganisationUrl }}

<div class="mb-1">
    <figure class="image is-5by3 featured-img">
        <img class="is-fluid" src="{{ $featuredImageUrl }}" alt="{{ $featuredImageAltText }}">
    </figure>
    <p class="is-size-7-mobile is-size-6-tablet mb-3">{{ $featuredImageType }} by <a href="{{ $featuredImageAttributeUrl }}" target="_blank">{{ $featuredImageAttribute }}</a> at <a href="{{$featuredImageOrganisationUrl}}" target="_blank">{{ $featuredImageOrganisation }}</a></p>
</div>

Open and edit layouts/blog/single.html and add {{ partial "widgets/featuredimage.html" . }}.

This will pull code for the featured image into the single page layout.

{{ define "main" }}
    <div class="container">
        ...
        {{ partial "widgets/featuredimage.html" . }}
        <div class="content has-text-grey-darker mb-3">
            {{ .Content }}
        </div>
        ...
    </div>
{{ end }}

6. Adding dates and tags to the blog post

I want to change the way the date and tags for each post are displayed on each blog post. I also want to add some code that can be reused on other pages. So we’re going to use a partial template.

Create and edit layouts/partials/widgets/dateandtags.html, and add to it

{{ $dateTime := .PublishDate.Format "01-Jan-06" }}
{{ $dateFormat := .Site.Params.dateFormat | default "01-Jan-06" }}
<i class="fas fa-calendar"></i> <time datetime="{{ $dateTime }}">{{ .PublishDate.Format $dateFormat }}</time>
| {{ with .Params.tags }}
    {{ range . }}
        <i class="fas fa-tag"></i>
        {{ $href := print (absURL "tags/") (urlize .) }}
        <a href="{{ $href }}">{{ . }}</a> |
    {{ end }}
{{ end }}
Est reading time: {{ .ReadingTime }} {{ if eq .ReadingTime 1 }} minute {{ else }} mins {{ end }}

Now update layouts/blog/single.html to reference the dateandtags.html partial

{{ define "main" }}
    <div class="container pt-3 pl-1 pr-1 pb-3">
        <h1 class="title">{{ .Params.author }}</h1>
        <div class="columns is-mobile">
            <div class="column is-narrow">
                <figure class="image is-48x48">
                    <img class="is-rounded" src="{{ .Params.authorImageUrl }}" alt="{{ .Params.author }}">
                </figure>
            </div>
            <div class="column">
                <p class=""><strong>{{ .Params.authorName }}</strong></p>
                {{ partial "widgets/dateandtags.html" . }}
            </div>
        </div>
        ...
    </div>
{{ end }}

The dateandtags.html partial code adds below the author name, the

  • Date published
  • Each tag, and
  • The estimated reading time

7. Create Your First Blog Post

Stop the server and in the terminal run

hugo new blog/flowers.md

Open and edit the file copying in the text below.

---
title: "Flowers"
description: "A blog page about flowers"
date: 2020-12-12T22:59:53+01:00
draft: false
url: ""
authorName: "Albert Laighton"
authorImageUrl: "https://ap-pics2.gotpoem.com/ap-pics/user/4918/471big.jpg?AlbertLaightonjpg6"
featuredImageType: "Photo"
featuredImageUrl: "https://source.unsplash.com/7pGehyH7o64"
featuredImageAltText: "Flowers in a jug"
featuredImageAttribute: "Leonardo Wong"
featuredImageAttributeUrl: "https://unsplash.com/@nardoleo"
featuredImageOrganisation: "Unsplash"
tags: ['poem','flowers']
categories: ['blog']
---

# Flowers

[Albert Laighton](https://mypoeticside.com/poets/albert-laighton-poems) was a 19th century American poet.

> They are autographs of angels, penned\
> In Nature’s green-leaved book, in blended tints,\
> Borrowed from rainbows and the sunset skies,\
> And written everywhere–on plain and hill,\
> In lonely dells, ‘mid crowded haunts of men;\
> On the broad prairies, where no eye save God’s\
> May read their silent, sacred mysteries. Thank God for flowers!\
> They gladden human hearts; Seraphic breathings part their fragrant lips\
> With whisperings of Heaven.

Source: [https://www.weleoveflorists.com](https://www.weloveflorists.com/2020/05/14/top-5-most-beautiful-flower-poems/)

Restart the server using

hugo server

Navigate to your homepage, click on the ‘Blog’ link in the nav bar. Cick through to the post. It should look like this

First post

7. Add a Favicon

The favicon is the little 16px x 16px image the appears in the tab in your webrowser. You can generate and export a simple logo using Canva. Go to realfavicongenerator.net and follow the instructions to generate your Favicon. You will upload the logo generated on Canva and download a zip file with all the favicon assets.

The images for the Favicon should be stored in static/images/favicon.

If you follow the instructions you will be given code to insert into the section of the pages.

Open and edit themes/new-theme/layout/partials/head.html and add

<!-- Favicon -->
<!-- https://realfavicongenerator.net/ -->
<link rel="apple-touch-icon" sizes="180x180" href="{{ absURL `images/favicon/apple-touch-icon.png` }}">
<link rel="icon" type="image/png" sizes="32x32" href="{{ absURL `images/favicon/apple-touch-icon.png` }}">
<link rel="icon" type="image/png" sizes="16x16" href="{{ absURL `images/favicon/favicon-16x16.png` }}">
<link rel="manifest" href="{{ absURL `images/favicon/site.webmanifest` }}">
<link rel="mask-icon" href="{{ absURL `images/favicon/safari-pinned-tab.svg` }}" color="#317aff">
<meta name="msapplication-TileColor" content="#317aff">
<meta name="theme-color" content="#ffffff">

Please note I’ve updated the link in the href to link to the image/favion folder, and you’ll need to check that the penultimate line in your code contains the correct hex code.

I’m very grateful that other developers blog about code.

The sources for these posts on Hugo that I’ve read, and which I’ve used to build my website

If you'd like help with a project, please click below

.