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
.