Using 'raw' html/css from designer

Hello!,

I work on the back end and front end support. I work with ‘raw’ html and css provided by a UI designer.

I’m wondering if there is a way to use this html mostly as is, something like JSX or Handle Bars as a template language.

  1. I hope to eliminate work involved in ‘converting’ the html to Seed macros.
  2. I would like the designer to be able to make updates to the html without my involvement.

Is this something Seed can do?

Hi!

If I understand correctly, you can use macro raw:

fn view(&model) -> Vec<Node<Msg>> {
    raw!(&model.my_html_as_a_string)
}

I would need at least a short example of your “raw” HTML and more details about your business logic to help more.

Cheers, M.

@MartinKavik raw! looks promising. I’ll give it a try and let you know how it goes.

Thanks for the fast reply! :slight_smile:

Been busy, but I finally got to playing with this. raw!() worked very well for static html.

Here’s a relevant snippet based on seed-quickstart

struct Model {
pub val: i32,
pub html: &'static str,
}

impl Default for Model {
    fn default() -> Self {
        Self {
            val: 0,
            html: include_str!("./components/counter.html"),
        }
    }
}
...
fn view(model: &Model) -> impl View<Msg> {
    raw!(&model.html)
}

Now that I have the raw html working as desired, the remaining issue is how to automate the conversion and addition of seed code to active elements.

For example, I need to convert html buttons to seed buttons:

html:

<button
  class="ml-4 mt-4 bg-green-500 text-white p-2 rounded text-2xl font-bold"
>
  +
</button>

seed:

button![
    class!("ml-4 mt-4 bg-green-500 text-white p-2 rounded text-2xl font-bold"),
    simple_ev(Ev::Click, Msg::Increment),
    format!("+")
],

In a preliminary search I came across html-to-seed which promises to make the work trivial, but I would like to automate that work if practical.

I’m thinking along the lines of a search, process and replace operation with the action code contained in a data- attribute something like:

data-seed="simple_ev(Ev::Click, Msg::Increment),"

Another idea to be explored is just creating a library of TEA components for elements needing seed actions. That would make the search and replace easier, but would require a separate maintenance step if the element style was to change.

I’m interested in any thoughts, comments or suggestions you might have on this.
Thanks in advance! :slight_smile:

I don’t recommend to use automatic HTML -> Seed template converter, because Seed API is still changing (and I assume we don’t want to freeze it because we want to improve it as much as possible).
An example of converter problem:

Your Seed example:

button![
    class!("ml-4 mt-4 bg-green-500 text-white p-2 rounded text-2xl font-bold"),
    simple_ev(Ev::Click, Msg::Increment),
    format!("+")
],

Current recommended way on the master branch:

button![
    C!["ml-4 mt-4 bg-green-500 text-white p-2 rounded text-2xl font-bold"],
    ev(Ev::Click, |_| Msg::Increment),   // new draft API: `E.click(|_| Msg::Increment)`
    "+"
],

So I would suggest to add “active” / dynamic parts once your elements are loaded through raw macro. Example for counter:

fn view(model: &Model) -> Vec<Node<Msg>> {
    let mut nodes: Vec<Node<Msg>> = raw!(
        r#"<button>-</button><span></span><button>+</button>"#
    );
    if let [decrement, counter, increment] = nodes.as_mut_slice() {
        decrement.add_event_handler(ev(Ev::Click, |_| Msg::Decrement));
        counter.replace_text(model.to_string());
        increment.add_event_handler(ev(Ev::Click, |_| Msg::Increment));
    }
    log!(nodes);
    nodes
}

I don’t know how much flexible / custom your handlers and values should be so I can’t suggest a better alternative to data-handler="..". However I would rather choose non-HTML invasive ways - e.g. return from your designer a tree of objects, where the object contains HTML and meta-data like handlers, values, etc. which help you to build Seed elements later.

I was not able to get your example working. A few questions:

I expected log!(nodes); would dump the nodes to the browser console, but I get

[<unknown> of type &alloc::vec::Vec<seed::virtual_dom::node::Node<appname::Msg>> is !Debug]

I think this means that Debug trait needs to be applied somewhere?, but I’m too new to rust to understand where or how.

I’m assuming that nodes does contain the correct data as the resulting web page is correctly displayed and so the problem here is simply not being able to display that data with log!.

My second question:

Assuming increment, decrement and counter are nodes, how do those names get associated with the html elements?

I tried adding id’s:

r#"<button id="decrement">-</button><span id="counter"></span><button id="increment">+</button>"#

But that didn’t make a difference.

My current state of code is available in the research branch of my fork in case you want to see the whole project.

Sorry to be so ignorant, I’m still very new to rust and seed.

Any suggestions you can offer are truly appreciated.

I hope you’ll find the most answers in this PR: https://github.com/gihrig/seed-quickstart/pull/1.
Let me know if I’ve written something too simple, too complex or you want to know more details.


Assuming increment , decrement and counter are nodes, how do those names get associated with the html elements?

It’s just by order - it’s basically destructured vector of nodes.


Sorry to be so ignorant, I’m still very new to rust and seed.

I tried to write some Rust/Seed notes into the code in that PR ^, hope it helps somehow.
Rust is hard to learn, Seed is a new framework - you are not ignorant - and I’m glad that I know how beginners use it so we can improve it.

That PR is perfect! The comments are extremely helpful - Thank you so much! :grinning:

I’ll study the extensive comments and work on applying this to a more complex web page.

I’ll post my success or any other questions.

Thanks again, the working example made my whole week! :grinning: