Post template
Render an individual blog post with its byline, taxonomy, blocks, and metadata
templates/post.liquid renders a published post at /blogs/:blogSlug/posts/:postSlug. The post route can select named variants such as templates/post.feature.liquid from the record's template setting.
The post object
| Property | Type | Description |
|---|---|---|
id | string | Post ID |
title | string | Plain-text title |
richTitle_html | string | Richly formatted title, when configured |
description | string | Plain-text description or excerpt |
richDescription_html | string | Rendered rich description |
slug | string | Post slug |
url | string | Public, locale-aware post URL |
publishDate | string | Publication date in ISO 8601 form |
image | media | Main image |
blog | object | Parent blog summary |
authors | array | Author summaries |
categories | array | Category summaries |
tags | array | Tag summaries |
blocks | array | Content blocks |
theme.settings | object | Per-post template settings |
attributes | object | Custom data made available to the theme |
meta | object | SEO title, description, image, and canonical data |
createdAt | string | Creation timestamp |
updatedAt | string | Last update timestamp |
Author relationships provide byline fields such as displayName, name, firstName, lastName, richName_html, image, slug, and url. They do not include an author biography. Category and tag summaries provide ready-built url values; prefer those to hand-built query strings.
Example
{% layout 'layouts/default.liquid' %}
{% capture content_for_layout %}
<article class="post">
<header>
{% if post.image %}
<img
src="{{ post.image | image_url: width: 1200, height: 630, fit: 'cover' }}"
alt="{{ post.image.alt | default: post.title }}"
>
{% endif %}
<h1>{{ post.title }}</h1>
{% if post.publishDate %}
<time datetime="{{ post.publishDate }}">{{ post.publishDate | date: '%d %B %Y' }}</time>
{% endif %}
{% if post.authors.size > 0 %}
<p class="byline">
By
{% for author in post.authors %}
{{ author.displayName | default: author.name }}{% unless forloop.last %}, {% endunless %}
{% endfor %}
</p>
{% endif %}
{% if post.description %}<p class="lead">{{ post.description }}</p>{% endif %}
</header>
{% stageblocks post %}
{% if post.categories.size > 0 %}
<nav aria-label="Categories">
{% for category in post.categories %}
<a href="{{ category.url }}">{{ category.title }}</a>
{% endfor %}
</nav>
{% endif %}
{% if post.tags.size > 0 %}
<nav aria-label="Tags">
{% for tag in post.tags %}
<a href="{{ tag.url }}">{{ tag.title }}</a>
{% endfor %}
</nav>
{% endif %}
{% if post.blog %}
<a href="{{ post.blog.url }}">More from {{ post.blog.title }}</a>
{% endif %}
</article>
{% endcapture %}
{% schema %}
{
"settings": [
{
"type": "switch",
"name": "show_related_posts",
"label": "Show related posts",
"defaultValue": true
}
],
"blocks": []
}
{% endschema %}Related posts
The related_posts filter matches other posts by tags, categories, or both:
{% if post.theme.settings.show_related_posts != false %}
{% assign related = post | related_posts: "both", 4 %}
{% for item in related %}
<a href="{{ item.url }}">{{ item.title }}</a>
{% endfor %}
{% endif %}