Published 2020-08-16.
Last modified 2023-08-12.
Time to read: 1 minutes.
jekyll
collection.
I use Jekyll to build this website.
Some material is published as articles, some as articles.
I wrote a script called newPost
that creates a new draft article with SEO considerations.
SEO rankings are improved when the description and title tag are neither too long nor too short.
There is a Visual Studio Code plugin called
jekyll-post
which is pretty good.
I found it a year after originally writing this article.
Sample Usage
Here is an example of how I used it on 2020-08-16:
$ _bin/newPost
Post Title (30-60 characters):
______________________________123456789012345678901234567890
This is a test of newPost for the greater good
46 characters, excellent!
Publication date: 2020-08-16
Post Description (30-60 characters):
____________________________________________________________123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
I wish newPost used some sort of web service to generate an SEO-optimized description
85 characters, excellent!
Post Categories (comma delimited):
Post Tags (comma delimited):
Post Keywords (comma delimited): Goofiness, Silliness
Banner image (bg_ .jpg):
For the above example the generated file is called _drafts/2020-08-16-this-is-a-test-of-newpost-for-the-greater-good.html
.
When you are happy with the new posting, move it from _drafts
to _posts
like this:
$ mv _drafts/2020-08-16-new-jekyll-post.html _posts/
Generated Posting
Here is the generated file:
--- categories: [] description: I wish newPost used some sort of web service to generate an SEO-optimized description headerImage: keywords: [Goofiness, Silliness] last_modified_at: 2020-08-16 layout: blog title: This is a test of newPost for the greater good tags: [] ---
Error Handling
The script checks the length of the title and the posting description for SEO purposes.
If either of these are too long or too short, the script allows the user to edit their input over and over until they get it right.
For example, here you can see that at first the user just types in xx
for the title,
then they provide a string that is too long, then they edit it until it has an acceptable length:
$ _bin/newPost
Post Title (30-60 characters):
______________________________123456789012345678901234567890
xx
28 characters too short, please edit
Post Title (30-60 characters):
______________________________123456789012345678901234567890
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
14 characters too long, please edit
Post Title (30-60 characters):
______________________________:123456789012345678901234567890
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
59 characters, excellent!
Source Code
This is the source code for the newPost
bash script.
#!/bin/bash # This bash script will setup a new HTML Jekyll draft blog post and open it for editing in Notepad++ # # See https://www.mslinn.com/blog/2020/08/16/new-jekyll-post.html # # Copyright Original by Katie Harron - @pibby from https://gist.github.com/pibby/6911493 # Copyright 2020 Modified by Mike Slinn - mslinn@mslinn.com # - added length checks for title and description # - added reprompt for when length check fails # - launch notepad instead of Mac editor # - modified front matter # - Added optional date as command line parameter # - Added date modification dialog # # SPDX-License-Identifier: Apache-2.0 DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )/.." cd "$DIR" function checkLength { # $1 - minimum length # $2 - maximum length # $3 - string to test length=${#3} if (( length < $1 )); then >&2 echo "$(($1 - $length)) characters too short, please edit" return 1 elif (( length > $2 )); then >&2 echo "$(( $length - $2 )) characters too long, please edit" return 2 else >&2 echo "$length characters, excellent!" return 0 fi } function edit { if [ `which notepad` ]; then notepad "$filename" # Invokes mslinn's notepad++ script elif [ `which gedit` ]; then `which gedit` "$filename" else echo "No editor defined, please edit '$filename' somehow" exit 1 fi } function emit_array { if [ "$2" ]; then echo "$1: [$2]\n" else echo -n "" fi } function emit_scalar { if [ "$2" ]; then echo "$1: $2\n" else echo -n "" fi } function reprompt { # $1 - name of front matter variable # $2 - minimum length of user-provided value # $3 - maximum length of user-provided value if [ -z "$1" ]; then 2> echo "Error: no front matter variable provided"; exit 1; fi if [ -z "$2" ]; then 2> echo "Error: no minimum length provided"; exit 1; fi if [ -z "$3" ]; then 2> echo "Error: no maximum length provided"; exit 1; fi NAME="$1" MIN="$2" MAX="$3" LEADIN="'_%0.s'" SPACES="$( eval $(echo printf "$LEADIN" {1..$MIN}) )" (( COUNT= (($MAX * 10) - ($MIN * 10) + 5) / 10 )) NUMBERS="$( eval $(echo printf '"0123456789%0.s"' {1..$COUNT}) )" (( CHARS= $MAX - $MIN )) VALUE="" #>&2 printf "SPACES='$SPACES'\n" #>&2 printf "NUMBERS='$NUMBERS'\n" while : do >&2 printf "Post $1 (30-60 characters):\n$SPACES${NUMBERS:1:$CHARS}\n" read -e -i "$VALUE" VALUE if $(checkLength "$MIN" "$MAX" "$VALUE"); then break; fi done >&2 echo echo "$VALUE" } # Set cwd to project root GIT_ROOT="$( git rev-parse --show-toplevel )" cd "${GIT_ROOT}" if [ ! -f _bin/loadConfigEnvVars ]; then echo -e "Error: _bin/loadConfigEnvVars was not found.\ncd \$msp" exit 1 fi source _bin/loadConfigEnvVars title="$( reprompt Title 30 60 )" ptitle=${title// /-} # convert spaces in title to hyphens # Convert title to lowercase and remove slashes plc="$( echo "$ptitle" | tr '[:upper:]' '[:lower:]' | tr -d '[/,]' )" >&2 printf "Filename slug (without date or filetype): " read -e -i "$plc" plc if [ "$1" ]; then pdate="$1" # TODO verify $1 is YYYY-mm-dd else pdate="$( date +%Y-%m-%d )" # create date as YYYY-mm-dd fi read -p 'Publication date: ' -e -i "$pdate" pdate filename=_drafts/$pdate-$plc.html # location to create the new file as year-month-day-title.md mkdir -p _drafts touch "$filename" # create the new blank post desc="$( reprompt Description 60 150 )" printf "Post CSS (comma delimited): "; read css printf "Post Categories (comma delimited): "; read categories printf "Post Tags (comma delimited): "; read tags #printf "Post Keywords (comma delimited): "; read keyw printf "Banner image (.png & .webp): "; read img printf "Enable code example clipboard icon (Y/n): "; read clipboard if [[ ! "$clipboard" =~ ^(n|N).* ]]; then javascriptEnd="/assets/js/clipboard.min.js" javascriptInline="new ClipboardJS('.copyBtn');" fi contents="---\n" contents="$contents$( emit_array css "$css" )" contents="$contents$( emit_array categories "$categories" )" contents="$contents$( emit_scalar description "$desc" )" contents="$contents$( emit_scalar image "$img" )" contents="$contents$( emit_scalar javascript "$javascript" )" contents="$contents$( emit_scalar javascriptEnd "$javascriptEnd" )" contents="$contents$( emit_scalar javascriptInline "$javascriptInline" )" #contents="$contents$( emit_array keywords "$keyw" )" contents="$contents$( emit_scalar last_modified_at "$pdate" )" contents="$contents$( emit_scalar layout blog )" contents="$contents$( emit_array tags "$tags" )" contents="$contents$( emit_scalar title "$title" )" contents="$contents---\n" echo -e "$contents" | sed '/^$/d' > "$filename" # fill out YAML Front Matter and insert into the new file echo "Created '$filename'" #edit printf "Use mem to append code examples to this post (y/N): "; read clipboard if [[ "$clipboard" =~ ^(y|Y).* ]]; then ps ax | grep '[j]ekyll' | awk -F ' ' '{print $1}' | xargs sudo kill -15 _bin/mem "$filename" & _bin/serve -c fi