Overview
The Blog extension adds a blog surface to the storefront: posts with authors and categories, a listing with pagination, an RSS feed, and a comment thread under each post. When the extension is enabled, a page or reusable block rendered under the blog base path (default /blog) reads blog values with single-brace tokens and repeats posts with {each} loops. The tokens resolve only on blog routes, so the same token on an ordinary page renders nothing.
Page tokens
| Token | Meaning | Example |
|---|---|---|
{blog.title} | Title of the blog, or the current post on a single-post page. | <h1>{blog.title}</h1> |
{blog.description} | Description from the blog settings. | <p>{blog.description}</p> |
{blog.base_url} | Base path of the blog, for example /blog. | <a href="{blog.base_url}">All posts</a> |
{blog.page} | Current page number in the listing. | <span>Page {blog.page}</span> |
{blog.pagination} | Newer and older links as HTML. Empty when there is no other page. | <div>{blog.pagination}</div> |
{blog.comments} | Approved comments and the comment form as HTML. Empty when comments are off. | <div>{blog.comments}</div> |
{blog.search} | Search form as HTML. | <div>{blog.search}</div> |
{blog.query} | Search query text from the current URL. | <p>Results for {blog.query}</p> |
{blog.pagination}, {blog.comments}, and {blog.search} contain ready-made HTML, so place them as content and do not wrap them in a script tag or an attribute.
Loops
Repeat a block once for each item. Every loop accepts limit=<n> and offset=<n>, and closes with {/each} or {/each <collection>}.
| Loop | Iterates over | Default alias | Available on |
|---|---|---|---|
{each blog_posts as=post} | Posts in the listing, or the recent posts on a single post. | post | Listing and single post |
{each blog_post_related as=related} | Posts related to the current post. | related | Single post |
{each blog_categories as=category} | Blog categories. | category | Listing and single post |
See Posts and comments for the fields each loop exposes.
Presence conditions
Test a collection before rendering it, so an empty blog or a post without comments leaves no empty wrapper.
| Condition | True when |
|---|---|
{if blog_posts} | The page has at least one post. |
{if blog_post} | The page is a single post. |
{if blog_post_related} | The post has at least one related post. |
{if blog_categories} | At least one category exists. |
{if blog_comments} | The post has comments output to render. |
Example: listing page
<h1>{blog.title}</h1>
<p>{blog.description}</p>
{blog.search}
{each blog_posts as=post}
<article>
<h2><a href="{post.url}">{post.title}</a></h2>
<p>{post.excerpt}</p>
</article>
{/each blog_posts}
{blog.pagination}

