Overview of askama_macros
mainaskama_macros crate provides the procedural macros required by the Askama templating engine. These macros are responsible for the compile-time processing and generation of template code from template files.repository·main·Indexed 22 days ago
https://github.com/askama-rs/askamaA type-safe template rendering engine for Rust that uses Jinja-like syntax. Askama generates Rust code from templates at compile time to ensure templates are checked against data structures for maximum performance and safety. It supports template inheritance, control flow, macros, and custom escapers. The project includes auxiliary crates such as askama_escape for lightweight HTML/XML escaping and askama_macros for procedural macro processing.
askama_macros crate provides the procedural macros required by the Askama templating engine. These macros are responsible for the compile-time processing and generation of template code from template files.askama_escape crate provides lightweight HTML and XML escaping utilities for cases where a full template engine is not required. It specifically escapes the following characters: ", ', &, \, < and >.Instead of multiple {{ a }}{{ b }} blocks, you can use the tilde ~ operator for string concatenation: {{ a ~ b ~ c }}.
Important: The ~ operator must be surrounded by spaces to prevent confusion with the whitespace control operator.
{{ a ~ b ~ c }}askama::Escaper trait for it. Once the type is implemented and registered in askama.toml, Askama will use this logic when rendering templates associated with the configured extensions.Askama provides two primary filters for handling missing or default values, which are more expressive than the Jinja-compatible |default filter.
|assigned_or(fallback): Use this when the left-hand side is in a "default" state (e.g., an empty string "", 0, None, or an Err(_) result). It returns the fallback value in these cases.|defined_or(fallback): Use this specifically for identifiers. It returns the fallback value only if the identifier is undefined (not declared in the scope).{# assigned_or for default states #}
{% let greeting = Some("Hello") %}
{{ greeting.as_ref() | assigned_or("Hi") }} {# Output: Hello #}
{# defined_or for undefined identifiers #}
{{ greeting | defined_or("Hi") }} {# Output: Hello if greeting is defined, else Hi #}Filters post-process values using the pipe symbol (|). They can be chained, where the output of one filter is passed to the next.
Filter Blocks: You can apply a filter to an entire block of content using {% filter ... %} ... {% endfilter %}.
To define custom filters, include a module named filters in the scope of the context deriving the Template implementation. Built-in filters take precedence in case of name collisions.
// Chained filters
{{ "{:?}"|format(name|escape) }}
// Filter block
{% filter lower %}
{{ t }} / HELLO / {{ u }}
{% endfilter %}
// Chained filter block
{% filter lower|capitalize %}
{{ t }} / HELLO / {{ u }}
{% endfilter %}Use is defined or is not defined to check for the existence of a variable.
Limitation: Due to proc-macro constraints, you can only check if a variable declared in the template or a field of the current type exists. You cannot check if a nested field or a function is defined (e.g., {% if x.y is defined %} will fail to compile).
{% if x is defined %}
x exists!
{% endif %}Askama allows calling functions and methods within templates.
self.method()).self:: path (equivalent to self::function()).super::b::f()).{# Method call #}
{{ method() }}
{# Function call from current module #}
{{ self::function() }}
{# External path call #}
{{ super::b::f() }}Askama supports string and integer literals, and almost all binary operators supported by Rust (arithmetic, comparison, and logic). It follows Rust's operator precedence. You can group expressions using parentheses.
Note on Bitwise Operators: To avoid confusion with filter expressions, the binary AND, OR, and XOR operators are renamed to bitand, bitor, and xor respectively.
Note on HTML Escaping: Special characters &, <, and > are escaped by default unless you use the | safe filter or disable escaping for the template.
{{ 3 * 4 / 2 }}
{{ (4 + 5) % 3 }}
{# Bitwise operators #}
{% if my_bitset bitand 1 != 0 %}
It is set!
{% endif %}Askama supports a variety of Jinja-inspired template features, including:
if/else statements, and include support.- markers to suppress whitespace.Askama supports block comments using {# and #}. These comments support nesting, similar to Rust.
{# A Comment #}
{#
A nested comment
{# Another nested comment #}
#}Variables are provided by the template's context type. You can access fields or methods using dot notation (e.g., {{ user.name }}).
To use Rust constants in your templates, use their full path starting from crate::.
// Rust side
pub const MAX_NB_USERS: usize = 2;
// Template side
<p>The user limit is {{ crate::MAX_NB_USERS }}.</p>
{% set value = 4 %}
{% if value > crate::MAX_NB_USERS %}
<p>{{ value }} is bigger than MAX_NB_USERS.</p>
{% else %}
<p>{{ value }} is less than MAX_NB_USERS.</p>
{% endif %}