Automating Creating New Content in Hugo

I’ve been using Hugo for about 6 months now, and it’s been working really really well for me. But the one thing that’s been bugging me is how clumsy it is to create new posts.

For example, here’s the command line stuff that would have created this post:

cd ~/Documents/Blog/blog
hugo new posts/2020/2020-05-05-Automating-Creating-New-Content-in-Hugo.md

All posts are plaintext markdown files, organized in folders within a content directory. The Hugo application has a command line tool to create content - but, almost every single time, I need to look up the syntax so I don’t goof it up. It’s a trivial command, but the syntax doesn’t seem to stick in my brain for some reason. Did I goof up on the date format? Did I get a dash in the wrong place? Typo in the file path? Accidentally left a space in somewhere and it breaks?

Once the content file is created, Hugo hands it off to the really good Macdown app for editing. But the creation of the file itself is awkward.

So. I needed a quick break from reading about online exam proctoring… Some googling and trial-and-error later, I now have a simple shell script that reads the content types I’ve set up in my archetypes directory, lets me pick one of them, and prompts me for a title. It then generates the file and sticks it in the right directory, then opens up Macdown for editing.

Here’s the script. It’s likely very very kludgey, and I probably need to build some better sanitation on the title/filename. But it works well enough for my use now. I have it saved as “new content.command” on my laptop, so it’s double-clickable1.

#!/bin/sh

# cd into my Hugo directory for my blog. Change this to your own directory path.
cd ~/Documents/Blog/blog

# read the files in the archetypes directory, stripping the .md extension.
echo "type?"
types=$(ls -1 archetypes | sed -e 's/\.md$//')
i=1

# display the archetype selection list
for j in $types do echo "$i. $j" file[i]=$j
i=$((i+1)) done echo "Enter content type #" read input type=${file[$input]} echo$type

# what should we call it?
echo "title?"

# strip out spaces, replace with -s. (maybe needs more sanitation?)
title=${title//[ ]/-} # get date for filename prefix eg. 2020-05-05 postdate=$(date +"%Y-%m-%d")

# get year to keep things in an organized year directory within the content type
postyear=date +'%Y'

# tell hugo to take over. it will hand off to the configured editor when done.
hugo new $type/$postyear/$postdate-$title".md"

Running that command prompted me for the info:

Last login: Tue May  5 10:06:19 on ttys003
_____             ____    __  __               ____   ___ ____   ___
|_   _|   _  ___  | ___|  |  \/  | __ _ _   _  |___ \ / _ \___ \ / _ \
| || | | |/ _ \ |___ \  | |\/| |/ _ | | | |   __) | | | |__) | | | |
| || |_| |  __/  ___) | | |  | | (_| | |_| |  / __/| |_| / __/| |_| |
|_| \__,_|\___| |____/  |_|  |_|\__,_|\__, | |_____|\___/_____|\___/
|___/
_  ___     ___   __    ____  _   __  __ ____ _____
/ |/ _ \ _ / _ \ / /_ _| ___|/ | |  \/  |  _ \_   _|
| | | | (_) | | | '_ (_)___ \| | | |\/| | | | || |
| | |_| |_| |_| | (_) | ___) | | | |  | | |_| || |
|_|\___/(_)\___/ \___(_)____/|_| |_|  |_|____/ |_|

➜  ~ /Users/dnorman/Documents/Blog/new\ content.command ; exit;
type?
1. asides
2. default
3. page
4. phdnotes
5. photos
6. podcast
7. posts
8. reflections
Enter content type #
7
posts
title?
Automating creating new content in hugo
/Users/dnorman/Documents/Blog/blog/content/posts/2020/2020-05-05-Automating-creating-new-content-in-hugo.md created
Editing posts/2020/2020-05-05-Automating-creating-new-content-in-hugo.md with "macdown" ...

and created the file at the right location at:

~/Blog/blog/content/posts/2020/2020-05-05-Automating-creating-new-content-in-Hugo.md`

1. on macOS, the super helpful security stuff will break the double-clickableness of this .command file if I use BBEdit to edit it, so I use nano in Terminal to avoid flagging the file as insecure or dirty or whatever. ↩︎