In this post, I will go over how you can use Hugo’s archetypes to quickly create new posts. I have previously used NetlifyCMS to help create new posts, but recently I have found that to be a bit overkill for my blog.
So I decided to simplify my workflow by using Hugo’s archetypes 1. Archetypes allow us to create templates markdown files, which is then used to create our blog posts.
Archetypes
First, let’s create a new archetype we will call post-bundle
Create a new folder at the root of your project called archetypes
(i.e. mkdir archetypes
).
Then inside the archetype
folder, create a structure that looks like this.
├── post-bundle
│ ├── images
│ └── index.md
Page Bundles
We will be using a page bundle, so we keep all the content related to our post in a single folder, like the images 2.
All we need to do is create an index.md
which will contain the content we show on our Hugo site.
index.md
Our index.md
file will look something like this:
---
title: {{ slicestr (replace .Name "-" " ") 11 | title }}
date: {{ dateFormat "2006-01-02" .Date }}
canonicalURL: https://haseebmajid.dev/posts/{{.Name}}
tags: []
---
Let’s break this file down:
title: {{ slicestr (replace .Name "-" " ") 11 | title }}
Here we are using go tempting to take a variable .Name
. For example if
.Name = 2023-03-20--how-to-create-new-posts-on-hugo-using-archetypes-
title: How to Create New Posts on Hugo Using Archetypes
You can see we strip the first 11
characters to strip the date of the title.
Then we move all -
hyphens and replace them with blank spaces. Finally, we convert
it to a “title” case which will capitalize certain words such as Hugo
and New
but not on
.
Next, we have:
date: {{ dateFormat "2006-01-02" .Date }}
This is just formatting the date to the format we want, in my case I want the date to be YYYY-MM-DD
3.
Post
Now that we have a template, let’s look at how we can create a new post. We will use a script to create new posts.
Let’s create a new script at script/add
:
#!/usr/bin/env bash
TITLE=${1:-}
TITLE_SLUG="$(echo -n "$TITLE" | sed -e 's/[^[:alnum:]]/-/g' | tr -s '-' | tr A-Z a-z)"
DATE="$(date +"%F")"
SLUG="$DATE-$TITLE_SLUG"
git checkout -b "$SLUG"
hugo new --kind post-bundle posts/$SLUG
This script takes a title as input and then converts it into a string we can use as the folder name and this
will be the .Name
variable. For example scripts/add "How to Create New Posts on Hugo using Archetypes"
will become 2023-03-18--how-to-create-new-posts-on-hugo-using-archetypes-
.
The script assumes you have a folder called content/posts
where all of your posts are stored.
I have all of my blog posts in content/posts
, and then I have another folder for my talks at content/talks
.
In my case, I use go-task
4 which can be used as a Makefile alternative. I have the following entry in my
Taskfile.yml
which looks like:
new_post:
cmds:
- scripts/add "{{.CLI_ARGS}}"
Finally, I can do something like this; task new_post -- "How to Create New Posts on Hugo using Archetypes"
.
This creates a new bundle at content/posts/2023-03-18--how-to-create-new-posts-on-hugo-using-archetypes-
.
With a new index.md
, which looks like:
---
title: How to Create New Posts on Hugo Using Archetypes
date: 2023-03-18
canonicalURL: https://haseebmajid.dev/posts/2023-03-18--how-to-create-new-posts-on-hugo-using-archetypes-
tags: []
---