Conditions and Loops
Last updated March 23, 2026
More often than not, you’ll need to display certain portions of content depending on the value of one or more data item, or repeat content for each entry in a list. Let’s see how this can be done using Liquid.
Using a simple “if”
The simplest condition you can use is an if statement:
{% if client.isNewClient == true %}
<p>Congrats on your first order!</p>
{% endif %}
The content will be displayed only when the condition is true.
Combining conditions
You can also combine several conditions using and and or
{% if client.isExistingClient == true and client.orderedRecently == true %}
<p>A fan of our brand, are we? :D</p>
{% endif %}
{% if client.isNewClient == true or client.orderedALongTimeAgo == true %}
<p>Congrats on your first order this year!</p>
{% endif %}
Inverse condition with “unless”
If you want to inverse the condition unless is your friend:
{% unless client.isNewClient %}
<p>Nice to see you again!</p>
{% endunless %}
In this case, the code would be equivalent to
{% if client.isNewClient != true %}
<p>Nice to see you again!</p>
{% endif %}
Doing both with “if … else”
A bit more frequent than unless the if ... else statement allows specifying both cases:
{% if client.isNewClient == true %}
<p>Congrats on your first order!</p>
{% else %}
<p>Nice to see you again!</p>
{% endif %}
Multiple conditions with “if … elsif … else”
There might be cases where you need to check for multiple conditions to find the right content. For these cases the if ... elsif ... else statement is the solution:
{% if client.isNewClient == true %}
<p>Congrats on your first order!</p>
{% elsif client.fullName == "Peter Parker" %}
<p>Welcome back Spide… hum… Mr Parker.</p>
{% else %}
<p>Nice to see you again {{client.fullName}}!</p>
{% endif %}
Dispatch according to a single variable
If you want to insert content according to the value of a single variable, you can trade the if ... elsif ... else statement with a simple case ... when ... end statement:
{% case client.fullName %}
{% when "Peter Parker" %}
<p>Welcome back Spide… hum… Mr Parker.</p>
{% when "Dianna Price" %}
<p>Nice to see you again WonderW… I mean… Miss Price.</p>
{% else %}
<p>Hello again {{client.fullName}}!</p>
{% endcase %}
Loops
Looping over lists is a very frequent need. Here are the essential aspects of iteration, but you can learn more in the official documentation.
for
Let’s use the data we defined in an earlier section:
{
"orderId": 1234,
"orderStatus": "pending",
"invoiceId": null,
"client": {
"civility": "Mr",
"fullName": "Peter Parker",
"isNewClient": true
},
"lineItems": [
{ "product": "Super strong silk", "quantity": 100, "price": 123.45 },
{ "product": "Electronic components", "quantity": 12, "price": 12.34 }
]
}
We can loop over the lineItems array to list our products using a for loop. It will repeat the code for each item in the array:
<table>
<tr>
<th>Product</th>
<th>Quantity</th>
<th>Unit Price</th>
<th>Total</th>
</tr>
{% for item in lineItems %}
<tr>
<td>{{item.product}}</td>
<td>{{item.quantity}}</td>
<td>${{item.price | with_delimiter, precision: 2}}</td>
<td>${{item.price | times: item.quantity | with_delimiter, precision: 2}}</td>
</tr>
{% endfor %}
</table>
The resulting HTML will look like this:
<table>
<tr>
<th>Product</th>
<th>Quantity</th>
<th>Unit Price</th>
<th>Total</th>
</tr>
<tr>
<td>Super strong silk<td>
<td>100</td>
<td>$123.45</td>
<td>$12,345.00</td>
</tr>
<tr>
<td>Electronic components</td>
<td>12</td>
<td>$12.34</td>
<td>$148.08</td>
</tr>
</table>
Data formatting
with_delimiter filter here. You can learn more in our documentation about Filters.The forloop object
Inside a for loop, you get access to a special object that stores the current state of the loop. It can be useful to build special cases for the first or last iteration, for instance.
{% for item in lineItems %}
{% if forloop.first == true %}
<p>{{item.product}} is the first item.</p>
{% elsif forloop.last == true %}
<p>{{item.product}} is the last item.</p>
{% else %}
<p>{{item.product}} is an item.</p>
{% endif %}
{% endfor %}
Learn more
forloop in the dedicated documentation, including things like index, index0 or length.Limiting and offsetting
You can control how many items a loop iterates over using limit and offset:
{% for item in lineItems limit: 1 %}
<p>First item: {{item.product}}</p>
{% endfor %}
{% for item in lineItems offset: 1 %}
<p>Remaining items: {{item.product}}</p>
{% endfor %}
You can also iterate in reverse order:
{% for item in lineItems reversed %}
<p>{{item.product}}</p>
{% endfor %}
Learn more
Related filters
When working with loops, these PDFMonkey filters are particularly useful:
- The slice_by filter — split an array into groups of N elements
- The where_exp filter — filter an array using an expression
Frequently asked questions
- How do I use conditions in PDFMonkey templates?
- Use Liquid conditional tags: {% if condition %}, {% elsif %}, {% else %}, and {% endif %} to show or hide content. You can also use {% unless %} for inverse conditions and {% case %} / {% when %} for multi-branch logic.
- How do I loop over data in PDFMonkey templates?
- Use the {% for item in list %} tag to repeat HTML for each entry in an array from your document payload. Inside the loop, access the forloop object for the current index, length, and first/last flags.
- Can I combine multiple conditions in PDFMonkey Liquid templates?
- Yes. Use 'and' to require all conditions to be true, or 'or' to require at least one. For example: {% if client.isNewClient == true and order.total > 100 %}.