Condition Expressions
This page covers everything you can write inside a Condition block — operators, nesting, and dynamic data.
A condition is any expression that evaluates to true or false. You type it in the Condition block's sidebar panel, and Unblock wraps your inner blocks with {% if expression %} / {% endif %}.
Existence
The simplest condition — check if a value exists and is not empty:
{% if post.thumbnail %}
{% if post.excerpt %}
{% if post.content %}
{% if user.id %} {# user.id is 0 for guests #}
An existence check returns false for null, false, 0, empty strings, and empty arrays.
Comparison operators
| Operator | Description | Example |
|---|---|---|
== | Equal | post.post_status == 'publish' |
!= | Not equal | post.post_status != 'draft' |
=== | Identical (strict) | post.comment_count === 0 |
!== | Not identical (strict) | post.type !== 'page' |
> | Greater than | post.tags|length > 0 |
< | Less than | post.categories|length < 3 |
>= | Greater or equal | post.date('Y') >= '2024' |
<= | Less or equal | post.date('Y') <= '2025' |
{% if post.category.slug == 'featured' %}
{% if post.comment_count > 0 %}
{% if post.date('Y') == '2026' %}
Use === and !== (strict) when you need to distinguish between 0, false, null, and empty strings. Use == and != for general comparisons.
Logical operators
| Operator | Description | Example |
|---|---|---|
and | Both must be true | post.thumbnail and post.excerpt |
or | At least one must be true | post.type == 'post' or post.type == 'page' |
not | Negation | not post.thumbnail |
{% if post.thumbnail and post.excerpt %}
{% if post.type == 'post' or post.type == 'page' %}
{% if not post.thumbnail %}
Containment operators
| Operator | Description | Example |
|---|---|---|
in | Value is in a list | post.post_status in ['publish', 'future'] |
not in | Value is not in a list | post.post_status not in ['draft', 'trash'] |
starts with | String starts with | post.title starts with 'How' |
ends with | String ends with | post.slug ends with '-draft' |
{% if post.post_status in ['publish', 'future'] %}
{% if 'sale' in post.tags %}
{% if post.category.slug not in ['uncategorized', 'draft'] %}
Nested conditions
Use parentheses to group logic and control evaluation order:
{% if post.post_status == 'publish' and (post.thumbnail or post.excerpt) %}
Without parentheses, and binds tighter than or. This means:
{# These are NOT the same: #}
{% if a and b or c %} {# → (a and b) or c #}
{% if a and (b or c) %} {# → a and (b or c) #}
You can nest as deep as needed:
{% if user.id and ('editor' in user.roles or ('author' in user.roles and post.author.id == user.id)) %}
Dynamic data in conditions
Conditions have full access to the same dynamic data you use in expressions — providers, methods, filters, and functions all work inside {% if %}.
Provider fields
Any field from any provider works in a condition:
{% if post.author.id == user.id %}
{% if site.language == 'fr' %}
{% if archive.type == 'category' %}
{% if 'administrator' in user.roles %}
Methods
Call methods with arguments:
{% if post.meta('is_featured') %}
{% if post.date('Y') == '2026' %}
Filters
Apply filters to transform values before comparing:
{% if post.title|length > 50 %}
{% if post.content|striptags|length > 1000 %}
{% if post.tags|length >= 3 %}
Variables
Use a Variable block to store a value, then check it in a Condition:
{% set subtitle = post.meta('subtitle') %}
{% if subtitle %}
<p class="subtitle">{{ subtitle }}</p>
{% endif %}
Math
Arithmetic works inside conditions:
{% if loop.index + 1 <= 5 %}
{% if loop.index % 2 == 0 %}
Filters like |length return a number, not a boolean. Writing {% if post.tags|length %} works (non-zero is truthy), but {% if post.tags|length > 3 %} is clearer about your intent.
Next steps
- Condition patterns — real-world recipes for common scenarios
- Condition overview — how the Condition block works
- Expressions & Syntax — full operator and precedence reference