Using variables in Jekyll to define custom content
I have a habit of constantly tinkering with this blog, and every now and then, it leads to a happy accident. I recently discovered that I can use Jekyll’s config.yml
to store custom variables :) You may have already known about this, and I’m probably not the first to make this discovery, but I’m very excited about the possibilities.
The reason for the tinkering which lead to the discovery is this. If you visit this website’s home page, about page, and footer section, you’ll notice that they all have some content in common. Specifically, my tag line and bio are used in many places, and copy-pasting them every time I change them is annoying and error-prone. On more than one occasion, my bio has been different on different pages of the website. This is why I wanted to figure out a way to define them as variables in one place and use them everywhere.
I first tried to define it somewhere in the main template using Liquid syntax but I was unsuccessful. I thought about using JavaScript to define those values and inserting it in the HTML, but that felt like killing a mosquito with a nuclear bomb. The two other places where I define variables are Jekyll’s config.yml
and Netlify’s netlify.toml
. The latter isn’t an option for obvious reasons, so the config.yml
made sense.
And just like that… it worked! Take a look at my config.yml
file:
# Jekyll Configuration
# Site Settings
url: "https://notes.ayushsharma.in"
website_url: "https://notes.ayushsharma.in/"
title: ayush sharma's notes ☕ + 🎧 + 🕹️
email: ayush@example.com
images-path: /static/images/
videos-path: /static/videos/
js-path: /static/js/
baseurl: "" # the subpath of your site, e.g. /blog
# Post Settings
permalink: /:year/:month/:title
# Build settings
markdown: kramdown
highlighter: rouge
# Sass settings
sass:
style: :compressed
# Collections
collections:
collection_nav_links:
output: false
collection_projects:
output: false
collection_social:
output: false
# Content
content:
## Personal information
bio_tagline: "I am a writer and Cloud Systems Architect"
bio_job_desc: "I've worked with startups and enterprises in the IT industry for over a decade, specialising in software development, multi-cloud architectures, DevOps, and SRE. I write about my experiences on this website."
bio_contact: "I'm always <a href=\"https://us6.list-manage.com/contact-form?u=768b89007e44f7f05c5e7539b&form_id=6eae4dbf8e9d1475f967c8447e3080ac\" target=\"_blank\">open to ideas/requests for new content, and chatting about video games and good books</a>"
If you see in the # Content
section, I’ve defined a parent key content
and child keys bio_tagline
, bio_job_desc
and bio_contact
with the content I need. I was surprised to find out that values can contain complex HTML as long as I escape them properly.
Figuring out how to use them took some deductive reasoning, but here’s what my home page source code looks like:
Hi, my name is Ayush Sharma.
{{ site.content.bio_tagline }}. This is my digital garden.
If you’ve used Jekyll before then you’ll be familiar with the site
element: it’s the parent element that contains everything defined in the config.yml
. So content.bio_tagline
after the site
element causes Jekyll to pick up those keys from the configuration file and plug in the values during site generation.
Similarly, my about page’s source code contains the following:
My name is Ayush Sharma. {{ site.content.bio_tagline }}.
{{ site.content.bio_job_desc }}
{{ site.content.bio_contact }}.
With nested variables possible in Jekyll’s config file, I can now define content blocks in one place within category variables that make sense. If you read my last post on the different features I use on this blog, you’ll remember that I talked about using Jekyll Collections to define social media links or navigation elements. I can now also use variables to define one variable containing the complete HTML required to render social media or navigation links and just call that whenever required.
Cheers!