Usage Guide
This comprehensive guide covers all aspects of using the Waltzing template language for building type-safe, compile-time HTML templates in Rust.
- File Extension:
.wtz(e.g.,template.html.wtz,component.wtz) - Purpose: Compile-time HTML template engine for Rust
- Output: Type-safe Rust functions that generate HTML
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 @.
Expression Syntax
| Pattern | Usage | Example |
|---|---|---|
@variable |
Simple interpolation | @user.name |
@(expression) |
Complex expressions | @(a + b * c), @(users.len() + 1) |
@{ ... } |
Template expressions | @{ <p>Hello</p> } |
<@ component::func > |
Function Tag | <@layout::main title="Home"> |
@safe(expr) |
Unescaped output | @safe(html_content) |
@@ |
Literal @ symbol | user@@domain.com |
When to Use Parentheses
Need parentheses:
- Arithmetic operations:
@(a + b * c) - Complex chained expressions:
@(items.iter().filter().count()) - Control flow expressions:
@(if condition { value } else { other }) - Logical operations:
@(!user.can_edit)
No parentheses needed:
- Simple function calls:
@format("text", arg) - Member access:
@user.name,@item.field - Method calls:
@users.len(),@string.trim() - Array indexing:
@items[0]
Imports and Uses
@use crate::models::* // Import Rust types
@use chrono::DateTime
@use std::collections::HashMap
@import "layouts/main.wtz" as layout // Import other templates
@import "components/header.wtz" as header
Function Definitions
Basic Syntax
@fn apply(
title: String,
posts: Vec,
user: Option,
current_time: DateTime
) {
}
Default Parameters
Functions can have default parameter values:
// Function with default parameters
@fn card(title: String, content: Content, class: String = "card") {
@title
@content
}
// Usage with defaults
<@card title="Welcome">
Hello world!
@card>
// Override the default
<@card title="Welcome" class="special-card">
Hello world!
@card>
When calling functions with default parameters via function tags, you can omit any parameters that have defaults. The function will use the default value automatically.
Control Flow
If/Else Statements
@if user.is_admin {
Admin Panel
} else if user.is_moderator {
Moderator Tools
} else {
User Content
}
// If-let pattern matching
@if let Some(profile) = user.profile {
Profile: @profile.bio
} else {
No profile available
}
For Loops
@for item in items {
- @item.name: $@item.price
}
// With enumeration
@for (index, item) in items.iter().enumerate() {
@item.name
}
// Labeled loops with break/continue
@for outer_label: group in groups {
@for item in group.items {
@if item.should_break {
@break :outer_label;
}
@item.name
}
}
Pattern Matching
@match user.status {
UserStatus::Active => {
Active
}
UserStatus::Pending => {
Pending
}
UserStatus::Banned(reason) => {
Banned: @reason
}
_ => {
Unknown Status
}
}
Function Tags
Function tags provide HTML-like syntax for calling template functions, making component composition intuitive and readable.
Basic Syntax
// Self-closing function tag
<@header::apply title="Page Title" />
<@button::render text="Click me" disabled />
// Function tag with content
<@layout::apply title="My App">
Page content goes here
@layout::apply>
// Shorthand closing (closes nearest open tag)
<@layout::apply title="Dashboard">
Content here
@@>
Attribute Types
<@component::apply
name="string literal" // String literal (quoted)
count=@@(items.len()) // Expression
active=@user.is_active // Simple expression
title=@title // Variable value
@variable // Shorthand for variable=@variable
@@&reference // Shorthand for reference=@@&reference
enabled // Boolean flag (true)
class='single-quotes' // Single-quoted string
/>
DO NOT mix quotes with @:
<@component name="@user.name" />
<@component name=@user.name />
<@component name="John Doe" />Content Parameter
If a function's last parameter is of type waltzing::Content, it receives the tag body:
// Function definition
@fn layout(title: String, content: Content) {
@title
@content
}
// Function tag - body becomes content parameter
<@layout title="My Page">
This becomes the content parameter
@layout>
Default Parameter Values in Function Tags
Function tags work seamlessly with default parameters, allowing you to omit attributes that have defaults:
// Function with multiple defaults
@fn button(
text: String,
variant: String = "primary",
size: String = "medium",
disabled: bool = false
) {
}
// All of these work:
<@button text="Click me" /> // Uses all defaults
<@button text="Submit" variant="success" /> // Override one default
<@button text="Cancel" variant="secondary" size="small" /> // Override multiple
<@button text="Save" disabled /> // Boolean flag syntax
Underscore Parameter Convention
Function tag parameters can omit leading underscores from function parameter names:
// Function definition with underscore parameter
@fn card(_title: String, _content: Content, _class: String = "card") {
@_title
@_content
}
// Function tag usage (omits underscores)
<@card title="Welcome" class="special-card">
Hello world!
@card>
Special apply Shorthand
If the function name is apply, it can be omitted:
// These are equivalent:
<@template::apply title="Page">Content@template::apply>
<@template title="Page">Content@template>
HTML Attributes
Conditional Attributes
Dynamic Attribute Names
// @attributeName - literal @@ prefix (for Alpine.js, Vue, etc.)