#render #jsx #html #rsx #html-string #render-template #template

tide-jsx

一个安全、简单的模板引擎,具有JSX的易用性

8个不稳定版本 (3个重大更改)

0.4.0 2022年9月17日
0.3.3 2022年9月17日
0.2.1 2022年9月17日
0.1.0 2022年9月17日

#188 in 模板引擎

Download history 4/week @ 2024-03-11 4/week @ 2024-03-18 13/week @ 2024-04-01 188/week @ 2024-04-08 9/week @ 2024-04-15 9/week @ 2024-05-20 21/week @ 2024-06-03 91/week @ 2024-06-10 1/week @ 2024-06-17 48/week @ 2024-06-24

每月下载量161次

MIT 许可证

22KB
298

tide-jsx

为了将简单的HTML片段渲染为String,使用rsx!宏生成组件树,并对其调用render

use tide_jsx::{rsx, Render};

let tree = rsx! {
  <div>
    <h1>{"Hello!"}</h1>
    <p>{"Hello world!"}</p>
  </div>
};

assert_eq!(tree.render(), "<div><h1>Hello!</h1><p>Hello world!</p></div>");

因为这是如此常见,还有一个名为html!的宏,它调用rsx!来生成组件树,然后对其调用render。大多数时候,你会发现自己使用rsx!宏来组合任意组件,而只有当需要字符串输出时,例如发送响应或生成Markdown文件时,才调用html!

在Render中,使用render::html_escaping模块对属性和普通字符串进行转义。为了使用未转义的值,以便可以安全地插入原始HTML,请在字符串周围使用raw!

use tide_jsx::{html, raw};

let tree = html! {
  <div>
    <p>{"<Hello />"}</p>
    <p>{raw!("<Hello />")}</p>
  </div>
};

assert_eq!(tree, "<div><p>&lt;Hello /&gt;</p><p><Hello /></p></div>");

自定义组件

Render最大的能力是提供类型安全以及自定义可渲染组件。引入新组件就像定义一个返回Render值的函数一样简单。

为了从其他组件或HTML节点构建组件,可以使用rsx!宏,它生成一个Render组件树

use tide_jsx::{component, rsx, html};

#[component]
fn Heading<'title>(title: &'title str) {
  rsx! { <h1 class={"title"}>{title}</h1> }
}

let rendered_html = html! {
  <Heading title={"Hello world!"} />
};

assert_eq!(rendered_html, r#"<h1 class="title">Hello world!</h1>"#);

如果你仔细观察,你会看到函数Heading

  • 是大写的。在底层,它生成一个同名的结构体,并在其上实现Render特质。
  • 没有返回类型。这是因为为了性能原因,所有内容都写入到写入器中。

可见性与组件库

通常,你可能会想要将你的组件存储在项目树中的其他地方,而不仅仅是你在工作的模块中(如果不在完全不同的模块中)。在这些情况下,定义组件的函数上应用的可见性将流向该结构体的所有字段。

例如,如果我们在上面的Heading组件前添加"pub":

#[component]
pub fn Heading<'title>(title: &'title str) {
  rsx! { <h1 class={"title"}>{title}</h1> }
}

生成的结构体可能看起来像...

pub struct Heading {
  pub title: &'title str
}

从安全角度考虑,这很重要,当你在结构库时需要理解。

完整示例

use render::html::HTML5Doctype;
use render::{component, rsx, html, Render};

#[component]
fn Page<'a, Children: Render>(title: &'a str, children: Children) {
   rsx! {

   }
}

pub fn some_page(user_name: &str) -> String {
    html! {
      <Page title={"Home"}>
        {format!("Welcome, {}", user_name)}
      </Page>
    }
}

依赖项

~9-20MB
~303K SLoC