Operators in Liquid enable comparisons and logical operations within conditional statements. They're the building blocks that make your templates dynamic, allowing you to create conditions that determine what content gets displayed based on your data.
What are Liquid operators?
Operators are symbols and keywords that let you compare values and combine conditions in your Liquid templates. Understanding operators is essential before diving into filters and tags because they form the foundation of conditional logic, the decision-making layer that makes your notifications intelligent and context-aware.
There are three main categories of operators in Liquid:
- Comparison operators evaluate relationships between values.
- Logical operators combine multiple conditions.
- Special operators handle specific scenarios like string containment.
Let's explore each category with practical notification examples.
Comparison operators
Comparison operators let you evaluate how two values relate to each other. These operators return either true or false, which you can use in conditional statements to control what content appears.
Equality operators
Equality operators check whether values are equal or not equal. These are the most basic comparisons you'll use:
- Equal to (
==): Returnstruewhen both values are the same. - Not equal to (
!=): Returnstruewhen values are different.
{
"user": {
"subscription_status": "active",
"account_type": "premium"
}
}{% if user.subscription_status == "active" %}
Your subscription is currently active.
{% endif %}
{% if user.account_type != "free" %}
Thank you for being a paid subscriber!
{% endif %}Your subscription is currently active.
Thank you for being a paid subscriber!Relational operators
Relational operators compare numeric values or evaluate size relationships. These are particularly useful for checking thresholds, limits, and ranges:
- Greater than (
>): Returnstruewhen the left value is larger than the right. - Less than (
<): Returnstruewhen the left value is smaller than the right. - Greater than or equal to (
>=): Returnstruewhen the left value is larger than or equal to the right. - Less than or equal to (
<=): Returnstruewhen the left value is smaller than or equal to the right.
{
"user": {
"account_balance": 1500,
"messages_sent": 4500,
"message_limit": 5000
}
}{% if user.account_balance > 1000 %}
✓ You qualify for our premium features!
{% endif %}
{% if user.messages_sent >= 4500 %}
⚠️ You're approaching your monthly message limit.
{% endif %}
{% if user.messages_sent < user.message_limit %}
You have {{ user.message_limit | minus: user.messages_sent }} messages remaining.
{% endif %}✓ You qualify for our premium features!
⚠️ You're approaching your monthly message limit.
You have 500 messages remaining.Logical operators
Logical operators let you combine multiple conditions to create more sophisticated conditional logic.
The and operator
Use and when all conditions must be true:
{
"user": {
"is_verified": true,
"profile_complete": true,
"payment_method": "visa"
}
}{% if user.is_verified and user.profile_complete and user.payment_method %}
🎉 Your account is fully activated! You're ready to go.
{% else %}
Please complete your account setup to continue.
{% endif %}🎉 Your account is fully activated! You're ready to go.The or operator
Use or when at least one condition must be true:
{
"user": {
"plan": "premium",
"total_spent": 850,
"referral_count": 3
}
}{% if user.plan == "premium" or user.total_spent > 1000 %}
You have access to priority support.
{% endif %}
{% if user.total_spent > 500 or user.referral_count >= 3 %}
You've unlocked access to our beta features!
{% endif %}You have access to priority support.
You've unlocked access to our beta features!Combining logical operators
You can combine and and or operators, though be mindful that Liquid evaluates them left-to-right:
{
"order": {
"items_count": 5,
"total": 89.99,
"is_first_order": true,
"customer_tier": "gold"
}
}{% if order.items_count >= 5 and order.total < 100 %}
You've unlocked bulk discount pricing!
{% endif %}
{% if order.is_first_order and order.total > 50 or order.customer_tier == "gold" %}
Free shipping applied to your order!
{% endif %}You've unlocked bulk discount pricing!
Free shipping applied to your order!Special operators
Liquid provides special operators for common string and array operations.
The contains operator
The contains operator checks whether a string includes a substring or an array includes an element:
{
"user": {
"email": "[email protected]",
"features": [
"api_access",
"sso",
"custom_domain"
],
"tags": [
"beta_tester",
"early_adopter"
]
}
}{% if user.email contains "@company.com" %}
Welcome, team member! You have access to internal tools.
{% endif %}
{% if user.features contains "api_access" %}
Your API key: xxx-xxx-xxx
{% endif %}
{% unless user.tags contains "premium" %}
Upgrade to premium for advanced features.
{% endunless %}Welcome, team member! You have access to internal tools.
Your API key: xxx-xxx-xxx
Upgrade to premium for advanced features.Understanding truthy and falsy values
Liquid's truthiness rules determine how values are evaluated in conditional contexts. This is particularly important for notifications where you need to handle various data states correctly.
Falsy values in Liquid
Only two values are falsy in Liquid:
nil(ornull)false
Everything else is truthy, which can be surprising if you're coming from other programming languages:
- Empty strings
""are truthy - Zero
0is truthy - Empty arrays
[]are truthy
{
"user": {
"phone_number": null,
"bio": "",
"login_count": 0,
"achievements": []
}
}{% if user.phone_number %}
SMS: {{ user.phone_number }}
{% else %}
No phone number on file
{% endif %}
{% if user.bio %}
Bio: {{ user.bio }}
(Note: Empty strings are truthy!)
{% endif %}
{% if user.login_count %}
Login count: {{ user.login_count }}
(Note: Zero is truthy!)
{% endif %}
{% if user.achievements %}
(Note: Empty arrays are truthy!)
Achievements exist: {{ user.achievements.size }} achievements
{% endif %}No phone number on file
Bio:
(Note: Empty strings are truthy!)
Login count: 0
(Note: Zero is truthy!)
(Note: Empty arrays are truthy!)
Achievements exist: 0 achievementsDefensive checks
Because of these truthiness rules, it's important to check explicitly for the conditions you care about:
{
"user": {
"bio": "",
"age": 0,
"notifications": []
}
}{# Check for nil explicitly #}
{% if user.phone_number != nil %}
SMS enabled
{% endif %}
{# Check for empty strings #}
{% if user.bio != "" %}
Bio: {{ user.bio }}
{% else %}
No bio provided
{% endif %}
{# Check for zero #}
{% if user.age > 0 %}
Age: {{ user.age }}
{% endif %}
{# Check array size #}
{% if user.notifications.size > 0 %}
You have notifications
{% else %}
No new notifications
{% endif %}No bio provided
No new notificationsThe unless tag with operators
The unless tag is the inverse of if—it executes when a condition is false:
{
"user": {
"email_verified": false,
"age": 16,
"country": "US"
}
}{% unless user.email_verified %}
⚠️ Please verify your email address to continue.
{% endunless %}
{% unless user.age >= 18 %}
This content is restricted to users 18 and older.
{% endunless %}
{% unless user.country == "US" %}
International shipping rates apply.
{% endunless %}⚠️ Please verify your email address to continue.
This content is restricted to users 18 and older.Putting operators together
Operators work together to create sophisticated conditional logic in your templates:
{
"user": {
"trial_days_remaining": 2,
"has_payment_method": false,
"total_users_invited": 5,
"conversion_rate": 0.15
}
}{% if user.trial_days_remaining > 0 and user.trial_days_remaining <= 3 %}
⏰ Your trial ends in {{ user.trial_days_remaining }} days.
{% unless user.has_payment_method %}
Add a payment method to avoid service interruption.
{% endunless %}
{% endif %}
{% if user.total_users_invited >= 5 and user.conversion_rate > 0.1 %}
🌟 Great referral performance! You've earned a bonus.
{% endif %}⏰ Your trial ends in 2 days.
Add a payment method to avoid service interruption.
🌟 Great referral performance! You've earned a bonus.Understanding operators is fundamental to writing effective Liquid templates. They allow you to create dynamic, context-aware content that responds intelligently to your data. As you move into filters and tags in the next chapters, you'll use these operators extensively to build sophisticated notification logic.