Jekyll injection
Adding date and time to a GitHub page
2021 Dec 31
It’s a problem every developer has faced (it me, I’m every developer). You make an earth-shattering edit to your blog on GitHub pages, commit, push, and refresh your browser to see the changes. But wait: are you looking at the edited page, or the old version? You watch the page build GitHub action to confirm that it completed, but has the deployment trickled all the way down yet?
The only way to really know which version you’re looking at is to add the build time or git revision somewhere on your page. Jekyll even offers the variable site.github.build_revision
for the latter.
We’re going to look at a more flexible solution that can be extended to other automated page modifications, which will eventually look like this:
Build: Fri Dec 31 01:03:45 UTC 2021, revision: f7c5b70
Assuming I haven’t broken anything, you can probably see it live at the bottom of this page.
The variables injected into the page will form part of the serum that transforms Jekyll’s markdown into Hyde’s html (or do I have those codeowners backwards?).
Setup your template page source with variables to be replaced
In my example, I’m working on the _layouts/default.html
page, where my footer is. You can run the injection on index.md
or any other html
or md
(markdown) translation unit.
We don’t want the injection to modify our source code and we don’t care about version control on the output of the injection process. So, move your source file to a template that will be the source of truth:
Make sure the template filename starts with _
or .
so that it is ignored by Jekyll. We’re good since default.html
is already in the _layouts
folder. In the future, do all of your editing on the template file rather than the one that gets automatically modified.
Next, add the content where you’re going to inject variables into default-template.html
:
The variable identifiers I have chosen are BUILD_DATE
and BUILD_REVI
.
Be careful that these identifiers don’t appear elsewhere in your source where you want them to be literal and unmodified. Perhaps add some sigil – e.g. $VARIABLE
– as an extra guard against the dumb parsing that we’re about to do.
Use sed
to search and replace the template variables and generate your page source
In this example, there are some handy bash
and git
commands to get the data that we want to inject.
First, copy the template source file to the output destination file to be injected. Then inject the data with sed
:
Recall that the var=$(command)
syntax saves the output of a bash command in a variable. The syntax for replacing search
with replace
globally in a file
is sed -i "s/search/replace/g" file
.
The underscore _
needs to be escaped in the search pattern like \_
.
Setting the timezone TZ
is optional, it will probably default to UTC otherwise.
Short of sigils, we can get little a extra protection by only replacing whole words that match the search pattern, by marking the beginning and ending word boundaries with \<
and \>
respectively:
Alternatively, if you don’t want to use sed
, you could generate an entire footer file with echo
, cat
, etc. For the Jekyll cayman theme, the footer is part of default.html
, so it seems easier to use sed
instead of generating all of default.html
from scratch.
Build and deploy the page
Because we’re modifying the page source after every commit, we can’t use the default Jekyll GitHub pages workflow. We need to use a custom jekyll.yml
workflow.
After checking out the git repo and running sed
as above, place these steps in the workflow yml
to build and deploy the page:
Make sure to update the branch name that you’re deploying from if it’s not main
. Are you still naming branches master
in 2022? 😩
I’m using JamesIves/github-pages-deploy-action to deploy. To guard against a left-pad fiasco, I forked it and used pgh
git helper to keep the fork up to date.
One downside of this non-default workflow is all the junk bot commits. If you can figure out how to get rid of them, kudos to you. The default Jekyll workflow doesn’t create junk commits like this, but its yml
isn’t accessible to edit and add the sed
commands.
Make sure to pull
the changes locally after each junk commit. If you’re like me, you’ll frequently forget to pull
and end up with even more junk commits to merge
the remote changes.