Bash Script for Creating Hugo Posts in Academic

Helper script to automate the creation of a directory, front matter, etc.

My preferred tools for creating pages in Hugo using the Academic Theme are Atom and just plain old Bash. I found the steps to create a new post in Academic a little more irksome than it was strictly necessary, especially considering the odd directory structure that Academic prefers:

Creating posts is therefore a multi-step process that produces errors if not followed exactly:

  1. Create a directory (following requirements for a name that also serves as a URL path, so no spaces, no special characters)
  2. Create a subdirectory for assets
  3. Create an index.md file with the specific front matter that Academic requires
  4. Edit and modify index.md with the title, summary, time, etc.

Instead of all these steps, let’s simply do:

./new "Title of My Awesome New Post"

and have this script do all the work for us!

#!/bin/bash

# Simple bash file to create a new post per Hugo Academic's expected directory
# structure.  https://github.com/gcushen/hugo-academic is a theme for Hugo, a
# static site generator.  The expected structure for new posts is (relative to
# the root of the project):
#
# /posts/Long-Title-Name-of-Post/index.md <- the actual post
# /posts/Long-Title-Name-of-Post/assets/ <- directory where images, etc. go
#
# This script attempts to sanitize the user input, leaving behind alphanumeric
# characters and dashes.

## Usage
#
#  ./new "The Cool Title of My New Post"
#

## Planned Improvements
#
# - Interactively ask for various inputs
#   - title
#   - subtitle (blank if not supplied)
#   - summary (title if not supplied)
#   - author (show list of valid options)
#   - tags (show list of existing, option to create new)
#   - categories (show list of existing, option to create new)
#   - draft (default to true)
#   - projects (select one or more associated projects)
#
# Goal would still be to make the script as automatic and simple as possible.
# This is not meant to be a fully interactive interface for Hugo.

# Set the target directory for this script relative to its location
TARGETDIR="./content/post"

# Make sure user supplies a title
if [ -z "$1" ]; then
  echo 'You must supply a post title, e.g.'
  echo '  ./new "The Cool Title of My New Post"'
  exit 1
fi

# Sanitize the input (we need this for the pre-filled template)
TITLE=${1} # take the input as-is for the Title before sanitizing for directory name
SANIN=${1// /-} # replace spaces with dashes
SANIN=${SANIN//_/-} # replace underscores with dashes
SANIN=${SANIN//[^a-zA-Z0-9\-]/} # remove everything except alphanumeric or dash

# Pre-fill the new file with Hugo Academic theme Front Matter
# Academic: https://sourcethemes.com/academic/
# Hugo Front Matter: https://gohugo.io/content-management/front-matter/
ISOTIME=$(date -u +'%Y-%m-%dT%H:%M:%SZ')
PREFILLTPL="---
title: '${TITLE}'
subtitle: ''
summary: 
authors:
#- admin
tags:
#- Academic
categories:
#- Demo
date: \"${ISOTIME}\"
lastmod: \"${ISOTIME}\"
featured: false
draft: true

# Featured image
# To use, add an image named \`featured.jpg/png\` to your page's folder.
# Placement options: 1 = Full column width, 2 = Out-set, 3 = Screen-width
# Focal point options: Smart, Center, TopLeft, Top, TopRight, Left, Right, BottomLeft, Bottom, BottomRight
image:
  placement: 2
  caption: 'Image credit: [**Unsplash**](https://unsplash.com/photos/CpkOjOcXdUY)'
  focal_point: ""
  preview_only: false

# Projects (optional).
#   Associate this post with one or more of your projects.
#   Simply enter your project's folder or file name without extension.
#   E.g. \`projects = [\"internal-project\"]\` references \`content/project/deep-learning/index.md\`.
#   Otherwise, set \`projects = []\`.
projects: []
# NOTE: Remember to start with text, H1 is already added
---
"

# Before we create directories and files, double check they don't exist
if [[ ! -e "${TARGETDIR}/${SANIN}/" ]]; then
  mkdir -p "${TARGETDIR}/${SANIN}/assets/"
  touch "${TARGETDIR}/${SANIN}/index.md"
  echo "${PREFILLTPL}" >> "${TARGETDIR}/${SANIN}/index.md"
else
  echo "The directory ${TARGETDIR}/${SANIN}/ already exists!  Aborting."
  exit 1
fi

Put the script above in the root directory of your Hugo install (or wherever you prefer, just change the TARGETDIR value to match). I saved my script as new but the name is arbitrary.

  • Create text file new in Hugo root directory
  • Paste the script above into this file, save
  • Run chmod +x new to make the file executable
  • Run ./new "Name of My New Post" and watch the magic happen!
Technical Program Manager

The key to everything is mastery of your frame of mind. Everything is relative.

comments powered by Disqus