Basic Output
Use double braces to output expressions:
{{ name }}
{{ user.email }}
{{ items[0] }}
{{ 1 + 2 }}
Attribute Access
Access object attributes with dot notation:
{{ user.name }}
{{ page.metadata.title }}
For dictionary keys:
{{ data.key }}
{{ data["key-with-dashes"] }}
Dict-Safe Resolution
For dict objects, dot notation resolves to dictionary keys first, then falls back to attributes. This means{{ data.items }} returns data["items"] (your data), not the dict.itemsmethod:
{# data = {"items": ["a", "b"], "keys": ["x", "y"]} #}
{{ data.items }} {# → ["a", "b"] — the key, not dict.items() #}
{{ data.keys }} {# → ["x", "y"] — the key, not dict.keys() #}
For non-dict objects (dataclasses, custom classes), dot notation uses getattr first, then falls back to subscript. This is the safe default for objects with __getitem__.
Jinja2 difference: Jinja2 always tries
getattrfirst regardless of type, so{{ data.items }}resolves to thedict.itemsmethod. Kida handles this correctly for dicts.
Index Access
Access sequence items by index:
{{ items[0] }}
{{ items[-1] }} {# Last item #}
{{ matrix[0][1] }}
HTML Escaping
By default, output is HTML-escaped for security:
{{ "<script>" }}
Output: <script>
Mark Content as Safe
Use thesafefilter for trusted HTML:
{{ html_content | safe }}
Or with an optional reason for code review:
{{ cms_block | safe(reason="sanitized by bleach") }}
Pipelines
Chain filters with the pipe operator:
{{ name | upper }}
{{ title | escape | truncate(50) }}
Use the pipeline operator |>for improved readability:
{{ title |> escape |> upper |> truncate(50) }}
Both syntaxes are equivalent:
{# Traditional pipe #}
{{ items | sort(attribute='date') | first }}
{# Pipeline operator #}
{{ items |> sort(attribute='date') |> first }}
Default Values
Handle missing or None values:
{{ user.nickname | default("Anonymous") }}
{{ count | default(0) }}
Shorthand dalias:
{{ missing | d("fallback") }}
Expressions
Full Python expressions are supported:
{{ price * 1.1 }}
{{ "Hello, " + name }}
{{ items | length > 0 }}
{{ value if condition else fallback }}
String Literals
Use single or double quotes:
{{ "Hello" }}
{{ 'World' }}
{{ "It's fine" }}
{{ 'Say "hi"' }}
Method Calls
Call methods on objects:
{{ name.upper() }}
{{ items.count(x) }}
{{ text.split(',')[0] }}
Global Functions
Built-in functions available in all templates:
{{ range(10) }}
{{ len(items) }}
{{ dict(a=1, b=2) }}
Available globals: range, dict, list, set, tuple, len, str, int, float, bool, abs, min, max, sum, sorted, reversed, enumerate, zip, map, filter.
See Also
- Filters — Transform output values
- Control Flow — Conditionals and loops
- Filter Reference — All built-in filters