markup.rs
是一个由过程宏驱动的Rust模板引擎,它在编译时解析模板并生成最优的Rust代码以在运行时渲染模板。模板可以嵌入Rust代码,这些代码由Rust编译器进行类型检查,实现完全的类型安全。
特性
- 完全类型安全,使用诸如rust-analyzer等编辑器扩展时可显示内联高亮错误。
- 受Haml、Slim和Pug启发的简洁易用、不容易出错的语法。
- 零不安全代码。
- 零运行时依赖。
- ⚡ 速度极快。在这个基准测试中,在不使用不安全代码的模板引擎中速度最快,总体第二快。
安装
[dependencies]
markup = "0.15.0"
框架集成
我们有以下web框架的集成示例:
快速示例
markup::define! {
Home<'a>(title: &'a str) {
@markup::doctype()
html {
head {
title { @title }
style {
"body { background: #fafbfc; }"
"#main { padding: 2rem; }"
}
}
body {
@Header { title }
#main {
p {
"本域名用于文档中的说明性示例。您可以在文献中使用此域名,无需事先协调或请求许可。"
}
p {
a[href = "https://www.iana.org/domains/example"] {
"更多信息..."
}
}
}
@Footer { year: 2020 }
}
}
}
Header<'a>(title: &'a str) {
header {
h1 { @title }
}
}
Footer(year: u32) {
footer {
"(c) " @year
}
}
}
fn main() {
println!(
"{}",
Home {
title: "示例域名"
}
)
}
输出
<!DOCTYPE html><html><head><title>示例域名</title><style>body { background: #fafbfc; }#main { padding: 2rem; }</style></head><body><header><h1>示例域名</h1></header><div id="main"><p>本域名用于文档中的说明性示例。您可以在文献中使用此域名,无需事先协调或请求许可。</p><p><a href="https://www.iana.org/domains/example">更多信息...</a></p></div><footer>(c) 2020</footer></body></html>
输出(手动美化)
<!doctype html>
<html>
<head>
<title>示例域名</title>
<style>
body {
background: #fafbfc;
}
#main {
padding: 2rem;
}
</style>
</head>
<body>
<header><h1>示例域名</h1></header>
<div id="main">
<p>
本域名用于文档中的说明性示例。您可以在文献中使用此域名,无需事先协调或请求许可。
</p>
<p>
<a href="https://www.iana.org/domains/example">更多信息...</a>
</p>
</div>
<footer>(c) 2020</footer>
</body>
</html>
语法参考 (待完善)
markup::define! 和 markup::new!
定义模板有两种方式: markup::define!
和 markup::new!
。
markup::define!
定义具有命名参数的模板。这些模板不能访问外部作用域的变量。这些模板可以有泛型参数。在底层,markup::define!
编译为实现了 markup::Render
和 std::fmt::Display
trait 的 Rust 结构体。
代码 |
---|
|
输出 |
|
markup::new!
定义没有任何参数的模板。这些模板可以访问外部作用域的变量。
代码 |
---|
|
输出 |
|
表达式
模板可以包含裸字面值,这些值会按原样渲染。它们也可以包含以 @
符号开头的表达式(包括函数和宏调用)。所有字符串都会进行HTML转义,除非它们被包裹在 markup::raw()
中。
代码 |
---|
|
输出 |
|
元素
元素使用类似CSS选择器的语法定义。元素可以在花括号中包含其他嵌套元素,或者在自闭合元素后跟分号。
代码 |
---|
|
输出 |
|
属性
属性在元素名称后定义。id
和 class
属性可以使用类似CSS选择器的语法,使用 #
和 .
定义。可以使用此简写语法多次指定类。其他属性在方括号中指定。
代码 |
---|
|
<div id="foo" class="bar baz"></div>
<div id="post-123" class="post category-tutorial"></div>
<input checked>
<input>
<input checked>
<input type="text">
<div data-post-id="123"></div>
<div data-baz="quux" data-foo="bar"></div>
@if 和 @if let
@if
和 @if let
的工作方式类似于 Rust。
代码 |
---|
|
输出 |
|
@match
@match
的工作方式类似于 Rust,但分支必须用大括号括起来。
代码 |
---|
|
输出 |
|
@for
@for
的工作方式类似于 Rust。
代码 |
---|
|
输出 |
|
语句
模板可以包含以 @
符号开头的语句。最常用的是 @let
语句,用于计算一个值以供后续重复使用。@fn
可用于定义函数。此外还支持 @struct
、@mod
、@impl
、@const
、@static
等。
代码 |
---|
|
输出 |
|