Skip to main content

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

OperatorDescriptionExample
==Equalpost.post_status == 'publish'
!=Not equalpost.post_status != 'draft'
===Identical (strict)post.comment_count === 0
!==Not identical (strict)post.type !== 'page'
>Greater thanpost.tags|length > 0
<Less thanpost.categories|length < 3
>=Greater or equalpost.date('Y') >= '2024'
<=Less or equalpost.date('Y') <= '2025'
{% if post.category.slug == 'featured' %}
{% if post.comment_count > 0 %}
{% if post.date('Y') == '2026' %}
Strict vs loose

Use === and !== (strict) when you need to distinguish between 0, false, null, and empty strings. Use == and != for general comparisons.

Logical operators

OperatorDescriptionExample
andBoth must be truepost.thumbnail and post.excerpt
orAt least one must be truepost.type == 'post' or post.type == 'page'
xorExactly one must be truepost.thumbnail xor post.excerpt
notNegationnot post.thumbnail
{% if post.thumbnail and post.excerpt %}
{% if post.type == 'post' or post.type == 'page' %}
{% if post.thumbnail xor post.excerpt %}
{% if not post.thumbnail %}

Containment operators

OperatorDescriptionExample
inValue is in a listpost.post_status in ['publish', 'future']
not inValue is not in a listpost.post_status not in ['draft', 'trash']
starts withString starts withpost.title starts with 'How'
ends withString ends withpost.slug ends with '-draft'
{% if post.post_status in ['publish', 'future'] %}
{% if 'sale' in post.tags %}
{% if post.category.slug not in ['uncategorized', 'draft'] %}

Tests

Tests check a property of a value with is, or is not to negate:

TestDescriptionExample
is definedValue is not nullpost.meta('subtitle') is defined
is emptyValue is empty (null, false, 0, '', [])post.excerpt is empty
is nullValue is exactly nullpost.parent is null
is evenNumber is evenloop.index is even
is oddNumber is oddloop.index is odd
is iterableValue can be looped overpost.tags is iterable
is sequenceValue is a list (sequential array)post.tags is sequence
is mappingValue is a map (keyed array or object)post.meta('data') is mapping
is divisible by(n)Number divides evenly by nloop.index is divisible by(3)
is same as(x)Strictly identical, type and valuepost.comment_count is same as(0)
{% if post.thumbnail is not empty %}
{% if loop.index is divisible by(2) %}
{% if post.excerpt is defined and post.excerpt is not empty %}

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 %}
Common mistake

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