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 is the container for posts, categories, and tags.
Context
The route provides 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 record stores the variant choice; /blogs/:slug resolves it and falls back to templates/blog.liquid.