utkarshkukreti / markup.rs

A blazing fast, type-safe template engine for Rust.
Apache License 2.0
350 stars 14 forks source link

Any ideas how to do nested components? #17

Closed 9876691 closed 2 years ago

9876691 commented 2 years ago

I'd like to build a nested tabs component. Something like

Tabs {
  tabs: vec!(Tab {
    title: "Tab 1",
    body: markup::new! {
            div {
              ... more content
            }
        }
  })
}

So a component, with a list of nested sub components.

I tried a few different things, something like

markup::define! {
    Tab<'a>(
        title: &'a str,
        body: Box<dyn markup::Render>
    ) {
        input[type="radio", id="tab2", name="css-tabs"] {}
        div {
            {title}
        }
        div {
            @body
        }
    }
    Tabs<'a>(tabs: &'a [Tab]) {
       ...list all the tabs
    }
}

But that doesn't compile. I guess I could pass around the Tab elements as a string, but ideally I"d like the type safety.

Any ideas?

ZaneHannanAU commented 2 years ago

Could use Box::new or the https://doc.rust-lang.org/nightly/unstable-book/language-features/box-syntax.html keyword; potentially even use a tab(markup::new! {}) function to return a wrapped Raw type.

utkarshkukreti commented 2 years ago

Hey @ianpurton, did you manage to figure out a solution? Box<dyn Render> will not work as the trait is not object-safe because its render function takes a generic argument (for performance reasons).

I pushed some changes in https://github.com/utkarshkukreti/markup.rs/commit/694f02141feea67b415cc44b91f27c102037ba8f to address this.

You can try it out by adding a dependency on the latest git commit.

I'm still thinking of a better name than DynRender for the struct before making a release.