maud

Splices and toggles

Splices: (foo)

Use (foo) syntax to insert the value of foo at runtime. Any HTML special characters are escaped by default.

let best_pony = "Pinkie Pie";
let numbers = [1, 2, 3, 4];
html! {
    p { "Hi, " (best_pony) "!" }
    p {
        "I have " (numbers.len()) " numbers, "
        "and the first one is " (numbers[0])
    }
}

Arbitrary Rust code can be included in a splice by using a block. This can be helpful for complex expressions that would be difficult to read otherwise.

html! {
    p {
        ({
            let f: Foo = something_convertible_to_foo()?;
            f.time().format("%H%Mh")
        })
    }
}

Splices in attributes

Splices work in attributes as well.

let secret_message = "Surprise!";
html! {
    p title=(secret_message) {
        "Nothing to see here, move along."
    }
}

To concatenate multiple values within an attribute, wrap the whole thing in braces. This syntax is useful for building URLs.

const GITHUB: &'static str = "https://github.com";
html! {
    a href={ (GITHUB) "/lambda-fairy/maud" } {
        "Fork me on GitHub"
    }
}

Splices in classes and IDs

Splices can also be used in classes and IDs.

let name = "rarity";
let severity = "critical";
html! {
    aside#(name) {
        p.{ "color-" (severity) } { "This is the worst! Possible! Thing!" }
    }
}

What can be spliced?

You can splice any value that implements std::fmt::Display. Most primitive types (such as str and i32) implement this trait, so they should work out of the box.

To change this behavior for some type, you can implement the Render trait by hand. The PreEscaped wrapper type, which outputs its argument without escaping, works this way. See the traits section for details.

use maud::PreEscaped;
let post = "<p>Pre-escaped</p>";
html! {
    h1 { "My super duper blog post" }
    (PreEscaped(post))
}

Toggles: [foo]

Use [foo] syntax to show or hide something based on a boolean expression foo.

This works on empty attributes:

let allow_editing = true;
html! {
    p contenteditable?[allow_editing] {
        "Edit me, I "
        em { "dare" }
        " you."
    }
}

And classes:

let cuteness = 95;
html! {
    p.cute[cuteness > 50] { "Squee!" }
}