yew icon indicating copy to clipboard operation
yew copied to clipboard

Support setting inner html from string with the `html` macro

Open ghost opened this issue 6 years ago • 6 comments

Problem

Devs would like to reuse existing templates/snippets for a lot of parts of an application.

They may try using pub const INDEX_HTML: &'static str = include_str!("../assets/templates/index.html"); and then inside html! { <div id="wrapper>{ INDEX_HTML } </div> } but all they will get is the html rendered as plain text inside the wrapper div :(

Proposed Solution

Add a special property like React's dangerouslySetInnerHTML (https://reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml) to VTag

ghost avatar Apr 03 '18 20:04 ghost

I think it would be great to take this idea a bit further: It would be great if it's possible to use only parts of existing html files. See kioo from the clojurescript land for an example of such an library. Don't get confused by the lisp code style. What this library does is basically the following:

  • Load a existing html file
  • Extract a bit of this html file based on a css selector (in the snippet case, for templates the whole html file is used)
  • modify parts of the extracted html file based on further css selectors.

The main benefit of such an strategy is the split between design work (could be done purely based on the html files) and implementing the actual webapp.

Without any further investigation I think is should be possible to implement such an feature as proc-macro based library using the html/css stack from the servo project and then inlining the prebuild template.

weiznich avatar Apr 04 '18 21:04 weiznich

Came here to ask exactly this, inspired by https://anderspitman.net/2018/04/04/static-react-rust-webapp/. Would be nice to render a Vue app into a single .html file, then include it into the wasm binary directly. Not immediately sure how this would interop with Rust code, though.

I'd rather see integration with something like wasm-bindgen, and support of native HTML/JS/CSS loaded as strings, than of an html! macro with a bunch of edge cases. Suggestion made entirely respectfully--this is a personal project, but it does seem to be biting off quite a bit.

ndarilek avatar Apr 05 '18 16:04 ndarilek

Missing label:

  • question

samuelvanderwaal avatar Jan 31 '20 04:01 samuelvanderwaal

This is very much desired, especially when a webpage contains many static contents. Translating them to JSX manually is a lot of work.

awaited-hare avatar Jun 08 '20 02:06 awaited-hare

@L1AN0 there is a workaround here: https://github.com/yewstack/yew/issues/1281

We could also add a special property like React's dangerouslySetInnerHTML (https://reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml)

jstarry avatar Jun 08 '20 16:06 jstarry

Revisiting this from #2841, I think the cleanest approach, without touching other parts of yew would be a single fn Html::from_html_unchecked(inner: &str) -> Self. Internally we can already differentiate the rendering modes and decide whether to emit the correct SSR content or to create new nodes.

A detail that most users are probably not aware of, is that setting .innerHtml does not execute <script> tags, but this would be mismatching with SSR - not that's it's such a good idea, but maybe there is some value in executing highlight.js or similar libs. There is an alternative API: Range.createContextualFragment that's quite well supported and does execute scripts when inserted.

In this case, the API could look like:

let inner = Html::from_html_unchecked(INDEX_HTML);
html! { <div id="wrapper>{ inner } </div> }

WorldSEnder avatar Aug 23 '22 13:08 WorldSEnder