HiveBrain v1.2.0
Get Started
← Back to all entries
snippetbashMinor

Generate a Jekyll blog post template using shell

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
templatejekyllshellpostgenerateusingblog

Problem

I'm creating my first Bash script newpost.sh, which generates a Markdown file containing the metadata for a new blog post. This blog post will be hosted in a Jekyll engine, like GitHub pages. The idea is to facilitate:

  • The generation of date



  • The conversion from the post title to URL



  • Compatible in both mac OS and Linux



So user can really focus on writing blog, instead of handling different metadata.

#!/bin/bash
#
#    This script creates a new blog post with metadata in ./_posts
#    folder. Date will be generated according to the current time in
#    the system. Usage:
#
#        ./newpost.sh "My Blog Post Title"
#

title=$1

if [ -z "$title" ]; then
    echo "usage: newpost.sh \"My New Blog\""
    exit 1
fi

bloghome=$(cd "$(dirname "$0")"; pwd)
url=$(echo "$title" | tr '[:upper:]' '[:lower:]' | tr ' ' '-')
filename="$(date +"%Y-%m-%d")-$url.md"
filepath=$bloghome/_posts/$filename

if [ -f filepath ]; then
    echo "$filepath already exists."
    exit 1
fi

touch $filepath

echo "---" >> $filepath
echo "layout:      post" >> $filepath
echo "title:       \"$title\"" >> $filepath
echo "date:        \"$(date +"%Y-%m-%d %H:%M:%S %z")\"" >> $filepath
echo "categories:  [weekly]" >> $filepath
echo "---" >> $filepath

echo "Blog created: $filepath"


Any feedback is welcome!

Solution

Overall, it is clear and well formatted. Here are some suggestions:

shellcheck.net

Firstly, I highly recommend running your scripts through shellcheck.net. This reveals:

  • Where you're using $filepath you should use "$filepath" in case part of the path contains spaces. Although shellcheck didn't catch it the assignment to filepath= should have quotes around the right side so it doesn't get broken up.



  • cd can fail and you should check the exit code, but in your case you're just using it inside of a subshell so it is probably fine as is.



double brackets

Using double brackets for conditionals in the shell is a good habit to get into. They won't surprise you when people leave variables empty, for instance. So

if [ -z "$title" ]; then


should be

if [[ -z "$title" ]]; then


bug

Where you check for the files existence you don't substitute the variable, you're checking for the existence of a file named filepath which probably never will be there. Replace:

if [ -f filepath ]; then


with

if [[ -f "$filepath" ]]; then


to get the desired result. I'm also using the quotes around the variable and double brackets previously mentioned.

heredocs

Instead of repeatedly appending to your file, why not do it in one fell swoop:

cat > "$filepath"
---
layout:      post
title:       "$title"
date:        "$(date +"%Y-%m-%d %H:%M:%S %z")"
categories:  [weekly]
---
EOF


That can replace your block of echos. Now you don't have to worry about escaping your double quotes and the template is clearly separated from the code. Heredocs also make it easier to edit the template within the script without messing up what the code is doing.

finally

Thanks for posting your shell script on codereview and trying to get better.

Code Snippets

if [ -z "$title" ]; then
if [[ -z "$title" ]]; then
if [ -f filepath ]; then
if [[ -f "$filepath" ]]; then
cat << EOF >> "$filepath"
---
layout:      post
title:       "$title"
date:        "$(date +"%Y-%m-%d %H:%M:%S %z")"
categories:  [weekly]
---
EOF

Context

StackExchange Code Review Q#158124, answer score: 2

Revisions (0)

No revisions yet.