Background
Creating new posts in Hugo is already pretty simple thanks to the post creation command, but it can help to remove even little bits of friction.
Two points of friction in the current process are:
- navigating to the project directory, and
- properly formatting the new file name by remembering to name the file with dashes (-) instead of spaces and including the .md file extension
In the same way that we simplified updating Hugo front matter with a Bash script, we can use a script to make post creation even simpler as well.
Building the script
We’ll build a script and address each of the friction points in turn.
Prerequisite knowledge
Since we’ll be building a Bash script, [a basic knowledge of Bash]((https://loopedline.com/post/bash-getting-started-working-with-the-shell/) and of automating Bash scripts is assumed.
Navigating to the project directory
We’ll start by addressing the step of navigating to the Hugo project directory.
For now, we’ll assume that the user will pass the properly-formatted name of the post to the script in the first parameter.
Because our Hugo project directory is not likely to change often we can assign it to a variable within a script and then use that variable to change the script’s active directory to the Hugo project directory. We then simply call the Hugo post creation command with the name of the file to be created (which we assume was passed when the command was invoked) and Hugo does the rest.
#!/bin/bash
# VARIABLES
directoryofhugoproject=/home/user/hugo-project-directory
new_post_name=$1
# MAIN program flow
cd $directoryofhugoproject
hugo new $new_post_name
That’s all it takes to automate away the first hurdle. Now we can create new Hugo posts from any directory.
Passing the article name as a string
Now we’ll address the second issue. We’d like the user to be able to type the desired filename with spaces instead of dashes and then use the script to automatically substitute the dashes for spaces. This can be accomplished with two changes.
#!/bin/bash
# VARIABLES
directoryofhugoproject=/home/user/hugo-project-directory
input_parameters=$@
# MAIN program flow
new_post_name=${input_parameters// /-}.md
cd $directoryofhugoproject
hugo new $new_post_name
To explain the altered lines:
input_parameters=$@
- As this StackOverflow answer and this one indicate, the special parameter $@
“expands to all command-line parameters separated by spaces.” In other words, this line takes all command-line parameters separated by spaces and assigns them to the input_parameters
variable.
new_post_name=${input_parameters// /-}.md
- As the answers in this StackOverflow question demonstrate, Shell Parameter Expansion of the form ${parameter/pattern/string} can be used to replace parts of a string. This form can appear a little confusing because “If pattern begins with ‘/’, all matches of pattern are replaced with string.” So, in the above line:
- the
input_parameters
variable = parameter /
(that is, a forward slash followed by a space) = pattern-
(that is, a dash) = string
This has the effect of replacing all the spaces of the string stored in the input_parameters
variable with dashes. Then the extension “.md” is appended to the end of the string. Finally, the result is stored in the variable new_post_name
.
Adding a subdirectory
In this particular application we’ll also assume we want to place our posts in a specific subdirectory automatically. We’ll do this with three changes.
#!/bin/bash
# VARIABLES
directoryofhugoproject=/home/user/hugo-project-directory
subdirectoryofcontent=article/
input_parameters=$@
# MAIN program flow
new_post_name=${input_parameters// /-}.md
new_post_path_and_name="$subdirectoryofcontent$new_post_name"
cd $directoryofhugoproject
hugo new $new_post_path_and_name
To explain the altered lines:
subdirectoryofcontent=article/
- Assign the subdirectory path to the subdirectoryofcontent variable.
new_post_path_and_name="$subdirectoryofcontent$new_post_name"
- Concatenate the contents of the subdirectoryofcontent and new_post_name variables and assign the result to the new_post_path_and_name variable.
hugo new $new_post_path_and_name
- Run the hugo new
command with the new new_post_path_and_name variable as the parameter.
Adding output
We’ll add some output to help the user understand the functioning of the script.
#!/bin/bash
# VARIABLES
directoryofhugoproject=/home/user/hugo-project-directory
subdirectoryofcontent=article/
input_parameters=$@
# MAIN program flow
echo
echo "Executing $BASH_SOURCE"
echo
new_post_name=${input_parameters// /-}.md
new_post_path_and_name="$subdirectoryofcontent$new_post_name"
echo "For input parameters: $input_parameters"
echo
echo "Creating file: $new_post_path_and_name"
echo "In the Hugo project directory: $directoryofhugoproject"
echo
cd $directoryofhugoproject
hugo new $new_post_path_and_name
The new lines won’t alter the basic functionality but might aid with comprehension and troubleshooting.
The completed script
Now we can create a new Hugo post by simply running the below script followed by the article name. The script will then add the dashes and .md extension and place the new file in the appropriate directory.
hugo-new.sh:
#!/bin/bash
# VARIABLES
directoryofhugoproject=/home/user/hugo-project-directory
subdirectoryofcontent=article/
input_parameters=$@
# MAIN program flow
echo
echo "Executing $BASH_SOURCE"
echo
new_post_name=${input_parameters// /-}.md
new_post_path_and_name="$subdirectoryofcontent$new_post_name"
echo "For input parameters: $input_parameters"
echo
echo "Creating file: $new_post_path_and_name"
echo "In the Hugo project directory: $directoryofhugoproject"
echo
cd $directoryofhugoproject
hugo new $new_post_path_and_name