Expressions
Output data from your Rust code into templates with type-safe expressions.
Simple Expressions
Use @ followed by an identifier to output a variable. Values are automatically HTML-escaped for security.
@user.name @* Field access *@
@items.len() @* Method call *@
@items[0] @* Indexing *@
@user.profile.avatar_url @* Nested access *@
Example:
@fn apply(user: User) {
Welcome, @user.name!
Email: @user.email
Member since: @user.created_at.format("%Y")
}
Complex Expressions
Expressions with operators must be wrapped in parentheses:
@(a + b) @* Arithmetic *@
@(count * 2 + 1) @* Multi-operator *@
@(value as f64) @* Type cast *@
@(if cond { a } else { b }) @* Inline if *@
Example:
@fn apply(items: Vec- , tax_rate: f64) {
Total items: @items.len()
Page @(current_page + 1) of @total_pages
Tax: $@(subtotal * tax_rate)
}
Variable Bindings
Use @let to create local variables within templates.
Expressions with operators in @let statements require parentheses. This is a common source of errors.
@let name = user.name
@let total = (a + b)
@let valid = (x > 0 && y < 10)
@let cast = (value as i32)@let total = a + b @* Error! *@
@let valid = x > 0 @* Error! *@
@let cast = value as i32 @* Error! *@Practical example:
@fn apply(items: Vec- , discount: f64) {
@let subtotal = items.iter().map(|i| i.price).sum::
()
@let discount_amount = (subtotal * discount)
@let total = (subtotal - discount_amount)
Subtotal: $@subtotal
Discount: -$@discount_amount
Total: $@total
}
Safe (Unescaped) Output
By default, all output is HTML-escaped. Use @safe() for trusted HTML content:
@safe(html_content) @* Output without escaping *@
@safe(markdown_html, "fallback
") @* With fallback value *@
Only use @safe() with content you trust. Never use it with user input.
Example:
@fn apply(article: Article) {
@article.title
@* Title is escaped - safe from XSS *@
@safe(article.rendered_html)
@* rendered_html is trusted, pre-sanitized content *@
}
Escaping the @ Symbol
Use @@ to output a literal @ symbol:
@@ @* Outputs: @ *@
email@@example.com @* Outputs: email@example.com *@
Inside @#...#@ raw blocks (any matching number of #), content is output verbatim - no escaping needed. The @@ escape is only needed outside raw blocks to output a literal @.
Expressions in Attributes
Expressions work seamlessly in HTML attributes:
@label
Dynamic classes example:
@fn apply(item: Item) {
@item.title
}
Expression Summary
| Syntax | Description | Example |
|---|---|---|
@var |
Simple variable (escaped) | @user.name |
@obj.field |
Field access | @user.profile.bio |
@obj.method() |
Method call | @items.len() |
@(expr) |
Complex expression | @(a + b) |
@safe(html) |
Unescaped output | @safe(rendered_md) |
@let x = val |
Variable binding | @let total = (a + b) |
@@ |
Literal @ symbol | email@@example.com |