Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

alternative to typed-html, considering that this seems to be unofficially unmaintained. #130

Open
vidhanio opened this issue Jul 28, 2023 · 0 comments

Comments

@vidhanio
Copy link

vidhanio commented Jul 28, 2023

hi!

i was looking for a crate to do in-rust html templating, found this crate, and unfortunately it looked unmaintained.

i've been working on my own crate for this for a while, and i thought it would be useful to some people here.

docs.rs

it has type checking (although just checks the validity of the attribute name, not the validity of their content, as it is all string-based) and allows even defining your own typed elements, with custom data types for the attributes! here is an example of the syntax:

Minimal Example

use html_node::{typed::self, elements::div};
                          // ^^^^^^^^^^^^^ bring the `div` element definition into scope
                          // `typed::elements` contains every default html elements'
                          // type defintions.

assert_eq!(
    typed::html!(<div id="test">hi</div>).to_string(),
    r#"<div id="test">hi</div>"#
);

// fails to compile, saying `DivAttributes` does not have field `cool_attr`
// typed::html!(<div cool-attr="hi" id="test>hi</div>)

// compiles!
typed::html!(<div data-cool-attr="hi" id="test">hi</div>)

Maximal Example

use std::fmt::Display;

use html_node::{typed::self, elements::div};

#[derive(Debug, Clone)]
struct Location {
    x: i32,
    y: i32,
}

impl Display for Location {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "{},{}", self.x, self.y)
    }
}

// generates all global attributes as well as those defined in the macro!
typed::element! {
    CustomElement("custom-element") {
        location: Location,
    }
}

let html = typed::html!(
    <div class="example">
	    <CustomElement id="lol" location=Location { x: 1, y: 2 } />
    </div>
);

assert_eq!(
    html.to_string(),
    r#"<div class="example"><custom-element id="lol" location="1,2"></custom-element></div>"#
);

the cool thing is that the typing is only at compile-time, and it all turns into the same Node type, so you can put typed elements inside untyped elements if needed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant