Category Template
The category template renders pages that display all posts within a specific category. It provides a filtered view of blog content organized by category.
Location
Section titled “Location”└── theme └── templates └── category.liquidURL Structure
Section titled “URL Structure”Category pages are accessible at:
/categories/:slug
For example: /categories/news, /categories/announcements
Template Variables
Section titled “Template Variables”The category template receives these variables:
The category Object
Section titled “The category Object”| Property | Type | Description |
|---|---|---|
id | string | Unique identifier |
title | string | Category name |
slug | string | URL-safe identifier |
The posts Array
Section titled “The posts Array”An array of all published posts in this category:
| Property | Type | Description |
|---|---|---|
posts | array | Posts belonging to this category |
Each post in the array has access to all standard post properties (title, description, publishDate, authors, image, etc.).
Basic Template Example
Section titled “Basic Template Example”{% layout 'layouts/default.liquid' %}
{% capture content_for_layout %}<div class="category-page"> <header class="category-header"> <h1>{{ category.title }}</h1> <p class="post-count">{{ posts.size }} {% if posts.size == 1 %}post{% else %}posts{% endif %}</p> </header>
<div class="posts-list"> {% if posts.size > 0 %} {% for post in posts %} <article class="post-card"> {% if post.image %} <img src="{{ post.image | image_url: width: 400, height: 250 }}" alt="{{ post.title }}" loading="lazy" > {% endif %}
<div class="post-card__content"> <h2> <a href="/posts/{{ post.slug }}">{{ post.title }}</a> </h2>
{% if post.publishDate %} <time datetime="{{ post.publishDate }}"> {{ post.publishDate | date: '%B %d, %Y' }} </time> {% endif %}
{% if post.description %} <p>{{ post.description | truncate: 150 }}</p> {% endif %} </div> </article> {% endfor %} {% else %} <p class="no-posts">No posts in this category yet.</p> {% endif %} </div></div>{% endcapture %}Working with Posts
Section titled “Working with Posts”Display Post Authors
Section titled “Display Post Authors”{% for post in posts %} <article class="post-item"> <h2><a href="/posts/{{ post.slug }}">{{ post.title }}</a></h2>
<div class="post-meta"> {% if post.authors.size > 0 %} <span class="author"> By {{ post.authors.first.name }} </span> {% endif %}
{% if post.publishDate %} <time datetime="{{ post.publishDate }}"> {{ post.publishDate | date: '%b %d, %Y' }} </time> {% endif %} </div> </article>{% endfor %}Featured Image with Fallback
Section titled “Featured Image with Fallback”{% for post in posts %} <article class="post-card"> {% if post.image %} <img src="{{ post.image | image_url: width: 400, height: 250 }}" alt="{{ post.title }}" class="post-card__image" loading="lazy" > {% elsif settings.global.fallbackImage %} <img src="{{ settings.global.fallbackImage | image_url: width: 400, height: 250 }}" alt="" class="post-card__image post-card__image--fallback" loading="lazy" > {% endif %}
<h3>{{ post.title }}</h3> </article>{% endfor %}Posts Grouped by Month
Section titled “Posts Grouped by Month”{% assign current_month = '' %}
{% for post in posts %} {% assign post_month = post.publishDate | date: '%B %Y' %}
{% if post_month != current_month %} {% unless current_month == '' %} </div> {% endunless %} <h3 class="month-header">{{ post_month }}</h3> <div class="month-posts"> {% assign current_month = post_month %} {% endif %}
<article class="post-item"> <a href="/posts/{{ post.slug }}">{{ post.title }}</a> <time>{{ post.publishDate | date: '%d' }}</time> </article>
{% if forloop.last %}</div>{% endif %}{% endfor %}Complete Template Example
Section titled “Complete Template Example”{% layout 'layouts/default.liquid' %}
{% capture content_for_layout %}<div class="category-page"> {# Breadcrumb navigation #} <nav class="breadcrumb" aria-label="Breadcrumb"> <ol> <li><a href="/">Home</a></li> <li><a href="/blog">Blog</a></li> <li aria-current="page">{{ category.title }}</li> </ol> </nav>
{# Category header #} <header class="category-header"> <h1>{{ category.title }}</h1> <p class="category-meta"> {{ posts.size }} {% if posts.size == 1 %}article{% else %}articles{% endif %} </p> </header>
{# Posts listing #} {% if posts.size > 0 %} <section class="category-posts"> {# Featured post (first/latest) #} {% assign featured = posts.first %} <article class="featured-post"> {% if featured.image %} <a href="/posts/{{ featured.slug }}" class="featured-post__image-link"> <img src="{{ featured.image | image_url: width: 1200, height: 500 }}" alt="{{ featured.title }}" > </a> {% endif %}
<div class="featured-post__content"> <h2> <a href="/posts/{{ featured.slug }}">{{ featured.title }}</a> </h2>
<div class="featured-post__meta"> {% if featured.publishDate %} <time datetime="{{ featured.publishDate }}"> {{ featured.publishDate | date: '%B %d, %Y' }} </time> {% endif %}
{% if featured.authors.size > 0 %} <span class="author">by {{ featured.authors.first.name }}</span> {% endif %} </div>
{% if featured.description %} <p class="featured-post__excerpt">{{ featured.description }}</p> {% endif %}
<a href="/posts/{{ featured.slug }}" class="btn">Read Article</a> </div> </article>
{# Remaining posts grid #} {% if posts.size > 1 %} <div class="post-grid"> {% for post in posts offset: 1 %} <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"> <h3 class="post-card__title">{{ post.title }}</h3>
<div class="post-card__meta"> {% if post.publishDate %} <time datetime="{{ post.publishDate }}"> {{ post.publishDate | date: '%b %d, %Y' }} </time> {% endif %} </div>
{% if post.description %} <p class="post-card__excerpt"> {{ post.description | truncate: 100 }} </p> {% endif %} </div> </a> </article> {% endfor %} </div> {% endif %} </section>
{% else %} <div class="category-empty"> <h2>No Articles Yet</h2> <p>There are no posts in the "{{ category.title }}" category yet. Check back soon!</p> <a href="/blog" class="btn btn--secondary">Browse All Posts</a> </div> {% endif %}
{# Navigation #} <nav class="category-nav"> <a href="/blog" class="back-link"> ← Back to Blog </a> </nav></div>{% endcapture %}
{% schema %}{ "name": "category", "settings": [ { "type": "checkbox", "name": "show_featured", "label": "Feature Latest Post", "defaultValue": true }, { "type": "select", "name": "layout", "label": "Posts Layout", "options": [ { "value": "grid", "label": "Grid" }, { "value": "list", "label": "List" } ], "defaultValue": "grid" } ]}{% endschema %}Linking to Categories
Section titled “Linking to Categories”From Post Templates
Section titled “From Post Templates”{# In post.liquid template #}{% if post.categories.size > 0 %} <div class="post-categories"> {% for category_name in post.categories %} <a href="/categories/{{ category_name | handleize }}" class="category-link"> {{ category_name }} </a> {% endfor %} </div>{% endif %}Category Navigation
Section titled “Category Navigation”{# Display all categories #}{% if all_categories.size > 0 %} <nav class="category-nav"> <h3>Categories</h3> <ul> {% for cat in all_categories %} <li> <a href="/categories/{{ cat.slug }}">{{ cat.title }}</a> </li> {% endfor %} </ul> </nav>{% endif %}Alternate Category Templates
Section titled “Alternate Category Templates”Create variations for different category presentations:
templates/├── category.liquid # Default category template├── category.featured.liquid # Hero-style featured layout├── category.compact.liquid # Compact list view└── category.archive.liquid # Archive-style chronological