Liquid Templating: Dynamic Content for Jekyll Sites
Create dynamic content in Jekyll with Liquid - master variables, filters, and control flow.
Greetings, brave adventurer! You can now scaffold and serve a Jekyll site - but every page is still hand-written and static. Liquid Templating teaches you the spoken magic of Jekyll: a templating language that lets one template render a hundred pages, pull in data, loop over lists, and decide what to show. This is where your site stops being a stack of files and starts being a living thing.
Liquid runs at build time, not in the browser, so all this power costs your visitors nothing. Learn it well, for every layout, include, and theme you ever touch in Jekyll speaks Liquid.
📖 The Legend Behind This Quest
Long ago, the merchants of Shopify needed a safe way to let shopkeepers customize their storefront pages without handing them the keys to the whole engine. So they forged Liquid - a templating language powerful enough to loop, filter, and decide, yet sandboxed so a careless incantation could never break the server. Jekyll adopted Liquid, and today it is the lingua franca of static templating.
With Liquid you write a page once and let the data fill it in - a blog index that lists every post, a navigation menu built from a data file, a card that changes colour based on a value. Master it, and you wield the heart of every Jekyll theme.
🎯 Quest Objectives
By the time you complete this journey, you will have mastered:
Primary Objectives (Required for Quest Completion)
- Objects & Variables - Output values with the double-brace syntax
- Filters - Transform values by chaining filters with the pipe
- Tags: Loops & Conditionals - Use
for,if, andassignto control logic - Includes & Layouts - Compose pages from reusable partials and skeletons
Secondary Objectives (Bonus Achievements)
- Passing Parameters to Includes - Make partials reusable with arguments
- Whitespace Control - Use
{%- -%}to keep generated HTML clean - Looping Over Site Data - Read
_datafiles in a template
Mastery Indicators
You’ll know you’ve truly mastered this quest when you can:
- Explain the difference between output
{{ }}and tag{% %}delimiters - Chain three filters to format a value end to end
- Build a list page that loops over a collection with a conditional badge
🗺️ Quest Prerequisites
📋 Knowledge Requirements
- Basic HTML (tags, attributes)
- Completion of Jekyll Fundamentals
- Recommended: YAML Configuration for data files
🛠️ System Requirements
- Modern operating system (Windows 10+, macOS 10.14+, or Linux)
- A working Jekyll site to experiment in
- A text editor or IDE (VS Code recommended)
🧠 Skill Level Indicators
This 🟡 Medium quest expects:
- You can build and serve a Jekyll site already
- You are comfortable editing files in
_layoutsand_includes - Ready for 75-90 minutes of focused learning
🌍 Choose Your Adventure Platform
Liquid lives inside your Jekyll site, so the only setup is a running site. Use --livereload so each edit shows instantly.
🍎 macOS Kingdom Path
Click to expand macOS instructions
```bash # Serve your site with live reload so Liquid edits appear instantly cd my-castle bundle exec jekyll serve --livereload ```🪟 Windows Empire Path
Click to expand Windows instructions
```powershell # Serve with live reload cd my-castle bundle exec jekyll serve --livereload ```🐧 Linux Territory Path
Click to expand Linux instructions
```bash # Serve with live reload cd my-castle bundle exec jekyll serve --livereload ```☁️ Cloud Realms Path
Click to expand Cloud/Container instructions
```bash # In a container, bind the host so live reload reaches your browser docker run --rm -it -p 4000:4000 -p 35729:35729 -v "$PWD":/srv/jekyll \ jekyll/jekyll:4 jekyll serve --livereload --host 0.0.0.0 ```🧙♂️ Chapter 1: Objects, Tags, and Filters - The Three Words of Power
Liquid has exactly three kinds of markup. Learn the three, and you can read any template.
⚔️ Skills You’ll Forge in This Chapter
- The output delimiter
{{ }}for printing values - The tag delimiter
{% %}for logic - Filters for transforming values
🏗️ The Three Delimiters
{{ page.title }} <!-- OBJECT: prints a value into the page -->
{% assign greeting = "hi" %} <!-- TAG: runs logic, prints nothing -->
{{ greeting | upcase }} <!-- FILTER: transforms a value -> "HI" -->
- Objects
{{ ... }}output content - a variable, a string, a number. - Tags
{% ... %}perform logic - assignments, loops, conditionals. They produce no visible output themselves. - Filters appear inside objects after a pipe
|and transform the value flowing through.
Chaining filters is where Liquid shines. Each filter feeds the next:
{{ "the static web" | capitalize | replace: "web", "kingdom" }}
<!-- Output: The static kingdom -->
{{ page.date | date: "%B %-d, %Y" }}
<!-- Output: June 14, 2026 -->
{{ post.content | strip_html | truncatewords: 20 }}
<!-- A 20-word plain-text preview of a post -->
Jekyll exposes useful global objects too: site (everything in _config.yml and _data), page (the current page’s front matter), content, and inside loops, post / item.
🔍 Knowledge Check: The Three Words
- Which delimiter prints a value, and which runs logic?
- What does the pipe
|do? - What does
{{ site.title }}read from?
⚡ Quick Wins and Checkpoints
- Printed a value: You output
{{ page.title }}on a page - Chained a filter: You transformed a string with at least two filters
🧙♂️ Chapter 2: Loops and Conditionals - Logic in the Template
A blog index is just a for loop over posts. A “featured” badge is just an if. This chapter gives your templates a brain.
⚔️ Skills You’ll Forge in This Chapter
- Iterating with
for - Branching with
if/elsif/else - Filtering and limiting loops
🏗️ Looping and Branching
A list of the five most recent posts, each with an optional “New” badge:
<ul class="post-list">
{% for post in site.posts limit:5 %}
<li>
<a href="{{ post.url | relative_url }}">{{ post.title }}</a>
{% if post.featured %}
<span class="badge">⭐ Featured</span>
{% elsif post.date > site.time | date: "%s" | minus: 604800 %}
<span class="badge">New</span>
{% endif %}
</li>
{% endfor %}
</ul>
Useful loop helpers:
{% for item in site.data.navigation %}
{{ forloop.index }}. {{ item.name }} <!-- forloop.index is 1-based -->
{% endfor %}
{% assign sorted = site.posts | sort: "title" %}
{% for p in sorted reversed %}
{{ p.title }}
{% endfor %}
if understands and, or, ==, !=, >, <, contains. Use unless for the negative case and case/when for many branches.
🔍 Knowledge Check: Logic
- How do you limit a
forloop to the first five items? - What variable gives you the current iteration number?
- When would you use
unlessinstead ofif?
🧙♂️ Chapter 3: Includes & Layouts - Composing Pages
Repetition is the enemy. Liquid lets you write a header once as an include, and a page skeleton once as a layout, then reuse them everywhere.
⚔️ Skills You’ll Forge in This Chapter
- Pulling in partials with
include - Passing parameters to includes
- Wrapping content in layouts
🏗️ Reuse with Includes and Layouts
Create _includes/card.html - a reusable component that accepts parameters:
<div class="card">
<h3>{{ include.title }}</h3>
<p>{{ include.body }}</p>
</div>
Use it anywhere, passing arguments by name:
{% include card.html title="Static Sites" body="Fast and secure by design." %}
{% include card.html title="Liquid" body="Templating without a server." %}
Layouts wrap a page’s content in shared chrome. Create _layouts/default.html:
<!DOCTYPE html>
<html lang="en">
<head>
<title>{{ page.title }} | {{ site.title }}</title>
</head>
<body>
{% include header.html %}
<main>{{ content }}</main>
{% include footer.html %}
</body>
</html>
Any page declaring layout: default in its front matter gets wrapped automatically; the special {{ content }} object is where the page’s own body lands. Layouts can even nest by giving a layout its own layout: front matter.
🔍 Knowledge Check: Composition
- How do you pass a value into an include?
- What object renders the page body inside a layout?
- How would you make every page share one footer?
🎮 Mastery Challenges
🟢 Novice Challenge: Filter Chain
Objective: Print a formatted, transformed value on a page.
Requirements:
- Output
{{ page.title }}somewhere visible - Chain at least two filters on one value
- Format a date with the
datefilter
Validation: The rendered page shows the transformed text and a formatted date.
🟡 Intermediate Challenge: Data-Driven List
Objective: Build a navigation menu from a _data file.
Requirements:
- Create
_data/navigation.ymlwith a list of links - Loop over it with
for - Mark the current page with an
ifcomparison
Validation: The menu renders every entry and highlights the active page.
🔴 Advanced Challenge: Parameterized Component
Objective: Create a reusable card include and a layout that uses it.
Requirements:
- Build
_includes/card.htmlthat acceptstitleandbody - Render at least three cards from a loop over data
- Wrap the page in a custom layout
Validation: Cards render from data and the page is wrapped by your layout.
🏆 Quest Rewards & Achievements
🎖️ Badges Earned:
- 🏆 Loremaster of Liquid - Variables, filters, and control flow are yours
- 🌱 Weaver of Templates - You compose pages from includes and layouts
🛠️ Skills Unlocked:
- Liquid Template Authoring - Write dynamic pages that render at build time
- Build-Time Templating Concepts - Reason about data-driven generation
🔓 Unlocked Quests:
- GitHub Pages Basics - Publish your dynamic site for free
- YAML Configuration - Feed your templates with structured data
📊 Progression Points: +50 XP
🗺️ Next Steps in Your Journey
Continue the Main Story:
- 🎯 GitHub Pages Basics - Take your templated site live
Explore Side Adventures:
- ⚔️ YAML Configuration - The data your templates loop over
- ⚔️ Git Workflow Mastery - Ship template changes cleanly
Character Class Recommendations
💻 Software Developer: Continue to GitHub Pages Basics
🏗️ System Engineer: Explore YAML Configuration
🎨 Frontend Specialist: Deepen your theming with custom layouts
📚 Resources
Official Documentation
- Liquid Reference (Shopify) - The canonical language reference
- Jekyll Liquid Documentation - Liquid as Jekyll uses it
- Jekyll Includes - Reusable partials with parameters
Community Resources
- Jekyll Talk Forum - Ask Liquid questions
- Liquid on Stack Overflow - Tagged Q&A
- Jekyll Cheat Sheet - Quick Liquid and Jekyll syntax
Learning Materials
- Jekyll Step-by-Step: Includes - Hands-on include tutorial
- Jekyll Variables - Every object Liquid can read
🤝 Quest Completion Checklist
- ✅ Completed all primary objectives
- ✅ Built a page that loops over data with a conditional
- ✅ Answered all knowledge check questions
- ✅ Completed at least one mastery challenge
- ✅ Explored the resource library
- ✅ Identified your next quest in the journey
🕸️ Knowledge Graph
Structured wiki-links connect this quest to the IT-Journey knowledge graph. Open the Obsidian Graph View to explore connections.
Level hub: [[Level 0001 - Web Fundamentals]] Overworld: [[🏰 Overworld - Master Quest Map]] Prerequisites: [[Jekyll Fundamentals]] Unlocks: [[GitHub Pages Basics]] · [[YAML Configuration]] Obsidian docs: [[Obsidian Knowledge Graph and Wiki Links]]
🎁 Rewards
Badges
- 🏆 Loremaster of Liquid - Mastered variables, filters, and control flow
- 🌱 Weaver of Templates - Composed pages from includes and layouts
Skills unlocked
- 🛠️ Liquid Template Authoring
- 🧠 Build-Time Templating Concepts
Features unlocked
- The ability to build data-driven pages in any later quest
🕸️ Quest Network
Referenced by
- Loading…