Custom Fields
This page shows you how to use custom fields from ACF, MetaBox, JetEngine, and Pods in your Unblock templates.
Supported plugins
Unblock natively integrates with these custom field plugins — no configuration needed:
When one of these plugins is active, meta() automatically resolves values through that plugin's API. You don't need to change your expressions.
Basic usage
Use meta('key') on any provider that supports custom fields:
{{ post.meta('event_date') }}
{{ user.meta('company') }}
{{ term.meta('icon') }}
Nested values work with dot access:
{{ post.meta('address').city }}
{{ post.meta('address').zip }}
Check if a field exists before using it:
{{ post.has_field('subtitle') ? post.meta('subtitle') : '' }}
meta('key') vs meta.key
meta('key') resolves a single field — one integration hook call.
meta.key resolves all meta fields for the object, triggering the integration hook for each one. With plugins like ACF active, this adds up.
Prefer meta('key') when you need specific fields.
{{ post.meta('event_date') }} {# Recommended — single hook call #}
{{ post.meta.event_date }} {# Resolves all fields first #}
raw_meta('key') bypasses integrations entirely:
{{ post.raw_meta('field_name') }}
Options
Options are passed as named arguments to meta().
return_format
Controls how choice fields (select, checkbox, radio) return their value.
{{ post.meta('color') }} {# Stored value: "red" #}
{{ post.meta('color', return_format: 'label') }} {# Display label: "Red" #}
{{ post.meta('color', return_format: 'value') }} {# Stored value: "red" #}
separator
For multi-value choice fields, controls the string joining selected values. Defaults to ', '.
{{ post.meta('tags', return_format: 'label', separator: ' | ') }}
{# Output: "Design | Code | Writing" #}
format_value
ACF only. Controls whether ACF formats the value or returns the raw database value.
{{ post.meta('wysiwyg_field') }} {# Formatted HTML #}
{{ post.meta('wysiwyg_field', format_value: false) }} {# Raw content #}
Defaults to true. Set to false when you need the raw stored value — useful for fields where ACF's formatting gets in the way.
Relational fields
When a custom field stores a relationship to another object (post, user, term, or attachment), Unblock automatically converts the value to a provider you can chain.
Supported field types
| Plugin | Field type | Resolves to |
|---|---|---|
| ACF | Post Object, Relationship | Post |
| ACF | User | User |
| ACF | Taxonomy | Term |
| ACF | Image, File, Gallery | Image / Attachment |
| MetaBox | Post | Post |
| MetaBox | Image Advanced, File Advanced | Image / Attachment |
| JetEngine | Posts | Post |
| JetEngine | Media, Gallery | Image / Attachment |
| Pods | Relationship (post type) | Post |
| Pods | Relationship (user) | User |
| Pods | Relationship (taxonomy) | Term |
| Pods | File, Avatar | Image / Attachment |
Single value
When a field stores one object, the returned value is a full provider — chain any field it supports:
{{ post.meta('related_post').title }}
{{ post.meta('related_post').thumbnail.src('medium') }}
{{ post.meta('team_lead').name }}
{{ post.meta('primary_category').link }}
{{ post.meta('hero_image').src('large') }}
Multiple values
Fields configured for multiple values (ACF Relationship, Gallery, MetaBox Image Advanced, etc.) return an array. Use a Loop block to iterate:
{# In a Loop block with source: post.meta('gallery') #}
{{ item.src('medium') }}
{{ item.alt }}
You can also access a single item by index:
{{ post.meta('gallery')[0].src('large') }}
ACF options pages
ACF is the only integration that supports option meta. Fields registered on ACF options pages are available through the site provider:
{{ site.meta('company_phone') }}
{{ site.meta('footer_logo').src }}
{{ site.meta('social_links') }}
site.meta() only works with ACF options pages. MetaBox, Pods, and JetEngine fields are not available through site.meta() — use post.meta(), user.meta(), or term.meta() for those plugins.
Resolution chain
When multiple custom field plugins are active, Unblock queries them in a fixed priority order:
| Priority | Plugin | Scope |
|---|---|---|
| 10 | ACF | post, user, term, option |
| 20 | MetaBox | post, user, term |
| 30 | Pods | post, user, term |
| 40 | JetEngine | post, user, term |
The first plugin that recognizes the field returns the value — the rest are skipped. If no plugin claims the field, Unblock falls back to WordPress get_metadata().
This means if the same meta key is registered in both ACF and MetaBox, ACF wins. In practice this rarely matters since most sites use a single custom field plugin.
Security
Private meta keys (starting with _) are blocked by default. To allow specific private keys, use the unblock/data/allowed_meta_keys filter.
Next steps
- Post provider — all post fields including
meta() - User provider — user fields and meta
- Common Patterns — real-world template examples