Managing Site Content with Sub
No self respecting developer will tolerate writing out the same commands over and over.
With Jekyll building the static files, I needed a way to:
- create draft posts
- serve drafts via localhost to review
- publish a draft as a full post
- build the site
- deploy to DigitalOcean
After manually running shell commands and manually editing files, I had to automate the workflow.
I use sub to organize the various scripts that handle each part of the process.
Create Draft Posts
First step was to create a template.md
file with all the optional
Front Matter a post might need.
---
title:
# # Rest are optional
# categories:
# tags:
# permalink:
# excerpt: # Markdown description before the story
# description: # SEO `<meta>` description (requires an `excerpt`)
# header:
# image: # Path to the full image for the size (1280x...)
# image_description: # Custom `alt` tag
# caption: # Photo credit (can be written in markdown)
# teaser: # Path to teaser image (roughly 500x300)
#
# # Hero video image
# video:
# id:
# provider:
#
# # An image with text overlay and call to action button
# overlay_image: # Path to the full image size
# overlay_filter: 0.5 # opacity between 0.0 and 1.0 (or full `rgba(255, 0, 0, 0.5)`)
# cta_label: # Call to action button label
# cta_url: # URL the call to action button goes to
# overlay_color: # Can be used rather than `overlay_image` as #ccc
#
# NOTE: https://mmistakes.github.io/minimal-mistakes/docs/helpers/
# https://mmistakes.github.io/minimal-mistakes/docs/utility-classes/
---
You’ll notice that only title
is required. Everything is commented out.
Also, there’s no date
attribute since this is a draft.
When I begin writing a draft I run:
site draft whatever-the-post-slug-will-be
which runs:
#!/bin/sh
set -u
set -e
cp _drafts/template.md _drafts/${1}.md
exec $EDITOR _drafts/${1}.md
A simple script to copy the template into the _drafts/
folder with the slug
name and then fire up my editor (NeoVim.)
Previewing Drafts on Localhost
Jekyll can preview drafts on the localhost. I run:
site serve
which executes:
#!/bin/sh
set -x
set -e
jekyll serve -D --watch
in a separate tmux pane. Jekyll is configured to watch for changes and rebuild the draft for preview.
Publishing
Once I’m happy with a draft it’s time to publish it (meaning promoting it from
_drafts/
into _posts/
.)
site publish whatever-the-post-slug-will-be
Which runs:
#! /usr/bin/env ruby
#
# Copy the file from the drafts folder, add the current date, and update the
# filename. Remove any commented out lines from the front matter.
#
now = Time.now
draft = File.basename(ARGV[0], '.md')
draft_filename = File.join('_drafts', "#{draft_filename}.md")
post_filename = File.join('_posts', "#{now.strftime('%Y-%m-%d')}-#{draft}.md")
post = File.open(post_filename, 'w')
state = :start
open(draft_filename).readlines.each do |line|
if (state == :start || state == :in_front_matter) && line =~ /^---/
post.puts line
if state == :start
post.puts "date: #{now.strftime('%Y-%m-%d %H:%M:%S %:z')}"
state = :in_front_matter
else
state = :body
end
elsif state == :in_front_matter && (line =~ /^#/ || line =~ /^\s$/)
# Skip all the comment lines in the front matter
next
else
post.puts line
end
end
post.close
File.unlink(draft_filename) if File.exist?(post_filename)
This Ruby script:
- Adds the current
date
attribute to the Front Matter - Removes all the commented out lines in the Front Matter
- Moves the file from the
_drafts
folder to the_posts
folder and prefixes the current date to the file.
Deploy Updates to Production
With everything ready, it’s time to deploy the changes to the [site]({{ .Site.BaseURL }}). One last script:
site deploy
running:
#!/bin/sh
$_SITE_ROOT/bin/site build
rsync -crvz --delete-after --delete-excluded _site/ wormbytes:/var/www/wormbytes.ca/
First we build the site:
#!/bin/sh
set -u
set -e
jekyll build
and then copy the _site/
directory up to the DigitalOcean production
server, deleting any files that have been removed and updating any new files.