Blog template
Render a blog landing page and its published-post summary list
templates/blog.liquid renders a blog landing page at /blogs/:slug. A blog contains posts, categories, and tags.
Context
The route gives blog, posts, and the normal template globals.
blog
| Property | Type | Description |
|---|---|---|
id | string | Blog ID |
title | string | Blog title |
richTitle_html | string | Richly formatted title, when configured |
description | string | Plain-text description |
richDescription_html | string | Rendered description HTML |
slug | string | Blog slug |
url | string | Public blog URL |
image | media | Main image |
categories | object | Joined category list; iterate blog.categories.docs |
tags | object | Joined tag list; iterate blog.tags.docs |
blocks | array | Content blocks |
theme.settings | object | Per-blog template settings |
meta | object | SEO title, description, image, and canonical data |
createdAt | string | Creation timestamp |
updatedAt | string | Last update timestamp |
posts
The route separately supplies up to 100 published posts for the blog. Each entry is a stable list summary with id, title, description, slug, publishDate, image, and url. Use the top-level posts variable for the archive list. It is deliberately smaller than the full post detail context.
Example
{% layout 'layouts/default.liquid' %}
{% capture content_for_layout %}
<main class="blog-page">
<header>
{% if blog.image and blog.theme.settings.show_image != false %}
<img
src="{{ blog.image | image_url: width: 1200, height: 480, fit: 'cover' }}"
alt="{{ blog.image.alt | default: blog.title }}"
>
{% endif %}
<h1>{{ blog.title }}</h1>
{% if blog.description %}
<div class="rich-text">{{ blog.richDescription_html }}</div>
{% endif %}
</header>
{% stageblocks blog %}
{% if posts.size > 0 %}
<ul class="post-list">
{% for post in posts %}
<li>
<article>
{% if post.image %}
<img
src="{{ post.image | image_url: width: 480, height: 300, fit: 'cover' }}"
alt="{{ post.image.alt | default: post.title }}"
loading="lazy"
>
{% endif %}
<h2><a href="{{ post.url }}">{{ post.title }}</a></h2>
{% if post.publishDate %}
<time datetime="{{ post.publishDate }}">{{ post.publishDate | date: '%d %B %Y' }}</time>
{% endif %}
{% if post.description %}<p>{{ post.description }}</p>{% endif %}
</article>
</li>
{% endfor %}
</ul>
{% else %}
<p>No posts have been published yet.</p>
{% endif %}
</main>
{% endcapture %}
{% schema %}
{
"settings": [
{
"type": "switch",
"name": "show_image",
"label": "Show blog image",
"defaultValue": true
}
],
"blocks": []
}
{% endschema %}List summaries do not include authors, categories, tags, or full post bodies. Fetch or render those on the post detail page instead of assuming they exist here.
Variants
Use filenames such as templates/blog.magazine.liquid for selectable variants. The selected blog stores which variant to use. /blogs/:slug resolves it and falls back to templates/blog.liquid.