rdml_leptos 0.1.1

An alternative templating macro for leptos
Documentation

An alternative templating macro for leptos with more consise syntax based on rdml

Examples

Elements

Elements are made up of the tag or component name, followed by attributes and children surrounded by braces.

Attributes are optional, must be surrounded by parenthesis, and are separated by commas.

use rdml_leptos::rdml;
use leptos::prelude::*;

#[component]
fn ButtonComponent() -> impl IntoView { rdml! {} }

rdml! {
    div(id="root", class="container") {
        span { "Hello, world!" }
        ButtonComponent(on:click=move |_| println!("Clicked!")) {}
    }
}
# ;

Text node

Quoted text will be interpreted as a text node

# use rdml_leptos::rdml;
# use leptos::prelude::*;
rdml! {
    div { "Text here" }
}
# ;

Expressions

Expressions can be any rust expression surrounded by parenthesis.

# use rdml_leptos::rdml;
# use leptos::prelude::*;
let i = 5;

rdml! {
    div { (if i > 1 { "Greater" } else { "Less" }) }
}
# ;

If blocks

If blocks can conditionally render certain nodes.

# use rdml_leptos::rdml;
# use leptos::prelude::*;
let i = 5;

rdml! {
    if i > 1 {
        span { "This is a span" }
    } else {
        div { "This is a div" }
    }
}
# ;

By default, the if generates creates a normal rust if expression in a closure (i.e. {move || if condition {} [...]}), however the #[show] attribute can be applied to use the Show component instead. (See control flow in the leptos book for more deatails).

# use rdml_leptos::rdml;
# use leptos::prelude::*;
let i = 5;

rdml! {
    #[show]
    if i > 1 {
        span { "This is a span" }
    } else {
        div { "This is a div" }
    }
}
# ;

For blocks

For blocks can render a list of nodes

# use rdml_leptos::rdml;
# use leptos::prelude::*;
rdml! {
    for i in 0..50 {
        div { (i) }
    }
}
# ;

By default, the for node collects the given iterable into a Vec<_>, however the For component can be used instead by adding the #[key([expr])] attribute. (See iteration in the leptos book).

# use rdml_leptos::rdml;
# use leptos::prelude::*;
# leptos::reactive::owner::Owner::new().with(|| {
let items = RwSignal::new(vec![1, 2, 3]);

rdml! {
    #[key(item.clone())]
    for item in items.get() {
        div { (item) }
    }
}
# ;
# });

Match blocks

You can also use match statements for control flow (this always generates a move closure with a rust match block)

# use rdml_leptos::rdml;
# use leptos::prelude::*;
let name = Some("a");
let other_name = "Other name";

rdml! {
    match name {
        Some("a") => div { "a" }
        Some("b") => "b",
        Some("c") => {
            span { "c" }
            button {}
        }
        _ => (other_name.to_string()),
    }
}
# ;

With attributes

Most nodes and blocks can have the #[with([stmt])] attribute applied to enter a new scope with the given statment. This attribute can be applied multiple times.

# use rdml_leptos::rdml;
# use leptos::prelude::*;
let x = 5;
let string = "hello".to_string();

rdml! {
    #[with(let value = x + 1;)]
    {
        div {}
        (value)
    }
    #[with(let string = string.clone();)]
    #[with(let string1 = string.clone();)]
    if x > 2 {
        div { (string.clone()) (string1.clone()) }
    }
}
# ;