Introduction
To convert an integer to a string in Jinja2, use the |string filter: {{ my_int|string }}. Jinja2 automatically converts values to strings in most output contexts ({{ }}), but explicit conversion is needed when you want to use string methods like concatenation, length, or startswith on a numeric value. The |string filter is the standard approach and works in all Jinja2 environments (Flask, Django, Ansible, Salt, etc.).
Basic Conversion with |string
1{# Variable: count = 42 #}
2
3{# Automatic string conversion in output #}
4<p>Count: {{ count }}</p>
5{# Output: <p>Count: 42</p> #}
6
7{# Explicit conversion with |string filter #}
8{{ count|string }}
9{# Output: 42 (as string) #}
10
11{# Why you need explicit conversion: string concatenation #}
12{{ "Item-" ~ count|string }}
13{# Output: Item-42 #}
14
15{# Without |string, ~ still works because Jinja auto-converts for ~ operator #}
16{{ "Item-" ~ count }}
17{# Output: Item-42 (also works) #}
When Explicit Conversion Is Needed
1{# String operations on numbers require conversion #}
2{% set port = 8080 %}
3
4{# Length of the number as a string #}
5{{ port|string|length }}
6{# Output: 4 #}
7
8{# Check if number starts with specific digits #}
9{% if port|string is matching("^80") %}
10 Port starts with 80
11{% endif %}
12
13{# Padding and formatting #}
14{{ port|string|center(10) }}
15{# Output: " 8080 " #}
16
17{# Joining a list that contains integers #}
18{% set codes = [200, 301, 404, 500] %}
19{{ codes|map('string')|join(', ') }}
20{# Output: 200, 301, 404, 500 #}
1{# Using format filter (like Python's str.format) #}
2{{ "Port: %d"|format(8080) }}
3{# Output: Port: 8080 #}
4
5{{ "Score: %.2f"|format(95.5) }}
6{# Output: Score: 95.50 #}
7
8{# Using ~ (tilde) for concatenation #}
9{% set id = 123 %}
10{{ "user_" ~ id }}
11{# Output: user_123 #}
12
13{# f-string style in Jinja2 (not real f-strings, but similar) #}
14{% set name = "Alice" %}
15{% set age = 30 %}
16{{ "%s is %d years old"|format(name, age) }}
17{# Output: Alice is 30 years old #}
1{# Integer to different bases #}
2{% set num = 255 %}
3Decimal: {{ num }}
4Hex: {{ "0x%x"|format(num) }}
5Octal: {{ "0o%o"|format(num) }}
6
7{# Thousands separator (Jinja2 doesn't have built-in) #}
8{# Use a custom filter or format #}
9{% set big_num = 1234567 %}
10{{ "{:,}".format(big_num) }}
11{# May not work in all Jinja2 environments #}
12
13{# In Flask/Ansible, use format filter #}
14{{ "%,d"|format(big_num) }}
In Ansible Templates
1# Ansible uses Jinja2 for templates
2# playbook.yml
3- name: Configure service
4 template:
5 src: config.j2
6 dest: /etc/app/config.ini
7
8# config.j2
9[server]
10port={{ http_port | string }}
11workers={{ ansible_processor_vcpus | string }}
12name=server-{{ inventory_hostname }}-{{ http_port | string }}
In Flask Templates
1# Flask app
2from flask import Flask, render_template
3
4app = Flask(__name__)
5
6@app.route('/')
7def index():
8 return render_template('page.html', count=42, items=[1, 2, 3])
1{# templates/page.html #}
2
3{# Direct output — auto-converts #}
4<span>{{ count }}</span>
5
6{# In conditionals comparing types #}
7{% if count|string == "42" %}
8 The answer!
9{% endif %}
10
11{# Building CSS classes with numbers #}
12<div class="col-{{ columns|string }}">Content</div>
13
14{# Building URLs #}
15<a href="/page/{{ page_num }}">Page {{ page_num }}</a>
16{# Auto-converts in {{ }} context #}
Converting Other Types
1{# Float to string #}
2{% set price = 19.99 %}
3{{ price|string }}
4{# Output: 19.99 #}
5
6{# Boolean to string #}
7{% set active = true %}
8{{ active|string }}
9{# Output: True #}
10
11{# String to integer (reverse) #}
12{% set port_str = "8080" %}
13{{ port_str|int }}
14{# Output: 8080 (as integer) #}
15
16{# String to float #}
17{{ "3.14"|float }}
18{# Output: 3.14 (as float) #}
19
20{# With default for invalid conversion #}
21{{ "abc"|int(default=0) }}
22{# Output: 0 #}
Common Pitfalls
Assuming + concatenates strings and numbers: Jinja2 + is addition for numbers and concatenation only for strings. "Item-" + 42 raises a TypeError. Use the ~ (tilde) operator for string concatenation, which auto-converts both sides to strings: "Item-" ~ 42.
Using |string when {{ }} already auto-converts: Inside {{ }} output blocks, Jinja2 automatically converts values to strings for display. {{ count|string }} and {{ count }} produce the same output. Only use |string when you need string methods (.length, .startswith) or when building strings in {% set %} blocks.
Forgetting |string in map() before join(): {{ [1, 2, 3]|join(', ') }} works in some Jinja2 versions but may fail in strict environments. Explicitly map to strings first: {{ [1, 2, 3]|map('string')|join(', ') }} for reliable behavior across all Jinja2 environments.
Using Python-style str() in Jinja2: Jinja2 templates do not have access to Python built-in functions by default. {{ str(count) }} raises UndefinedError. Use {{ count|string }} instead. To use Python builtins, they must be explicitly added to the template context.
Type comparison with == after conversion: {{ 42|string == 42 }} is False because you are comparing a string to an integer. Be consistent with types in comparisons: either compare count|string == "42" or count == 42, not mixed types.
Summary
Use {{ value|string }} to explicitly convert integers (or any type) to strings in Jinja2
Use ~ (tilde) for string concatenation — it auto-converts both operands to strings
{{ }} output blocks auto-convert to string, but {% %} logic blocks do not
Use |map('string')|join() to convert and join lists of numbers
Reverse conversion: |int for string-to-integer, |float for string-to-float, with optional default parameter