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

# Variables & Templates

> Learn how to use variable placeholders and Jinja2 templates to create dynamic workflows

## Overview

Jinba Flow supports powerful templating capabilities that allow you to:

* Reference results from previous steps
* Access configured secrets securely
* Use Jinja2 templates for complex logic
* Create dynamic, reusable workflows

## Variable Placeholders

### Basic Syntax

Variables are enclosed in double curly braces: `{{ variable }}`

### Available Variables

| Variable                            | Description                   | Example                             |
| ----------------------------------- | ----------------------------- | ----------------------------------- |
| `steps.<step_id>.result`            | Result from a previous step   | `{{steps.fetch_data.result}}`       |
| `steps.<step_id>.result.<property>` | Specific property from result | `{{steps.api_call.result.content}}` |
| `secrets.<secret_name>`             | Configured workspace secret   | `{{secrets.API_KEY}}`               |
| `item`                              | Current item in forEach loop  | `{{item}}`                          |
| `item.<property>`                   | Property of current item      | `{{item.id}}`                       |

### Accessing Step Results

```yaml theme={null}
# Access entire result
- name: data
  value: "{{steps.previous_step.result}}"

# Access specific property
- name: content
  value: "{{steps.llm_response.result.content}}"

# Access nested property
- name: user_email
  value: "{{steps.get_user.result.user.email}}"

# Access array element
- name: first_item
  value: "{{steps.get_list.result[0]}}"
```

### Using Secrets

Secrets are configured at the workspace level and accessed securely:

```yaml theme={null}
config:
  - name: api_key
    value: "{{secrets.OPENAI_API_KEY}}"
  - name: token
    value: "{{secrets.GITHUB_TOKEN}}"
```

**Security Notes**:

* Secrets are encrypted at rest
* Never hardcode sensitive values in workflows
* Use secrets for API keys, tokens, and credentials

## Jinja2 Templates

Jinba Flow supports full Jinja2 templating for advanced logic. Templates are processed before step execution.

### Control Structures

#### For Loops

```yaml theme={null}
value: |
  items = []
  {%- for user in steps.get_users.result %}
  items.append({
    "id": "{{user.id}}",
    "name": "{{user.name}}"
  })
  {%- endfor %}
```

#### Conditional Statements

```yaml theme={null}
value: |
  {%- if steps.check.result.status == 'success' %}
  print("Processing successful")
  {%- else %}
  print("Handling error")
  {%- endif %}
```

#### Loop with Index

```yaml theme={null}
value: |
  {%- for item in items %}
  {{loop.index}}: {{item}}
  {%- endfor %}
```

### Built-in Functions

Jinja2 provides useful built-in functions:

```yaml theme={null}
# zip - Combine multiple lists
{%- for a, b in zip(list1, list2) %}
{{a}}: {{b}}
{%- endfor %}

# range - Generate number sequence
{%- for i in range(5) %}
Item {{i}}
{%- endfor %}

# length/count
Total: {{items|length}}
```

### Filters

Apply transformations to values:

```yaml theme={null}
# String manipulation
{{ variable | upper }}
{{ variable | lower }}
{{ variable | trim }}
{{ variable | replace('old', 'new') }}

# Default values
{{ variable | default('fallback_value') }}

# JSON handling
{{ data | tojson }}

# List operations
{{ items | first }}
{{ items | last }}
{{ items | join(', ') }}
```

### Whitespace Control

Use `{%-` and `-%}` to control whitespace:

```yaml theme={null}
value: |
  {%- for item in items -%}
  {{item}}
  {%- endfor -%}
```

* `{%-` removes whitespace before the tag
* `-%}` removes whitespace after the tag

## Common Patterns

### Processing Lists

```yaml theme={null}
- id: process_items
  tool: PYTHON_SANDBOX_RUN
  input:
    - name: code
      value: |
        results = []
        {%- for item in steps.input_list.result %}
        results.append({
          "id": "{{item.id}}",
          "processed": True
        })
        {%- endfor %}
        result = results
```

### Conditional Data Selection

```yaml theme={null}
- id: select_data
  tool: PYTHON_SANDBOX_RUN
  input:
    - name: code
      value: |
        {%- if steps.config.result.mode == 'full' %}
        data = {{steps.full_data.result}}
        {%- else %}
        data = {{steps.summary_data.result}}
        {%- endif %}
        result = data
```

### Combining Multiple Sources

```yaml theme={null}
- id: merge_data
  tool: PYTHON_SANDBOX_RUN
  input:
    - name: code
      value: |
        combined = []
        {%- for user, order in zip(steps.users.result, steps.orders.result) %}
        combined.append({
          "user": "{{user.name}}",
          "order": "{{order.id}}"
        })
        {%- endfor %}
        result = combined
```

### Filtering Lists

```yaml theme={null}
value: |
  active_items = []
  {%- for item in items if item.status == 'active' %}
  active_items.append("{{item.name}}")
  {%- endfor %}
```

### Building Dynamic Prompts

```yaml theme={null}
- id: generate_prompt
  tool: LLM
  input:
    - name: prompt
      value: |
        Analyze the following items:
        {%- for item in steps.items.result %}
        - {{item.name}}: {{item.description}}
        {%- endfor %}
        
        Provide insights based on the above data.
```

## Best Practices

### Variable References

* Use descriptive step IDs for clarity
* Access only the properties you need
* Handle potential null/undefined values with defaults

### Templates

* Keep templates readable with proper indentation
* Use whitespace control for clean output
* Break complex logic into multiple steps

### Secrets

* Never log or expose secret values
* Use workspace-level secrets for team sharing
* Rotate secrets regularly

### Performance

* Avoid deeply nested templates
* Limit loop iterations
* Pre-process data when possible

## Troubleshooting

### Common Issues

**Variable not found**

* Check step ID spelling
* Ensure the referenced step runs before current step
* Verify the property path is correct

**Template syntax error**

* Check for balanced braces `{{ }}`
* Verify Jinja2 tag syntax `{% %}`
* Look for missing quotes in strings

**Unexpected output**

* Use debug steps to inspect intermediate values
* Check whitespace handling
* Verify data types (string vs object)

## Related

* [Step Module Options](/en/pages/basics/step-options) - forEach, when, needs
* [YAML Coding Panel](/en/pages/basics/manifest) - Complete YAML syntax
* [Debug](/en/pages/basics/debug) - Debugging workflows
