> ## Documentation Index
> Fetch the complete documentation index at: https://docs.endprompt.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Liquid Templating

> Master the template syntax for dynamic prompts

Endprompt uses [Liquid](https://shopify.github.io/liquid/) templating to create dynamic prompts. This lets you inject request data, apply transformations, and add conditional logic to your prompts.

## Basic Syntax

### Variable Output

Use double curly braces to output values:

```liquid theme={null}
{{ inputs.name }}
{{ inputs.text }}
{{ inputs.count }}
```

### Filters

Apply filters to transform values:

```liquid theme={null}
{{ inputs.name | upcase }}
{{ inputs.text | truncate: 100 }}
{{ inputs.items | size }}
```

### Tags

Use tags for logic and control flow:

```liquid theme={null}
{% if inputs.include_examples %}
Here are some examples:
{% endif %}
```

## Accessing Input Values

All input fields are available under `inputs`:

```liquid theme={null}
Customer name: {{ inputs.customer_name }}
Order ID: {{ inputs.order_id }}
Items: {{ inputs.items | join: ", " }}
```

### Default Values

Use the `default` filter for optional fields:

```liquid theme={null}
Language: {{ inputs.language | default: "English" }}
Max length: {{ inputs.max_length | default: 100 }}
```

<Tip>
  Always provide defaults for optional fields to ensure your prompt works even when values aren't provided.
</Tip>

## Common Filters

### String Filters

| Filter       | Description             | Example                                           |
| ------------ | ----------------------- | ------------------------------------------------- |
| `upcase`     | Convert to uppercase    | `{{ "hello" \| upcase }}` → `HELLO`               |
| `downcase`   | Convert to lowercase    | `{{ "HELLO" \| downcase }}` → `hello`             |
| `capitalize` | Capitalize first letter | `{{ "hello" \| capitalize }}` → `Hello`           |
| `truncate`   | Shorten with ellipsis   | `{{ "hello world" \| truncate: 8 }}` → `hello...` |
| `strip`      | Remove whitespace       | `{{ "  hello  " \| strip }}` → `hello`            |
| `replace`    | Replace text            | `{{ "hello" \| replace: "e", "a" }}` → `hallo`    |
| `split`      | Split into array        | `{{ "a,b,c" \| split: "," }}` → array             |

### Number Filters

| Filter       | Description  | Example                           |
| ------------ | ------------ | --------------------------------- |
| `plus`       | Add numbers  | `{{ 5 \| plus: 3 }}` → `8`        |
| `minus`      | Subtract     | `{{ 5 \| minus: 3 }}` → `2`       |
| `times`      | Multiply     | `{{ 5 \| times: 3 }}` → `15`      |
| `divided_by` | Divide       | `{{ 10 \| divided_by: 2 }}` → `5` |
| `round`      | Round number | `{{ 4.6 \| round }}` → `5`        |

### Array Filters

| Filter    | Description         | Example                            |
| --------- | ------------------- | ---------------------------------- |
| `size`    | Array length        | `{{ inputs.items \| size }}`       |
| `first`   | First element       | `{{ inputs.items \| first }}`      |
| `last`    | Last element        | `{{ inputs.items \| last }}`       |
| `join`    | Join with separator | `{{ inputs.items \| join: ", " }}` |
| `sort`    | Sort array          | `{{ inputs.items \| sort }}`       |
| `reverse` | Reverse order       | `{{ inputs.items \| reverse }}`    |
| `uniq`    | Remove duplicates   | `{{ inputs.items \| uniq }}`       |

## Control Flow

### If / Else

```liquid theme={null}
{% if inputs.tone == "formal" %}
Please respond in a formal, professional manner.
{% elsif inputs.tone == "casual" %}
Keep the response casual and friendly.
{% else %}
Use a neutral, balanced tone.
{% endif %}
```

### Unless

```liquid theme={null}
{% unless inputs.skip_examples %}
Here are some examples to guide you:
- Example 1
- Example 2
{% endunless %}
```

### Case / When

```liquid theme={null}
{% case inputs.format %}
  {% when "json" %}
    Return your response as valid JSON.
  {% when "markdown" %}
    Format your response using Markdown.
  {% when "plain" %}
    Return plain text without formatting.
  {% else %}
    Use your best judgment for formatting.
{% endcase %}
```

## Loops

### For Loop

```liquid theme={null}
Process the following items:
{% for item in inputs.items %}
- {{ forloop.index }}. {{ item }}
{% endfor %}
```

### Loop Variables

| Variable         | Description                 |
| ---------------- | --------------------------- |
| `forloop.index`  | Current iteration (1-based) |
| `forloop.index0` | Current iteration (0-based) |
| `forloop.first`  | True if first iteration     |
| `forloop.last`   | True if last iteration      |
| `forloop.length` | Total iterations            |

### Loop Example with Conditions

```liquid theme={null}
{% for category in inputs.categories %}
{% if forloop.first %}Categories to analyze:{% endif %}
  - {{ category | capitalize }}
{% if forloop.last %}
Please evaluate the content against all listed categories.
{% endif %}
{% endfor %}
```

## Working with Objects

Access nested properties with dot notation:

```liquid theme={null}
Customer: {{ inputs.customer.name }}
Address: {{ inputs.customer.address.city }}, {{ inputs.customer.address.country }}
```

### Iterate Over Object Properties

```liquid theme={null}
{% for item in inputs.metadata %}
  {{ item[0] }}: {{ item[1] }}
{% endfor %}
```

## Including Snippets

Reuse common template fragments with includes:

```liquid theme={null}
{% include 'json-output-instructions' %}
{% include 'tone-guidelines' %}
```

<Note>
  Snippets are defined in the Prompt Snippets section. See [Working with Snippets](/prompts/snippets) for details.
</Note>

## Real-World Examples

### Email Generator

```liquid theme={null}
Write a {{ inputs.tone | default: "professional" }} email for the following situation:

Subject: {{ inputs.subject }}
Recipient: {{ inputs.recipient_name }}
Context: {{ inputs.context }}

{% if inputs.key_points %}
Key points to include:
{% for point in inputs.key_points %}
- {{ point }}
{% endfor %}
{% endif %}

{% if inputs.max_length %}
Keep the email under {{ inputs.max_length }} words.
{% endif %}

Return the email with a clear subject line and body.
```

### Content Classifier

```liquid theme={null}
Classify the following {{ inputs.content_type | default: "text" }} into one of these categories:
{% for category in inputs.categories %}
- {{ category }}
{% endfor %}

Content to classify:
{{ inputs.content | truncate: 5000 }}

{% include 'json-output-instructions' %}

Return:
{
  "category": "selected category",
  "confidence": 0.0 to 1.0,
  "reasoning": "brief explanation"
}
```

### Multi-Language Support

```liquid theme={null}
{% case inputs.language %}
  {% when "es" %}
    Responde en español.
  {% when "fr" %}
    Répondez en français.
  {% when "de" %}
    Antworten Sie auf Deutsch.
  {% else %}
    Respond in English.
{% endcase %}

{{ inputs.instruction }}

Content: {{ inputs.content }}
```

## Best Practices

<AccordionGroup>
  <Accordion title="Always use defaults" icon="shield-check">
    Optional fields should have sensible defaults to prevent empty values in prompts.
  </Accordion>

  <Accordion title="Truncate long inputs" icon="scissors">
    Use `truncate` to prevent extremely long inputs from exceeding token limits.
  </Accordion>

  <Accordion title="Use includes for reusability" icon="copy">
    Common instructions (JSON formatting, tone guidelines) should be snippets.
  </Accordion>

  <Accordion title="Test edge cases" icon="flask">
    Test with empty arrays, missing optional fields, and unusual values.
  </Accordion>

  <Accordion title="Keep logic simple" icon="minimize">
    Complex logic is hard to debug. Keep conditionals straightforward.
  </Accordion>
</AccordionGroup>

## Debugging Templates

If your template isn't working:

1. Check the **rendered preview** in the prompt editor
2. Verify input field names match exactly
3. Test with simple values first
4. Check for typos in filter names
5. Ensure conditionals have proper `endif` / `endfor` tags

## Next Steps

<CardGroup cols={2}>
  <Card title="Create a Prompt" icon="plus" href="/prompts/create-prompt">
    Put your template skills to use
  </Card>

  <Card title="Prompt Snippets" icon="puzzle-piece" href="/prompts/snippets">
    Learn to create reusable template fragments
  </Card>
</CardGroup>
