Theme Architecture¶
This guide covers Phase 7 of the Quick Start β how the zer0-mistakes theme assembles pages from layouts, includes, Liquid templates, and data files.
How Jekyll Builds a Page¶
Every page follows this pipeline:
Markdown file (content + frontmatter)
β
Layout template (_layouts/article.html)
β
Includes (_includes/header.html, sidebar.html, etc.)
β
Theme base layout (root.html β default.html)
β
Static HTML file (in _site/)
When you run jekyll build, it reads each content file, merges it with its assigned layout, resolves all {% raw %}{% include %}{% endraw %} calls, evaluates Liquid expressions, and writes the final HTML to _site/.
Layouts¶
Layouts are HTML templates that wrap your content. Set the layout in front matter:
Available Layouts¶
| Layout | Purpose | Used By |
|---|---|---|
root |
Base HTML shell β <head>, <body>, scripts, stylesheets |
Everything (parent of other layouts) |
default |
Standard page with header, footer, and sidebar | General pages, docs, notes |
article |
Blog post layout with date, author, tags, reading time | Posts |
quest |
Quest layout with level badge, XP, achievements, prerequisites | Quests |
quest-collection |
Groups quests by tier in a filterable grid | Quest index pages |
journals |
Journal/notebook layout for dated entries | Notebooks |
javascript |
Layout for JS-heavy interactive pages | Special pages |
Layout Inheritance¶
Layouts chain together. For example:
The content variable in each layout is replaced by the child layout or the page content.
Includes (Partials)¶
Includes are reusable HTML snippets injected into layouts with:
Key Includes in IT-Journey¶
_includes/
βββ components/
β βββ powered-by.html # Footer attribution
βββ contributor/
β βββ profile_card.html # Contributor profile card
β βββ character_sheet.html # RPG-style character stats
β βββ achievement_wall.html # Achievement badge display
β βββ stats_panel.html # Activity statistics panel
βββ content_statistics/ # Site-wide content stats
βββ quest-card.html # Individual quest display card
βββ quest-filters.html # Quest filtering controls
βββ quest-stats.html # Quest completion statistics
βββ quest_grid.html # Quest grid layout
Passing Variables to Includes¶
Inside the include, access variables via include.quest and include.show_xp.
Liquid Templating¶
Jekyll uses the Liquid templating language for dynamic content. There are three main constructs:
Output Tags¶
Display variables with double curly braces:
{% raw %}{{ page.title }}
{{ site.title }}
{{ page.date | date: "%B %d, %Y" }}
{{ page.content | number_of_words }} words{% endraw %}
Logic Tags¶
Control flow with {% raw %}{% %}{% endraw %} tags:
{% raw %}{% if page.comments %}
{% include comments.html %}
{% endif %}
{% unless page.draft %}
<p>Published: {{ page.date | date: "%Y-%m-%d" }}</p>
{% endunless %}
{% case page.layout %}
{% when "quest" %}
<span class="badge">Quest</span>
{% when "articles" %}
<span class="badge">Article</span>
{% endcase %}{% endraw %}
Loops¶
Iterate over collections and arrays:
{% raw %}{% for post in site.posts limit:5 %}
<h2><a href="{{ post.url }}">{{ post.title }}</a></h2>
<p>{{ post.description }}</p>
{% endfor %}
{% for quest in site.quests %}
{% if quest.difficulty == "π’ Easy" %}
{% include quest-card.html quest=quest %}
{% endif %}
{% endfor %}{% endraw %}
Useful Filters¶
| Filter | Example | Result |
|---|---|---|
date |
{% raw %}{{ page.date \| date: "%B %d, %Y" }}{% endraw %} |
"March 31, 2026" |
upcase |
{% raw %}{{ "hello" \| upcase }}{% endraw %} |
"HELLO" |
slugify |
{% raw %}{{ "My Title" \| slugify }}{% endraw %} |
"my-title" |
where |
{% raw %}{{ site.quests \| where: "difficulty", "π’ Easy" }}{% endraw %} |
Filtered array |
sort |
{% raw %}{{ site.posts \| sort: "date" \| reverse }}{% endraw %} |
Sorted array |
markdownify |
{% raw %}{{ page.description \| markdownify }}{% endraw %} |
HTML from markdown |
number_of_words |
{% raw %}{{ page.content \| number_of_words }}{% endraw %} |
Word count |
strip_html |
{% raw %}{{ page.content \| strip_html }}{% endraw %} |
Plain text |
Data Files¶
YAML files in _data/ are accessible as site.data.* in templates. This keeps structured data out of your templates and content files.
IT-Journey Data Files¶
| File | Contains | Access As |
|---|---|---|
_data/navigation/main.yml |
Primary site menu | site.data.navigation.main |
_data/navigation/quests.yml |
Quest sidebar menu | site.data.navigation.quests |
_data/navigation/posts.yml |
Posts sidebar menu | site.data.navigation.posts |
_data/navigation/quickstart.yml |
Quickstart sidebar | site.data.navigation.quickstart |
_data/ui-text.yml |
UI strings (i18n-ready) | site.data.ui-text |
_data/prerequisites.yml |
Learning prerequisites | site.data.prerequisites |
_data/content_statistics.yml |
Content stats | site.data.content_statistics |
Using Data in Templates¶
{% raw %}{% for item in site.data.navigation.main %}
<a href="{{ item.url }}">{{ item.title }}</a>
{% if item.children %}
<ul>
{% for child in item.children %}
<li><a href="{{ child.url }}">{{ child.title }}</a></li>
{% endfor %}
</ul>
{% endif %}
{% endfor %}{% endraw %}
The _site/ Output Directory¶
Everything Jekyll generates ends up in _site/. This directory:
- Is regenerated each build β never edit files here directly
- Contains only static files (HTML, CSS, JS, images)
- Is the directory you deploy to your hosting provider
- Is listed in
.gitignoreso it's not committed
Customizing the Theme¶
Override a Theme Layout¶
To override a theme layout, create the same file in your project:
Jekyll checks your project first, then the theme gem.
Override an Include¶
Same pattern:
Add New Layouts or Includes¶
Add them to _layouts/ or _includes/ in your project. They're automatically available.
What's Next¶
| Next Step | Guide |
|---|---|
| Create posts, quests, and docs | Content Creation |
| Style your site with skins and CSS | Styling & Navigation |
| Run the site locally | Local Development |
IT-Journey Quests: Liquid Templating Β· Jekyll Fundamentals
External Docs: Jekyll Layouts Β· Jekyll Includes Β· Liquid Reference Β· Jekyll Data Files