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.

Important

Expressions with operators in @let statements require parentheses. This is a common source of errors.

Correct
@let name = user.name
@let total = (a + b)
@let valid = (x > 0 && y < 10)
@let cast = (value as i32)
Wrong
@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 *@
Security Warning

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 *@
Raw Blocks

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
@image.alt

Dynamic classes example:

@fn apply(item: Item) {
    
}

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