2个不稳定版本
0.2.0 | 2024年3月22日 |
---|---|
0.1.1 | 2024年3月7日 |
0.1.0 |
|
#85 in 模板引擎
每月136次下载
23KB
215 行
HTML Compile
用于在Rust中生成HTML字符串的模板引擎,适用于静态网站。
可以通过输入简明语法到提供的宏中或从Rust结构体中生成HTML字符串。
该引擎优先考虑速度,应仅用于信任的HTML数据。
使用宏生成HTML
GitHub上的目录 example 提供了一个完整的示例。以下是对语法不同方面的解释。
使用的语法受到 pug.js 的启发,但已根据Rust环境进行了调整。
创建文本元素
使用字符串字面量
html!(div (style = "border: 1px solid black;" class = "Hello") "Hello World");
将创建以下HTML字符串,该字符串包含一个具有 div
的 style
属性,创建黑色边框,一个设置为 class
的 Hello
属性,文本设置为 "Hello World"
"<div style=\"border: 1px solid black;\" class=\"Hello\">Hello World</div>"
第一个标记(此处为 div
)指定了元素的名称。
一组括号 ()
包含元素的属性。属性名在 =
之前,属性值之后,并用双引号括起来。不同的属性用空格分隔。
内容末尾的双引号中的文本指定了文本内容 "Hello World"
使用变量
文本也可以从变量中派生。在这种情况下,用花括号 {}
包围变量
let example_text = "Hello World";
html!(div (style = "border: 1px solid black;" class = "Hello") {example_text});
给出与之前相同的结果
"div style=\"border: 1px solid black;\" class=\"Hello\">Hello World</div>"
创建没有属性或内容的元素
两种形式 html!(div)
和 html!(div ())
都会创建一个包含没有样式的空 div 的 HTML 字符串。
"<div></div>"
空元素不应有结束标签,并且将相应处理。例如,html!(hr)
将返回 "<hr />"
创建包含其他元素的元素
html!(ul () [el!(li () "First Sibling")] [el!(li () "Second Sibling")])
将创建以下 HTML 字符串,其中包含一个有两个项目的无序列表
"<ul><li>First Sibling</li><li>Second Sibling</li></ul>"
在浏览器中,它呈现为
- 第一个兄弟
- 第二个兄弟
每个子组件都被方括号 []
包围,并输入到宏 el!
中,该宏创建组件。多个指定的子组件被视为兄弟。
el!(li () "Second Sibling")
的结果可以存储在变量中,并如下使用变量
let second_sibling = el!(li () "Second Sibling");
let result = html!(ul()[el!(li () "First Sibling")][second_sibling]);
这将返回相同的 HTML 字符串。
当子元素通过向量或数组指定时
let example_list = [
el!(li () "First Sibling"),
el!(li () "Second Sibling")
];
html!(ul () vec[example_list])
将创建以下 HTML 字符串,其中包含一个有两个项目的无序列表
"<ul><li>First Sibling</li><li>Second Sibling</li></ul>"
在浏览器中,它呈现为
- 第一个兄弟
- 第二个兄弟
在方括号 []
之前插入文本 vec
会让宏期望一个向量或数组。
使用 Rust 结构体生成 HTML
此库还提供了工具,可以通过函数 build_component()
从 Rust 结构体生成 HTML 字符串。
use std::fs;
fn main() {
use html_compile::compile::*;
use html_compile::types::*;
let item_list: Vec<String> = vec![1, 2, 3].iter().map(|x| format!("{}", x)).collect();
let item_components: Vec<Box<Component>> = item_list
.iter()
.map(|item| {
Box::new(Component {
tag: "li",
meta: None,
child: Child::Text(item),
})
})
.collect();
let input_component = Component {
tag: "section",
meta: Some(vec![
Attribute {
label: "class",
value: "Example",
},
]),
child: Child::ComponentVec(vec![
Box::new(Component {
tag: "h2",
meta: None,
child: Child::Text("A List of Items"),
}),
Box::new(Component {
tag: "p",
meta: None,
child: Child::Text("The list begins after the following line"),
}),
Box::new(Component {
tag: "hr",
meta: None,
child: Child::NoChild,
}),
Box::new(Component {
tag: "ul",
meta: None,
child: Child::ComponentVec(item_components),
}),
]),
};
let output = build_component(&input_component);
let write_output_path = "./output.html";
fs::write(write_output_path, output).expect("Unable to write to file");
}
文件 output.html
看起来如下
<section class="Example">
<h2>A List of Items</h2>
<p>The list begins after the following line</p><hr/><ul><li>1</li><li>2</li><li>3</li></ul>
</section>
这在浏览器中将如下呈现
项目列表
列表从以下行之后开始
- 1
- 2
- 3
将 HTML 插入现有 HTML 字符串
html_compile 提供了一个宏 insert_html!
和一个函数 insert_components
,该宏和函数将搜索占位符字符串 {COMPONENT}
并将其替换为生成的 HTML 字符串。
宏
insert_html!({test_contents}, div () "Hello World")
函数
let test_component: Component = Component {
tag: "div",
meta: None,
child: Child::Text("Hello World"),
};
insert_components(test_contents, test_component)
两者都在变量 test_contents
中搜索占位符 {COMPONENT}
并将其替换为 <div>Hello World</div>
。
在 crates.io 中查找
在 GitHub 上查找代码
注意,在 GitHub 上的代码中有一个名为 example
的目录,该目录提供了一个使用此库的示例应用程序。