Zola Git Pre-Commit Hook: Updating Post Dates
In order to keep the “Last updated” field of posts always accurate, I automated its modification with a custom Git pre-commit hook.
A Git pre-commit hook is a script that runs automatically before each commit. It can perform custom actions, such as validating code, running tests, or, in this case, updating post dates.
The Hook
This Bash script creates or modifies the updated
field in the front matter of committed Markdown files with their last modified date.
Here’s the code (also available on gist):
#!/usr/bin/env bash
# Requires Bash 4.0 or newer.
# This script updates the 'updated' field in the front matter of modified .md
# files setting it to their last modified date.
# Function to exit the script with an error message.
# Function to extract the date from the front matter.
# Get the modified .md files, ignoring "_index.md" files.
# Loop through each modified .md file.
for; do
# Get the last modified date from the filesystem.
last_modified_date=
# Extract the "date" field from the front matter.
date_value=
# Skip the file if the last modified date is the same as the "date" field.
if ; then
continue
fi
# Update the "updated" field with the last modified date.
# If the "updated" field doesn't exist, create it below the "date" field.
&& ||
# Stage the changes.
done
Setup
After setting up your Zola project and Git repository:
-
Create or update the
pre-commit
file inside.git/hooks
(in your project’s root directory) with the script above. -
Make the script executable with
chmod +x .git/hooks/pre-commit
.
It’s that simple.
Now, whenever you commit Markdown files with a date
field, the updated
field will be created or updated with the file’s last modification date in ISO 8601 format (e.g. 2027-08-29).
Extra: Losslessly Compressing PNGs
To speed things up, I love (losslessly) compressing files. For that purpose, I updated the script to include PNG compression with either oxipng or optipng.
Since you can’t have more than one pre-commit hook[1], I added the compression functionality to the previous script by appending these lines (gist with the full script):
# Check if oxipng or optipng are installed.
if ; then
png_compressor="oxipng -o max"
elif ; then
png_compressor="optipng -o 7"
fi
# If either compressor is installed…
if ; then
# Get the modified or added png files.
# Loop through each png file.
for; do
# Compress the png file.
||
# Stage the changes.
done
fi
With these extra lines, if a PNG compressor is installed, the script will look through the commited PNG files and losslessly compress them.
Now I can easily maintain accurate “Last updated” dates for Zola posts and optimise PNG images for faster loading times.
Over time, I’ve added other features like preventing commits of drafts and files that include “TODO”, and running optimisation scripts. You can take a look at the hook I’m currently using here.
-
If you prefer to maintain separate functionality and use multiple files for your pre-commit scripts, you can create a
pre-commit
file that invokes all the other scripts (which you could put inside apre-commit.d
directory, for example). ↩