Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Bash script to create new Jekyll posts
#!/bin/bash
# About: Bash script to create new Jekyll posts
# Author: @AamnahAkram
# URL: https://gist.github.com/aamnah/f89fca7906f66f6f6a12
# Description: This is a more advanced version of the script which can
# - take options
# - has color coded status messages
# - improved code
# - lowercase permalinks
# - usage message
# - opens file in Sublime Text after creation
# VARIABLES
######################################################
# COLORS
Color_Off='\033[0m' # Text Reset
# Regular Colors
Black='\033[0;30m' # Black
Red='\033[0;31m' # Red
Green='\033[0;32m' # Green
Yellow='\033[0;33m' # Yellow
Blue='\033[0;34m' # Blue
Purple='\033[0;35m' # Purple
Cyan='\033[0;36m' # Cyan
White='\033[0;37m' # White
jpost() {
# VARIABLES
###########
# Define the post directory (where to create the file)
JEKYLL_POSTS_DIR=$HOME'/Sandbox/jekyll/_posts/'
# Post title
# if more than one argument is provided then TITLE is the last argument
if [ $# -gt 1 ]; then
TITLE=${@: -1}
# if only one argument is provided then it is the Title
else
TITLE=$1
fi
# Replace spaces in title with underscores
TITLE_STRIPPED=${TITLE// /_}
# Permalink
PERMALINK=$(tr A-Z a-z <<< $TITLE_STRIPPED)
# Date
DATE=`date +%Y-%m-%d`
# Post Type (markdown, md, textile)
TYPE='.md'
# File name structure
FILENAME=${DATE}-${TITLE_STRIPPED}${TYPE}
# File path
FILEPATH=${JEKYLL_POSTS_DIR}${FILENAME}
# USAGE
###########
showUsage() {
echo "Usage: jpost -o \"This is my post\" "
}
# CREATE POST
#############
createPost() {
# create file
touch ${FILEPATH}
# add YAML front matter to the newly created file
echo -e "---
layout: post
title: ${TITLE}
permalink: ${PERMALINK}
---
" > ${FILEPATH}
# success message
echo -e "${Green}File was succesfully CREATED \n
${JEKYLL_POSTS_DIR}${FILENAME}${Color_Off}
"
}
# ARGUMENTS
###########
while getopts "o" opt; do
case $opt in
o) open=1 ;;
esac
done
# CONDITIONS
############
if [ $# -eq 0 ]; then
showUsage
else
# check if file alreday exists and is not empty
if [ -s ${FILEPATH} ]; then
echo -e "${Red}File already EXISTS and is NOT EMPTY${Color_Off}"
#check if file already exists
elif [ -e ${FILEPATH} ]; then
echo -e "${Yellow}File already EXISTS${Color_Off}"
# check for -o (open) argument
elif [ ! -z $open ]; then
createPost
# Open file in Sublime Text
open -a "Sublime Text" $FILEPATH
# if no file with the same name exists, proceed with creating a new one
else
createPost
fi
fi
}
#!/bin/bash
# About: Bash script to create new Jekyll posts
# Author: @AamnahAkram
# URL: https://gist.github.com/aamnah/f89fca7906f66f6f6a12
# Description: This is a very basic version of the script
# VARIABLES
######################################################
# Get current working directory
# Define the post directory (where to create the file)
JEKYLL_POSTS_DIR=$HOME'/Sandbox/jekyll/_posts/'
# Post title
TITLE=$1
# Replace spaces in title with underscores
TITLE_STRIPPED=${TITLE// /_}
# Permalink
PERMALINK=${TITLE_STRIPPED}
# Date
DATE=`date +%Y-%m-%d`
# Post Type (markdown, md, textile)
TYPE='.md'
# File name structure
FILENAME=${DATE}-${TITLE_STRIPPED}${TYPE}
# COMMANDS
#######################################################
# go to _posts directory
cd ${JEKYLL_POSTS_DIR}
# make a new post file
touch ${FILENAME}
# add YAML front matter
echo -e "
---
layout: post
title: ${TITLE}
permalink: ${PERMALINK}
---
" >> ${FILENAME}
}
@Alanthink
Copy link

Alanthink commented Mar 27, 2018

Thanks for writing this script. It is really useful.

I found two small problems.

First, it is more convenient to create a new post using the following sample command:

./command create a new file

So here, we have 4 input parameters. However, you only manipulate the first argument.

so a better way is to use the following script:

# Post title
TITLE=""

for var in "$@"
do
    TITLE=$TITLE" $var"
done

# Trim leading spaces
TITLE="$(echo "${TITLE}" | sed -e 's/^[ \t]*//')"

Second, the final file has a leading "\n". It is better to remove it.

I put the new scripts on my blog.

@langenhagen
Copy link

langenhagen commented Apr 7, 2020

Maybe something more compact, without colors and permalink tho:

#!/bin/bash
# Create a new jekyll post with the current date and the given title
# and print the path to the post file.
#
# author: andreasl

post_title="$*"
[ -z "$post_title" ] && printf 'Error: Script needs a post title.\n' && exit 1

repo_dir="$(git rev-parse --show-toplevel)"
post_date="$(date '+%Y-%m-%d')"
title_slug="$(printf -- "$post_title" | sed -E 's/[^a-zA-Z0-9]+/-/g' | tr "[:upper:]" "[:lower:]")"
post_path="${repo_dir}/_posts/${post_date}-${title_slug}.md"
[ -e "$post_path" ] && printf 'Error: Post exists already.\n' && exit 2

IFS= read -r -d '' front_matter << EOF
---
title: "${*}"
date: ${post_date}
tags: []
---
EOF

printf -- "${front_matter}" > "${post_path}"

printf -- '%s\n' "${post_path}"

@febs
Copy link

febs commented Oct 16, 2020

This one above is a tiny masterpiece. :-)

@jadia
Copy link

jadia commented May 16, 2021

Thanks man! This saved me a lot of time. :)

@sfsam
Copy link

sfsam commented Jul 10, 2021

Zsh FWIW...

#!/bin/zsh

# Create and edit a new Jekyll post
# Based on bash script by @AamnahAkram
# https://gist.github.com/aamnah/f89fca7906f66f6f6a12 
#
# Usage: ./new-post.sh "title of your new post"

POSTS_DIR='src/_posts/'
TITLE=$1
# Lowercase all characters in TITLE
TITLE_LOWERCASE=${TITLE:l}
# Uppercase first character of each word in TITLE
TITLE_UPPERCASE=${(C)TITLE}
# Replace spaces in TITLE_LOWERCASE with underscores
TITLE_STRIPPED=${TITLE_LOWERCASE// /_}
DATE=`date +%Y-%m-%d`
TYPE='.md'
FILENAME=${DATE}-${TITLE_STRIPPED}${TYPE}
cd ${POSTS_DIR}
cat > ${FILENAME} <<EOF
---
layout: post
title: ${TITLE_UPPERCASE}
---


EOF
mvim ${FILENAME}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment