Luigit
repositories / dotfiles

dotfiles

bugabingas dorkfiles

owned by admin

pi/agent/skills/optional/rust-maud/SKILL.md

Raw
Rendered preview

name: rust-maud description: Write HTML in Rust using Maud — compile-time verified html! macro, component patterns, PreEscaped, Render trait, integration with Axum/Actix. license: MIT

rust-maud skill

What I do

Guide Maud template engine usage in Rust. Maud compiles templates to Rust code at compile time.

Quick Start

use maud::html;

let name = "World";
let markup = html! {
    h1 { "Hello, " (name) "!" }
};
[dependencies]
maud = "*"

Syntax

Text and Escaping

html! { "Oatmeal, are you crazy?" }  // Literal text
html! { pre { r#"Rocks, these are my rocks."# } }  // Raw strings
html! { (PreEscaped("<script>")) }  // Disable escaping
html! { (DOCTYPE) }  // DOCTYPE

Elements

html! {
    h1 { "Title" }
    p { strong { "Bold" } " and normal" }
    br;              // Void elements end with ;
    img src="img.png";
    input type="text" name="user";
    input type="checkbox" checked;  // Boolean attribute
}

Classes and IDs

html! {
    div#container.main-class {
        "Content"
    }
    #main { "Main" }     // Implicit div
    .tip { "Tip" }
}

Splices (Values)

html! {
    p { "Hi, " (name) "!" }
    a href=(href) { "Link" }
    a href={ (base) "/users" } { "API" }  // Concatenate
    div.#(theme)-theme { "Content" }  // Splice in class
}

Toggles

html! {
    div contenteditable[editable] { "Edit" }
    li.active[is_active] { "Active" }
    p title=[title] { "Optional attr" }  // Option<T>
}

Control Flow

// @if / @else
@if user_logged_in {
    a href="/logout" { "Logout" }
} @else {
    a href="/login" { "Login" }
}

// @if let
@if let Some(name) = username {
    p { "Welcome, " (name) }
}

// @for loop
@for item in &items {
    li { (item) }
}

// @let
@let first = user.name.chars().next();
li { (first) ". " (user.name) }

// @match
@match status {
    Status::Active => { span.active { "Active" } },
    _ => { span { "Unknown" } }
}

Partials (Composition)

fn header(title: &str) -> Markup {
    html! { head { title { (title) } } }
}

fn page(title: &str, content: Markup) -> Markup {
    html! {
        (header(title))
        main { (content) }
    }
}

Render Trait

use maud::{html, Render};

struct Button { label: &'static str, href: &'static str }

impl Render for Button {
    fn render(&self) -> Markup {
        html! { a href=(self.href) class="button" { (self.label) } }
    }
}

html! { (Button { label: "Click", href: "/click" }) }

Framework Integration

// Actix-web
#[get("/")]
async fn index() -> Markup { html! { h1 { "Hello!" } } }

// Rocket
#[get("/<name>")]
fn hello(name: &str) -> Markup { html! { h1 { "Hello, " (name) "!" } } }

// Axum
async fn hello() -> Markup { html! { h1 { "Hello!" } } }
let app = Router::new().route("/", get(hello));

Best Practices

  1. Prefer functions for partials
  2. Implement Render for domain types
  3. Use toggles [is_active] over @if
  4. Push logic to Rust, not templates
  5. Use PreEscaped sparingly

Use this skill when building Rust web apps with Maud templates.

---
name: rust-maud
description: Write HTML in Rust using Maud — compile-time verified html! macro, component patterns, PreEscaped, Render trait, integration with Axum/Actix.
license: MIT
---

# rust-maud skill

## What I do

Guide Maud template engine usage in Rust.
Maud compiles templates to Rust code at compile time.

## Quick Start

```rust
use maud::html;

let name = "World";
let markup = html! {
    h1 { "Hello, " (name) "!" }
};
```

```toml
[dependencies]
maud = "*"
```

## Syntax

### Text and Escaping

```rust
html! { "Oatmeal, are you crazy?" }  // Literal text
html! { pre { r#"Rocks, these are my rocks."# } }  // Raw strings
html! { (PreEscaped("<script>")) }  // Disable escaping
html! { (DOCTYPE) }  // DOCTYPE
```

### Elements

```rust
html! {
    h1 { "Title" }
    p { strong { "Bold" } " and normal" }
    br;              // Void elements end with ;
    img src="img.png";
    input type="text" name="user";
    input type="checkbox" checked;  // Boolean attribute
}
```

### Classes and IDs

```rust
html! {
    div#container.main-class {
        "Content"
    }
    #main { "Main" }     // Implicit div
    .tip { "Tip" }
}
```

### Splices (Values)

```rust
html! {
    p { "Hi, " (name) "!" }
    a href=(href) { "Link" }
    a href={ (base) "/users" } { "API" }  // Concatenate
    div.#(theme)-theme { "Content" }  // Splice in class
}
```

### Toggles

```rust
html! {
    div contenteditable[editable] { "Edit" }
    li.active[is_active] { "Active" }
    p title=[title] { "Optional attr" }  // Option<T>
}
```

### Control Flow

```rust
// @if / @else
@if user_logged_in {
    a href="/logout" { "Logout" }
} @else {
    a href="/login" { "Login" }
}

// @if let
@if let Some(name) = username {
    p { "Welcome, " (name) }
}

// @for loop
@for item in &items {
    li { (item) }
}

// @let
@let first = user.name.chars().next();
li { (first) ". " (user.name) }

// @match
@match status {
    Status::Active => { span.active { "Active" } },
    _ => { span { "Unknown" } }
}
```

### Partials (Composition)

```rust
fn header(title: &str) -> Markup {
    html! { head { title { (title) } } }
}

fn page(title: &str, content: Markup) -> Markup {
    html! {
        (header(title))
        main { (content) }
    }
}
```

### Render Trait

```rust
use maud::{html, Render};

struct Button { label: &'static str, href: &'static str }

impl Render for Button {
    fn render(&self) -> Markup {
        html! { a href=(self.href) class="button" { (self.label) } }
    }
}

html! { (Button { label: "Click", href: "/click" }) }
```

## Framework Integration

```rust
// Actix-web
#[get("/")]
async fn index() -> Markup { html! { h1 { "Hello!" } } }

// Rocket
#[get("/<name>")]
fn hello(name: &str) -> Markup { html! { h1 { "Hello, " (name) "!" } } }

// Axum
async fn hello() -> Markup { html! { h1 { "Hello!" } } }
let app = Router::new().route("/", get(hello));
```

## Best Practices

1. Prefer functions for partials
2. Implement `Render` for domain types
3. Use toggles `[is_active]` over `@if`
4. Push logic to Rust, not templates
5. Use `PreEscaped` sparingly

---

Use this skill when building Rust web apps with Maud templates.