The problem
Static site generators are great. But so are blog posts that automatically
appear on schedule. How do we reconcile the two? There are
solutions involving checking for updates on a schedule like
every hour or every day, but that seems unsatisfying: if the posts have already
been written, the blog should only need to be regenerated exactly when there
is new content to publish.
The solution
(These instructions are specifically for Pelican as that is what
this blog uses, a similar method should work for other static blogging
engines.)
Use Pelican's WITH_FUTURE_DATES
setting to
make future dated posts not appear as part of the blog, but only as
drafts
. Add the following to the article template in order to
include the future publication dates in an easy to parse format:
{% if article.status == "draft" %}
<!-- Post at datetime {{ article.date|strftime("%H:%M %Y-%m-%d") }} -->
{% endif %}
Then the following script schedule_publish.sh
uses those comments to
schedule rerunning itself using at
:
#!/bin/sh
# Pelican publish
make publish
# Clear old queue entries if they call this script.
for q in `atq -q g | cut -f1`
do
if [ `at -c $q | tail -2 | head -1` = "$0" ]
then
atrm $q
fi
done
# Check newly published drafts for when they should be published.
# Not using for because output lines have spaces.
grep -F -- '<!-- Post at datetime ' output/drafts/* | cut -d' ' -f5-6 | while read time
do
# Schedule running this script for that time.
echo "$0" | at -q g $time
done
Last, follow the instructions in this blog post and run that
script as the deployment task
.
The details