Post
Access current post data. Available on single post/page views and inside Loop blocks (via the loop data alias).
All Fields
| Field | Arguments | Returns | Description |
|---|---|---|---|
id | — | int | Post ID |
title | — | string | Post title |
slug | — | string | Post name (URL slug) |
format | — | string | false | Post format slug, false when no format |
excerpt | {options} | string | Post excerpt (chainable builder) |
content | page, len, remove_blocks | string | Post content (filtered) |
paged_content | — | string | Current page content (for paginated posts) |
link | — | string | Permalink URL |
path | — | string | URL path only |
edit_link | — | string | null | Admin edit URL (null when not authorized) |
date | date_format | string | Publish date |
time | time_format | string | Publish time |
timestamp | — | int | Unix timestamp |
modified_date | date_format | string | Last modified date |
modified_time | time_format | string | Last modified time |
modified_timestamp | — | int | Modified unix timestamp |
author | — | User | Post author |
modified_author | — | User | Last editor |
thumbnail | — | Image | Featured image |
thumbnail_id | — | int | Featured image ID, 0 if none |
category | — | Term | Primary category (comparable to a string) |
categories | — | array | All categories |
tags | — | array | All tags |
terms | query_args, options | array | Terms from taxonomy |
has_term | term_name_or_id, taxonomy | bool | Check if has term |
type | — | string | Post type slug, chainable to .labels.* |
parent | — | Post | false | Parent post (false if no parent) |
ancestors | — | array | Ancestor posts |
children | args | array | Child posts |
next | in_same_term | Post | false | Next post (false if none) |
prev | in_same_term | Post | false | Previous post (false if none) |
comments | count, order, type, status | iterable | Post comments (chainable) |
comment_count | — | int | Number of comments |
can_edit | — | bool | Current user can edit |
password_required | — | bool | Password protected |
pagination | — | object | Pagination data for paginated posts |
gallery | html | array | Galleries in the content |
post_class | class | string | CSS classes |
meta | field_name | mixed | Post meta value |
raw_meta | field_name | mixed | Meta value, without plugins |
has_field | field_name | bool | Check if field exists |
Raw Database Fields
Direct read access to the underlying WP_Post columns — useful when you need the exact stored value (no filtering, no formatting):
| Field | Returns | Description |
|---|---|---|
ID | int | Post ID (alias of id) |
post_title | string | Title (raw) |
post_name | string | Slug (alias of slug) |
post_author | string | Author user ID (numeric string) |
post_type | string | Post type slug |
post_parent | int | Parent post ID, 0 if none |
post_status | string | publish, draft, pending, private, etc. |
post_date / post_date_gmt | string | Publish date in YYYY-MM-DD HH:MM:SS |
post_modified / post_modified_gmt | string | Modified date in YYYY-MM-DD HH:MM:SS |
post_mime_type | string | MIME type (mainly for attachments) |
post_content | string | Raw post content, as HTML |
post_excerpt | string | Raw post excerpt, as HTML |
comment_status | string | 'open' or 'closed' |
menu_order | int | Manual order value |
post_content and post_excerpt are empty when the visitor can't read the post or it's password protected. meta and raw_meta without a key give all the meta as a map; raw_meta skips the custom field plugins.
Content
content
Arguments:
page— Page number for paginated content (default: 0 = all)len— Word limit (default: -1 = no limit)remove_blocks— Remove block markup (default: false)
{{ post.content }}
{{ post.content(2) }} <!-- Page 2 only -->
{{ post.content(0, 50) }} <!-- Limit to 50 words, as plain text -->
{{ post.content(0, -1, true) }} <!-- Remove blocks -->
A word limit strips the HTML tags first.
excerpt
post.excerpt is a chainable builder. You can pass an options object or chain methods to refine it — both styles work and you can mix them.
Options object:
words— Word count (default: 50)chars— Character limit (overrides words)end— Suffix text (default:'…')force— Force from content even if excerpt exists (default: false)strip— Strip HTML tags (default: true)read_more— "Read more" link text (default: none)the_content— Use full WordPress excerpt filter (default: false, slower). The other options are then ignored.
{{ post.excerpt }}
{{ post.excerpt({words: 25}) }}
{{ post.excerpt({chars: 150}) }}
{{ post.excerpt({words: 30, end: '...'}) }}
{{ post.excerpt({force: true}) }}
{{ post.excerpt({read_more: 'Continue reading'}) }}
Chained methods:
{{ post.excerpt.length(25) }} <!-- 25 words -->
{{ post.excerpt.chars(150) }} <!-- 150 chars -->
{{ post.excerpt.length(30).end('...') }}
{{ post.excerpt.force(true) }}
{{ post.excerpt.read_more('Continue reading') }}
{{ post.excerpt.strip(true).length(20) }}
Dates
format: PHP date format string (default: WordPress setting)
{{ post.date }} <!-- Uses WP date format -->
{{ post.date('F j, Y') }} <!-- January 15, 2024 -->
{{ post.time }} <!-- Uses WP time format -->
{{ post.time('g:i a') }} <!-- 2:30 pm -->
{{ post.timestamp }} <!-- 1705330245 -->
{{ post.modified_date('Y-m-d') }}
Author
The author field returns a User object with all user fields.
{{ post.author.name }}
{{ post.author.avatar }}
{{ post.modified_author.name }}
post.author is also available as the root author variable. See User & Author for details.
Featured Image
The thumbnail field returns an Image object.
{{ post.thumbnail.src }}
{{ post.thumbnail.src('medium') }}
{{ post.thumbnail.alt }}
{{ post.thumbnail.width }}
{{ post.thumbnail_id }} <!-- 0 when no thumbnail -->
Post Type
post.type returns the post type slug — you can compare it directly to a string and chain into the post type object's labels:
{{ post.type }} <!-- 'post' or 'page' or CPT slug -->
{{ post.type.labels.singular_name }} <!-- 'Post' / 'Page' / etc. -->
Taxonomies
category / categories / tags / terms
Term references stringify to the term name and support direct comparison — no need to access .name explicitly:
{{ post.category }} <!-- 'News' -->
{{ post.category.link }}
{{ post.category.slug }}
terms
Arguments:
query_args— Taxonomy name, array of names,'all'(default), or a hash of term query arguments with ataxonomykey.tagandtagsstand forpost_tag,categoriesforcategory,anyforall.options—{merge: true}to combine or{merge: false}to group by taxonomy
terms returns a list: join it or loop over it.
{{ post.terms('genre')|map(t => t.name)|join(', ') }}
{{ post.terms(['category', 'tags'])|length }}
{{ post.terms({taxonomy: 'genre', orderby: 'name'})|map(t => t.name)|join(', ') }}
{{ post.terms('all', {merge: false})|keys|join(', ') }} <!-- category, post_tag, … -->
With {merge: false}, the result is a map from each taxonomy to its terms, which you can loop over with {% for taxonomy, terms in post.terms('all', {merge: false}) %}.
has_term
Arguments:
term_name_or_id— Term name, slug, or IDtaxonomy— Taxonomy name (default:'all')
{{ post.has_term('news') }}
{{ post.has_term('news', 'category') }}
{{ post.has_term(5, 'category') }}
Hierarchy
children
Arguments:
args— Post type to get,'parent'for same type, or query array (default:'any')
children returns a list: join it or loop over it.
{{ post.children|length }}
{{ post.children('page')|map(c => c.title)|join(', ') }}
{{ post.children('parent')|length }}
{{ post.children({post_type: 'page', orderby: 'title'})|map(c => c.title)|join(', ') }}
parent / next / prev
These return false (not null) when there's no adjacent post — match against the value before chaining:
{{ post.parent.title }}
{{ post.next.title }}
{{ post.next(true) }} <!-- Same category -->
{{ post.next('genre') }} <!-- Same genre term -->
{{ post.prev.title }}
{{ post.prev(true) }}
Comments
post.comments returns an iterable, chainable comment thread.
Arguments:
count— Number of comments (default: all)order—'ASC','DESC', or'wp'for WP setting (default:'wp')type— Comment type (default:'comment')status— Comment status (default:'approve')
'wp' follows Settings › Discussion, which shows the oldest comments first by default. Loop over the comments to display them:
{{ post.comments|length }}
{{ post.comments(5)|length }} <!-- First 5 in the Discussion order -->
{{ post.comments(10, 'DESC')|length }} <!-- Latest 10, newest first -->
{{ post.comments.order('DESC') }} <!-- Chainable order -->
{{ post.comments.orderby('comment_date') }} <!-- Chainable orderby -->
{{ post.comments.order('DESC').orderby('comment_date') }}
{{ post.comment_count }}
Comment author email, IP address, and user agent are stripped before iteration — they're never available in templates. Only public-facing comment data (author name, content, date, etc.) is exposed.
Other Fields
gallery
Arguments:
html— Return HTML galleries (default: true)
gallery returns the list of galleries found in the post content: their HTML by default, or with false one {ids, src} entry per gallery. Loop over it:
{% for gallery in post.gallery(false) %}
{{ gallery.src|length }} images
{% endfor %}
post_class
Arguments:
class— Extra class(es) to add
{{ post.post_class }}
{{ post.post_class('custom-class') }}
Custom Fields (Meta)
{{ post.meta('event_date') }}
{{ post.meta('address').city }}
{{ post.has_field('custom_field') }}
meta('key') integrates with ACF, MetaBox, JetEngine, and Pods — the plugin filter resolves the value through those frameworks when active. Private meta keys (starting with _) are blocked for security.
Common Patterns
Post card
{{ post.title }}
{{ post.excerpt({words: 25}) }}
{{ post.date('F j, Y') }}
{{ post.author.name }}
{{ post.thumbnail.src('medium') }}
Custom field with fallback
{{ post.meta('custom_title') ?: post.title }}
{{ post.meta('custom_excerpt') ?: post.excerpt }}
A missing custom field is an empty string, so ?: falls back where ?? wouldn't.
Post navigation
{% if post.prev %}<a href="{{ post.prev.link }}">{{ post.prev.title }}</a>{% endif %}
{% if post.next %}<a href="{{ post.next.link }}">{{ post.next.title }}</a>{% endif %}
Taxonomy list
{{ post.categories|map(c => c.name)|join(', ') }}
{{ post.tags|map(t => t.name)|join(', ') }}
Conditional featured image
{{ post.thumbnail ? post.thumbnail.src('large') : '/default.jpg' }}
{{ post.thumbnail.alt ?: post.title }}