I would like to render Markdown in an app that I'm working on, so I wrote this (using the comrak crate for Markdown rendering):
html! {
<div>
{ markdown_to_html("Hello, **涓栫晫**!", &ComrakOptions::default()) }
</div>
}
Of course this just results in the HTML being escaped and output directly on the page.
I googled around to try to find how to output a raw string with Yew, but I didn't find anything.
PS. The Discord link seems to have expired :)
Yew currently doesn't support this - at least not directly.
However, thanks to the flexibility of references there's almost nothing you can't do.
Here's the code for a component that can be used to render raw html:
#[derive(Debug, Clone, Eq, PartialEq, Properties)]
struct RawHTMLProps {
pub inner_html: String,
}
struct RawHTML {
props: RawHTMLProps,
node_ref: NodeRef,
}
impl Component for RawHTML {
type Message = ();
type Properties = RawHTMLProps;
fn create(props: Self::Properties, _: ComponentLink<Self>) -> Self {
Self { props, node_ref: NodeRef::default() }
}
fn update(&mut self, _: Self::Message) -> ShouldRender {
true
}
fn change(&mut self, props: Self::Properties) -> ShouldRender {
if self.props != props {
self.props = props;
true
} else {
false
}
}
fn view(&self) -> Html {
// create the parent element and store a reference to it
html! {
<div ref=self.node_ref.clone()/>
}
}
fn rendered(&mut self, _first_render: bool) {
let el = self.node_ref.cast::<Element>().unwrap();
el.set_inner_html(&self.props.inner_html);
}
}
The relevant code is in the rendered method which manually sets the innerHTML of the element.
You can use this component like this:
html! {
<RawHTML inner_html="<span>Hello World</span>"/>
}
There's also a lower level approach to this which can be seen in the inner_html example but it's not quite as easy to understand what's going on there.
I think a component like this would make a great addition to the yewtil crate.
Thanks for your help! I couldn't get the code you posted to work (dyn_cast doesn't seem to exist?), but I adapted the code you linked to into this, which works great:
#[derive(Debug, Clone, Eq, PartialEq, Properties)]
struct RawHTMLProps {
pub inner_html: String,
}
struct RawHTML {
props: RawHTMLProps,
}
impl Component for RawHTML {
type Message = Msg;
type Properties = RawHTMLProps;
fn create(props: Self::Properties, _: ComponentLink<Self>) -> Self {
Self { props }
}
fn update(&mut self, _: Self::Message) -> ShouldRender {
true
}
fn change(&mut self, props: Self::Properties) -> ShouldRender {
if self.props != props {
self.props = props;
true
} else {
false
}
}
fn view(&self) -> Html {
let div = web_sys::window()
.unwrap()
.document()
.unwrap()
.create_element("div")
.unwrap();
div.set_inner_html(&self.props.inner_html[..]);
let node = Node::from(div);
let vnode = VNode::VRef(node);
vnode
}
}
Right, sorry about that, it should've been dyn_into. You need to have JsCast in scope in order to use it ( use wasm_bindgen::JsCast).
Please refer to this comment that doesn't make me look quite as stupid.
That doesn't seem to work either:
no method named `dyn_into` found for struct `yew::html::NodeRef` in the current scope
Well this got very embarrassing for me, didn't it :sweat_smile:.
The method I was looking for is just cast. It's implemented on NodeRef itself.
The docs still use try_into but the function got renamed over a month ago.
I updated the code again and this time it should definitely work.
I was hastily trying to correct myself before so I didn't properly think about it. Sorry for wasting your time like that.
The docs still use try_into but the function got renamed over a month ago.
I updated the code again and this time it should definitely work.
I think the docs might still need to be updated for this
@kellpossible, totally forgot about that.
Fix: #1469
Thanks for bringing it up
Most helpful comment
Yew currently doesn't support this - at least not directly.
However, thanks to the flexibility of references there's almost nothing you can't do.
Here's the code for a component that can be used to render raw html:
The relevant code is in the
renderedmethod which manually sets theinnerHTMLof the element.You can use this component like this:
There's also a lower level approach to this which can be seen in the
inner_htmlexample but it's not quite as easy to understand what's going on there.I think a component like this would make a great addition to the
yewtilcrate.