> Version notice: This site documents BAML v0, the legacy DSL. BAML v1 is a separate, fully featured programming language in public beta. If the user intends to use BAML v1, ignore this site's content and use the BAML v1 documentation instead. If the intended version is unclear, clarify it before using this page.
> For clean Markdown of any page, append .md to the page URL. For the complete documentation index, see https://docs.boundaryml.com/llms.txt. For MCP access, connect to https://docs.boundaryml.com/_mcp/server.

# What is Jinja / Cookbook

BAML Prompt strings are essentially [Minijinja](https://docs.rs/minijinja/latest/minijinja/filters/index.html#functions) templates, which offer the ability to express logic and data manipulation within strings. Jinja is a very popular and mature templating language amongst Python developers, so Github Copilot or another LLM can already help you write most of the logic you want.

## Jinja Cookbook

When in doubt -- use the BAML VSCode Playground preview. It will show you the fully rendered prompt, even when it has complex logic.

### Basic Syntax

* `{% ... %}`: Use for executing statements such as for-loops or conditionals.
* `{{ ... }}`: Use for outputting expressions or variables.
* `{# ... #}`: Use for comments within the template, which will not be rendered.

### Loops / Iterating Over Lists

Here's how you can iterate over a list of items, accessing each item's attributes:

**`Jinja`**

```jinja Jinja
function MyFunc(messages: Message[]) -> string {
  prompt #"
    {% for message in messages %}
      {{ message.user_name }}: {{ message.content }}
    {% endfor %}
  "#
}
```

### Conditional Statements

Use conditional statements to control the flow and output of your templates based on conditions:

**`Jinja`**

```jinja Jinja
function MyFunc(user: User) -> string {
  prompt #"
    {% if user.is_active %}
      Welcome back, {{ user.name }}!
    {% else %}
      Please activate your account.
    {% endif %}
  "#
}
```

### Setting Variables

You can define and use variables within your templates to simplify expressions or manage data:

```jinja
function MyFunc(items: Item[]) -> string {
  prompt #"
    {% set total_price = 0 %}
    {% for item in items %}
      {% set total_price = total_price + item.price %}
    {% endfor %}
    Total price: {{ total_price }}
  "#
}
```

### Including other Templates

To promote reusability, you can include other templates within a template. See [template strings](/ref/baml/template-string):

```baml
template_string PrintUserInfo(arg1: string, arg2: User) #"
  {{ arg1 }}
  The user's name is: {{ arg2.name }}
"#

function MyFunc(arg1: string, user: User) -> string {
  prompt #"
    Here is the user info:
    {{ PrintUserInfo(arg1, user) }}
  "#
}
```

### String Formatting

BAML supports Python's new-style string formatting via the `.format()` method on strings. This uses `{}` placeholders (not `%s`-style).

```jinja
{# Basic substitution #}
{{ "{}, {}!".format("Hello", "World") }}
{# Output: Hello, World! #}

{# Number formatting with commas #}
{{ "{:,}".format(1234567) }}
{# Output: 1,234,567 #}

{# Fixed decimal places #}
{{ "{:.2f}".format(3.14159) }}
{# Output: 3.14 #}

{# Padding and alignment #}
{{ "{:<10}".format("left") }}
{{ "{:>10}".format("right") }}
{{ "{:^10}".format("center") }}
```

> **Note**
>
> Only new-style `{}` formatting is supported. Old-style `%s` formatting via the `|format` filter is **not** available because BAML uses the `|format` filter for [serializing objects](/ref/prompt-syntax/jinja-filters#format) (e.g. `value|format(type="yaml")`).

For a full reference of what's possible with Python's format specification, see [pyformat.info](https://pyformat.info/).

### Built-in filters

See [jinja docs](https://jinja.palletsprojects.com/en/3.1.x/templates/#list-of-builtin-filters)