---
title: "Liquid in every field - Workflow Suite"
description: "Every text field of every step is a Liquid template: outputs, filters, if and for, dates and maths, and the json filter for valid JSON."
canonical: "https://docs.workflow-suite.app/liquid-in-fields"
---

# Liquid in every field

Every text field of every step is a **Liquid** template, the same template language Shopify themes use. A plain variable is the simplest case. Filters, conditions and loops work in the same field.

## Outputs and filters

An output is written in double curly braces. A filter changes the value. Filters are chained with the pipe character:

```liquid
{{ event.payload.email | downcase }}
{{ event.payload.title | truncate: 40 }}
{{ event.payload.note | default: "no note" }}
```

## Filters that matter in workflows

| Filter | Use |
| --- | --- |
| `json` | Writes a value as JSON, with quotes and escaping. The most important one: see below |
| `parse_json` | Turns JSON text into an object or a list |
| `default` | A fallback for an empty value |
| `date` | Formats a date, for example with `'%Y-%m-%d'`. The word `'now'` is the current time |
| `plus`, `minus`, `times`, `divided_by`, `round` | Maths. `times: 1` turns text such as `"49.90"` into a number |
| `append`, `prepend`, `replace`, `remove` | Build text |
| `upcase`, `downcase`, `capitalize`, `strip` (or `trim`) | Tidy text |
| `split`, `join`, `first`, `last`, `size` | Lists |
| `map`, `where`, `sort`, `uniq`, `concat` | Work on lists of objects, for example all SKUs of an order |
| `url_encode`, `escape` | Values inside URLs and HTML |

An unknown filter is an error, not silently ignored, so a typing mistake shows up in the first test.

## JSON and the json filter

Many fields expect JSON: the body of an HTTP request, **Variables (JSON)** of a Shopify step, **Input (JSON)** of a code step, **Payload (JSON)**. Text from your store can contain quotes and line breaks, and that breaks JSON written by hand.

Wrong, breaks as soon as a title contains a quote:

```liquid
{ "title": "{{ event.payload.title }}" }
```

Right. The filter escapes the text and adds the quotes itself, so you write none:

```liquid
{ "title": {{ event.payload.title | json }} }
```

It works for everything: a number stays a number, an empty value becomes `null`, an object or a list is written in full:

```liquid
{ "order": {{ event.payload | json }}, "skus": {{ event.payload.line_items | map: "sku" | json }} }
```

Objects and lists print as JSON even without the filter, and an empty value prints nothing. Inside JSON, still use the filter, so that an empty value becomes `null` instead of a gap.

## Keeping the type

A field that is exactly ONE output keeps the value's type. This hands a real list to **Repeat for each**, not text:

```liquid
{{ steps.orders.output.orders.nodes }}
```

As soon as there is anything else in the field, the result is text.

## if and for

A condition compares values. It cannot use a filter, so work the value out first with `assign`:

```liquid
{% assign total = event.payload.total_price | times: 1 %}
{% if total > 500 and event.payload.currency == "EUR" %}Priority order{% else %}Order{% endif %} {{ event.payload.name }}
```

A loop, for the lines of an email or of a CSV file:

```liquid
{% for line in event.payload.line_items %}{{ line.quantity }} x {{ line.title }}
{% endfor %}
```

In JSON, mind the comma between entries:

```liquid
[{% for line in event.payload.line_items %}{{ line.sku | json }}{% unless forloop.last %},{% endunless %}{% endfor %}]
```

## Dates

```liquid
{{ 'now' | date: '%Y-%m-%d' }}
{{ event.payload.created_at | date: '%d.%m.%Y %H:%M' }}
{{ 'now' | date: '%s' | minus: 1209600 | date: '%Y-%m-%d' }}
```

The last line is the date 14 days ago: the time in seconds, minus 14 days in seconds, formatted again. The maintenance templates use it in a Shopify search.

## Limits

- A field's template can be 100 KB, and must finish within 2 seconds.
- Including other templates (`render`, `include`) is not available.
- A missing value renders as nothing and does not fail the step. See [Variables and the variable picker](https://docs.workflow-suite.app/variables.md).
- Conditions do not use templates. Their **Field** is a plain path such as `event.payload.vendor`. See [Conditions](https://docs.workflow-suite.app/conditions.md).

For a whole script that reads and changes your store in Liquid, see [Liquid script step](https://docs.workflow-suite.app/liquid-step.md).
