Enabling link abbreviations in Minimal Mistakes
I want to be able to use link abbreviations in Minimal Mistakes, for example,
use foo:<filename> in place of the full link for images and images in a
gallery like the following:
---
link_abbrs:
- link_abbr: foo http://127.0.0.1:8123/archive/image/foo/
gallery:
- url: foo:20260218184820.png
image_path: foo:20260218184820.png
- url: foo:20260218184820.png
image_path: foo:20260218184820.png
- url: foo:20260218184820.png
image_path: foo:20260218184820.png
---

{% include gallery caption="Link abbreviations" %}
The links can then be translated to their full forms in the built result such as:
http://127.0.0.1:8123/archive/image/foo/20260218184820.png
Create a new Ruby plugin file
We can create a plugin under _plugins/link_abbr.rb which handles the link
abbreviations:
require 'addressable/uri'
Jekyll::Hooks.register [:pages, :documents], :pre_render do |doc|
next unless doc.data['link_abbrs'].is_a?(Array)
doc.data['link_abbrs'].each do |item|
next unless item.is_a?(Hash) && item['link_abbr']
key, base_url = item['link_abbr'].split(' ', 2)
next unless key && base_url
# 1. Replaces "](key:filename)" inside the Markdown body content
doc.content = doc.content.gsub(/\]\(#{Regexp.escape(key)}:([^\)]+)\)/) do
escaped_path = Addressable::URI.escape(base_url + $1)
prefix = base_url.start_with?('/assets') ? "https://josephtesfaye.com/josephs-blog" : ""
"](#{prefix}#{escaped_path})"
end
# 2. Replace image_path in figures
doc.content = doc.content.gsub(/image_path="#{Regexp.escape(key)}:([^"]+)"/) { "image_path=\"#{Addressable::URI.escape(base_url + $1)}\"" }
# 3. Replace inside ANY front matter array (gallery, gallery1, gallery2, etc.)
doc.data.each do |_, value|
if value.is_a?(Array)
value.each do |list_item|
next unless list_item.is_a?(Hash)
['url', 'image_path'].each do |attr|
if list_item[attr] && list_item[attr].to_s.start_with?("#{key}:")
# Replace the exact abbreviation prefix with the base URL
full_path = list_item[attr].to_s.sub(/^#{Regexp.escape(key)}:/, base_url)
list_item[attr] = Addressable::URI.escape(full_path)
end
end
if list_item['title']
list_item['title'] = list_item['title'].to_s.gsub(/\]\(#{Regexp.escape(key)}:([^\)]+)\)/) do
escaped_path = Addressable::URI.escape(base_url + $1)
prefix = base_url.start_with?('/assets') ? "https://josephtesfaye.com/josephs-blog" : ""
"](#{prefix}#{escaped_path})"
end
end
end
end
end
end
end
The github-pages gem enforces strict safe mode and completely disables the
_plugins directory to mimic GitHub’s legacy deployment environment, overriding
any safe: false settings in your configuration.
To allow custom plugins to run locally, you need to replace it with the standard Jekyll gem. Since you already have all your plugins explicitly listed in your Gemfile, this is a safe swap.
Gemfile:
-gem "github-pages", group: :jekyll_plugins
+gem "jekyll"
+gem "kramdown-parser-gfm"
+gem "faraday-retry"
_config.yml:
-remote_theme: mmistakes/minimal-mistakes@4.20.2
+theme: minimal-mistakes-jekyll
Terminal:
bundle install
bundle exec jekyll serve
Use GitHub Actions to build your GitHub Pages site
This affects the default GitHub Pages build. The classic GitHub Pages build
environment strictly enforces safe mode and ignores all files in the _plugins
directory. If you push the site using the default settings, it will still host
successfully, but your custom plugin will not run and the link abbreviations
will remain unparsed.
To use custom plugins while hosting on GitHub Pages, you must switch your deployment method to GitHub Actions. This modern approach uses your exact Gemfile, executes your Ruby scripts, and then hosts the final output on GitHub Pages.
- Go to your repository on GitHub.
- Click on Settings, then select Pages from the left sidebar.
- Under Build and deployment, change the Source from “Deploy from a branch” to “GitHub Actions”.
- GitHub will suggest a default Jekyll workflow. Click Configure.
- Commit the provided
.github/workflows/jekyll.ymlfile to your repository.
With this workflow active, GitHub will read your updated Gemfile, run the
link_abbr.rb plugin during the build step, and deploy the fully rendered HTML
to your live site.
Comments