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 Render. Most primitive types (such as str and i32) implement this trait, so they should work out of the box.

To get this behavior for a custom 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 classes and boolean attributes on a HTML element based on a boolean expression foo.

Toggle boolean 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!" }
}

Optional attributes with values: title=[Some("value")]

Add optional attributes to an element using attr=[value] syntax, with square brackets. These are only rendered if the value is Some<T>, and entirely omitted if the value is None.

html! {
    p title=[Some("Good password")] { "Correct horse" }

    @let value = Some(42);
    input value=[value];

    @let title: Option<&str> = None;
    p title=[title] { "Battery staple" }
}