Post Template
The post template renders individual blog posts or news articles. It displays the full post content, author information, categories, and related metadata.
Location
Section titled “Location”└── theme └── templates └── post.liquidThe post Object
Section titled “The post Object”The post template has access to the post object with these properties:
Core Properties
Section titled “Core Properties”| Property | Type | Description |
|---|---|---|
id | string | Unique identifier |
title | string | Post title |
description | string | Post excerpt/lede |
slug | string | URL-safe identifier |
image | media | Featured image |
Publishing Properties
Section titled “Publishing Properties”| Property | Type | Description |
|---|---|---|
publishDate | string | Publication date (ISO 8601) |
blog | blog | Parent blog |
Authors & Taxonomy
Section titled “Authors & Taxonomy”| Property | Type | Description |
|---|---|---|
authors | array | Post authors (people) |
categories | array | Post categories |
tags | array | Post tags |
Content
Section titled “Content”| Property | Type | Description |
|---|---|---|
blocks | array | Content blocks |
customAttributes | object | Custom attribute values |
theme | object | Theme-specific field values |
Metadata
Section titled “Metadata”| Property | Type | Description |
|---|---|---|
meta.title | string | SEO title |
meta.description | string | SEO description |
meta.image | media | SEO/OG image |
createdAt | string | Creation timestamp |
updatedAt | string | Last update timestamp |
Basic Template Example
Section titled “Basic Template Example”{% layout 'layouts/default.liquid' %}
{% capture content_for_layout %}<article class="post"> <header class="post-header"> {% if post.image %} <img src="{{ post.image | image_url: width: 1200, height: 600 }}" alt="{{ post.image.alt | default: post.title }}" class="post-header__image" > {% endif %}
<h1>{{ post.title }}</h1>
{% if post.publishDate %} <time datetime="{{ post.publishDate }}"> {{ post.publishDate | date: '%B %d, %Y' }} </time> {% endif %}
{% if post.description %} <p class="lead">{{ post.description }}</p> {% endif %} </header>
<div class="post-body"> {% stageblocks post %} </div></article>{% endcapture %}Working with Authors
Section titled “Working with Authors”Single Author Display
Section titled “Single Author Display”{% if post.authors.size > 0 %} {% assign author = post.authors.first %} <div class="post-author"> {% if author.image %} <img src="{{ author.image | image_url: width: 80, height: 80 }}" alt="{{ author.name }}" class="author-avatar" > {% endif %} <div class="author-info"> <span class="author-name"> <a href="/people/{{ author.slug }}">{{ author.name }}</a> </span> {% if author.role %} <span class="author-role">{{ author.role }}</span> {% endif %} </div> </div>{% endif %}Multiple Authors
Section titled “Multiple Authors”{% if post.authors.size > 0 %} <div class="post-authors"> <span class="byline">By</span> {% for author in post.authors %} <a href="/people/{{ author.slug }}">{{ author.name }}</a> {% unless forloop.last %} {% if forloop.index == post.authors.size | minus: 1 %} and {% else %} , {% endif %} {% endunless %} {% endfor %} </div>{% endif %}Author Bio Box
Section titled “Author Bio Box”{% if post.authors.size > 0 %} <aside class="author-box"> <h3>About the Author{% if post.authors.size > 1 %}s{% endif %}</h3>
{% for author in post.authors %} <div class="author-bio"> {% if author.image %} <img src="{{ author.image | image_url: width: 120, height: 120 }}" alt="{{ author.name }}" > {% endif %} <div> <h4>{{ author.name }}</h4> {% if author.role %} <p class="role">{{ author.role }}</p> {% endif %} {% if author.biography_html %} {{ author.biography_html }} {% endif %} </div> </div> {% endfor %} </aside>{% endif %}Working with Categories and Tags
Section titled “Working with Categories and Tags”Display Categories
Section titled “Display Categories”{% if post.categories.size > 0 %} <div class="post-categories"> {% for category in post.categories %} <a href="/blog?category={{ category | handleize }}" class="category-badge"> {{ category }} </a> {% endfor %} </div>{% endif %}Display Tags
Section titled “Display Tags”{% if post.tags.size > 0 %} <div class="post-tags"> <span class="tags-label">Tags:</span> {% for tag in post.tags %} <a href="/blog?tag={{ tag | handleize }}" class="tag"> {{ tag }} </a> {% unless forloop.last %}, {% endunless %} {% endfor %} </div>{% endif %}Combined Taxonomy
Section titled “Combined Taxonomy”<footer class="post-meta"> {% if post.categories.size > 0 %} <div class="meta-item"> <strong>Categories:</strong> {% for category in post.categories %} <a href="/blog?category={{ category | handleize }}">{{ category }}</a> {% unless forloop.last %}, {% endunless %} {% endfor %} </div> {% endif %}
{% if post.tags.size > 0 %} <div class="meta-item"> <strong>Tags:</strong> {% for tag in post.tags %} <a href="/blog?tag={{ tag | handleize }}">{{ tag }}</a> {% unless forloop.last %}, {% endunless %} {% endfor %} </div> {% endif %}</footer>Working with the Blog Relationship
Section titled “Working with the Blog Relationship”Back to Blog Link
Section titled “Back to Blog Link”{% if post.blog %} <a href="/blogs/{{ post.blog.slug }}" class="back-link"> ← Back to {{ post.blog.title }} </a>{% endif %}Breadcrumb with Blog
Section titled “Breadcrumb with Blog”<nav class="breadcrumb" aria-label="Breadcrumb"> <ol> <li><a href="/">Home</a></li> {% if post.blog %} <li><a href="/blogs/{{ post.blog.slug }}">{{ post.blog.title }}</a></li> {% endif %} <li aria-current="page">{{ post.title }}</li> </ol></nav>Working with Theme-Specific Fields
Section titled “Working with Theme-Specific Fields”Access custom fields defined in the template schema via post.theme:
{# Template schema defines: reading_time, show_social_share, related_posts #}
{% if post.theme.reading_time %} <span class="reading-time">{{ post.theme.reading_time }} min read</span>{% endif %}
{% if post.theme.show_social_share %} {% render 'snippets/social-share' title: post.title %}{% endif %}Complete Template Example
Section titled “Complete Template Example”{% layout 'layouts/default.liquid' %}
{% capture content_for_layout %}<article class="post-page"> {# Breadcrumb #} <nav class="breadcrumb" aria-label="Breadcrumb"> <ol> <li><a href="/">Home</a></li> {% if post.blog %} <li><a href="/blogs/{{ post.blog.slug }}">{{ post.blog.title }}</a></li> {% endif %} <li aria-current="page">{{ post.title }}</li> </ol> </nav>
{# Post header #} <header class="post-header"> {% if post.categories.size > 0 %} <div class="post-categories"> {% for category in post.categories %} <a href="/blog?category={{ category | handleize }}" class="category-badge"> {{ category }} </a> {% endfor %} </div> {% endif %}
<h1 class="post-title">{{ post.title }}</h1>
<div class="post-meta"> {% if post.publishDate %} <time datetime="{{ post.publishDate }}"> {{ post.publishDate | date: '%B %d, %Y' }} </time> {% endif %}
{% if post.theme.reading_time %} <span class="reading-time">{{ post.theme.reading_time }} min read</span> {% endif %} </div>
{# Authors #} {% if post.authors.size > 0 %} <div class="post-authors"> {% for author in post.authors %} <a href="/people/{{ author.slug }}" class="author"> {% if author.image %} <img src="{{ author.image | image_url: width: 48, height: 48 }}" alt="{{ author.name }}" class="author-avatar" > {% endif %} <span class="author-name">{{ author.name }}</span> </a> {% endfor %} </div> {% endif %} </header>
{# Featured image #} {% if post.image %} <figure class="post-featured-image"> <img src="{{ post.image | image_url: width: 1200, height: 600 }}" alt="{{ post.image.alt | default: post.title }}" > {% if post.image.caption %} <figcaption>{{ post.image.caption }}</figcaption> {% endif %} </figure> {% endif %}
{# Post content #} <div class="post-content"> {% if post.description %} <p class="lead">{{ post.description }}</p> {% endif %}
{% stageblocks post %} </div>
{# Tags #} {% if post.tags.size > 0 %} <footer class="post-footer"> <div class="post-tags"> <span class="tags-label">Tagged:</span> {% for tag in post.tags %} <a href="/blog?tag={{ tag | handleize }}" class="tag">{{ tag }}</a> {% endfor %} </div> </footer> {% endif %}
{# Social sharing #} {% if post.theme.show_social_share != false %} <div class="post-share"> <h3>Share this post</h3> {% render 'snippets/social-share' title: post.title %} </div> {% endif %}
{# Author bio #} {% if post.authors.size > 0 %} <aside class="author-bio-section"> {% for author in post.authors %} <div class="author-bio"> {% if author.image %} <img src="{{ author.image | image_url: width: 120, height: 120 }}" alt="{{ author.name }}" class="author-bio__image" > {% endif %} <div class="author-bio__content"> <h4> <a href="/people/{{ author.slug }}">{{ author.name }}</a> </h4> {% if author.role %} <p class="author-role">{{ author.role }}</p> {% endif %} {% if author.biography_html %} <div class="author-bio__text">{{ author.biography_html }}</div> {% endif %} </div> </div> {% endfor %} </aside> {% endif %}
{# Navigation #} <nav class="post-nav"> {% if post.blog %} <a href="/blogs/{{ post.blog.slug }}" class="back-link"> ← More from {{ post.blog.title }} </a> {% endif %} </nav></article>{% endcapture %}
{% schema %}{ "name": "post", "settings": [ { "type": "number", "name": "reading_time", "label": "Reading Time (minutes)" }, { "type": "checkbox", "name": "show_social_share", "label": "Show Social Share Buttons", "defaultValue": true }, { "type": "checkbox", "name": "show_author_bio", "label": "Show Author Bio", "defaultValue": true } ], "blocks": [ "content", "image-gallery", "video-gallery", "well" ]}{% endschema %}Using Posts in Components
Section titled “Using Posts in Components”Create a reusable post card component:
{# components/post-card.liquid #}{# Required: post (post object) Optional: show_excerpt (boolean), show_author (boolean)#}{% assign show_excerpt = show_excerpt | default: true %}{% assign show_author = show_author | default: false %}
<article class="post-card"> <a href="/posts/{{ post.slug }}" class="post-card__link"> {% if post.image %} <img src="{{ post.image | image_url: width: 400, height: 250 }}" alt="{{ post.title }}" class="post-card__image" loading="lazy" > {% endif %}
<div class="post-card__content"> {% if post.categories.size > 0 %} <span class="post-card__category">{{ post.categories.first }}</span> {% endif %}
<h3 class="post-card__title">{{ post.title }}</h3>
{% if show_excerpt and post.description %} <p class="post-card__excerpt">{{ post.description | truncate: 120 }}</p> {% endif %}
<div class="post-card__meta"> {% if post.publishDate %} <time datetime="{{ post.publishDate }}"> {{ post.publishDate | date: '%b %d, %Y' }} </time> {% endif %}
{% if show_author and post.authors.size > 0 %} <span class="post-card__author"> by {{ post.authors.first.name }} </span> {% endif %} </div> </div> </a></article>Usage:
<div class="post-grid"> {% for post in all_posts limit: 6 %} {% render 'components/post-card' post: post, show_author: true %} {% endfor %}</div>Alternate Post Templates
Section titled “Alternate Post Templates”Create variations for different post types:
templates/├── post.liquid # Default blog post template├── post.news.liquid # News article layout├── post.review.liquid # Review with rating└── post.interview.liquid # Interview Q&A formatAlternate templates appear in the CMS for editors to select per post.