2 个版本
0.0.2 | 2019年3月5日 |
---|---|
0.0.1 | 2019年2月24日 |
#60 在 #handlebars
在 wearte 中使用
7KB
175 行
[WIP] wearte
wearte 代表 Wow Even Another Rust Template Engine,它是最快的 Rust 模板引擎之一。它使用类似 Handlebars 的语法。
此包是从 yarte 分叉的,修复了关于许可的棘手问题。yarte 本身是 askama 的直接后代。你可以在 LICENSE-MIT 中找到它们许可证的副本。
为什么要使用 derive 模板引擎?
有许多基于 mustache 或/和 handlebars 的模板引擎,我还没有知道任何一种是从编译器中派生出模板编译的(例如 askama)。通过从这个过程中派生这个任务,我们可以使用我们自己的工具或第三方工具(如 LLVM)来优化生成的指令。在其他情况下这是不可能的,这将在我们的 web 服务器中形成一个瓶颈,达到毫秒级别。正因为如此,wearte
将模板放在优先级,通过静态分配其需求。因此,我们写得比宏 write!
更快,易于并行化,并在其默认的 html 转义中使用 simd。
总之,使用 derive 是为了最快和最简单。
入门
将 wearte 依赖项添加到您的 Cargo.toml 文件中
[dependencies]
wearte = "0.0.1"
为了在模板中使用结构体,您必须调用过程宏 Template
。例如,在下面的代码中,我们将使用结构体 CardTemplate
,然后定义 s
为包含内容的 CardTemplate
。
use wearte::Template;
#[derive(Template)]
#[template(path = "hello.html")]
struct CardTemplate<'a> {
title: &'a str,
body: &'a str,
}
let template = CardTemplate {
title: "My Title",
body: "My Body",
};
现在我们的结构体已经定义,让我们在模板中使用它。wearte 模板看起来像普通文本,其中嵌入 wearte 表达式。
假设文件 hello.html
看起来像这样
<div class="entry">
<h1>{{title}}</h1>
<div class="body">
{{body}}
</div>
</div>
并调用模板以在 String
中分配结果,并将其用 wearte::Result 包装返回。
template.call()
<div class="entry">
<h1> My Title </h1>
<div class="body">
My Body
</div>
</div>
模板化
wearte 使用开括号 {{
和闭括号 }}
来解析内部内容,具体取决于使用的功能。大多数功能由 Handlebars 定义,例如路径、注释、HTML、助手和部分。其他如将 Rust 代码添加到模板中,显然是由 wearte 定义。
// precompile your template
#[derive(Template)]
#[template(source = "Hello, {{ name }}!", ext = "txt")]
struct HelloTemplate<'a> {
name: &'a str,
}
assert_eq!(
"Hello, world!",
HelloTemplate { name: "world" }.call().unwrap() // then call it.
);
注释
{{! Comments can be written }}
{{!-- in two different ways --}}
HTML
wearte 将由 {{表达式}}
返回的值进行 HTML 转义。如果您不想让 wearte 转义值,请使用 "三重反引号",{{{
。例如,有以下的结构体
let t = CardTemplate {
title: "All about <p> Tags",
body: "<p>This is a post about <p> tags</p>"
};
和以下的模板
<div class="entry">
<h1>{{title}}</h1>
<div class="body">
{{{body}}}
</div>
</div>
将得到以下结果
<div class="entry">
<h1>All About <p> Tags</h1>
<div class="body">
<p>This is a post about <p> tags</p>
</div>
</div>
助手
内置
if、else 和 else if 助手{{#if isLiked}}
Liked!
{{else if isSeen}}
Seen!
{{else}}
Sorry ...
{{\if}}
使用助手let author = Author {
name: "J. R. R. Tolkien"
};
{{#with author}}
<p>{{name}}</p>
{{/with}}
每个助手{{#each into_iter}}
{{#- if first || last -}}
{{ index }}
{{- else -}}
{{ index0 }}
{{/-if }} {{ key }}
{{\-each}}
unless 助手{{#unless isAdministrator-}}
Ask administrator.
{{\-unless}}
[WIP] 日志助手{{#log }} {{log\}}
[WIP] 查找助手{{#lookup }} {{\lookup}}
[WIP] 用户定义
为了创建一个用户定义的助手 ..
文本字面量
布尔值、整数、浮点数等不会被转义以提高性能。如果可能的话,建议使用这些类型。
部分
可以使用部分来生成使用预定义函数的更快代码。
{{> path/to/file }}
Rust 代码
wearte 提供了在 HTML 文件中使用原始 Rust 代码的可能性。这是有限的,但大多数基本语法都得到了支持。
{{#with getUser(id)?-}}
Hello, {{#if isAdmin || isDev }}Mr. {{\if}}{{ user }}
{{/-with}}
Hello, {{#each conditions}}
{{#-if let Some(check) = cond }}
{{#-if check }}
{{ let cond = if check { "&foo" } else { "&"} }}
{{
if check {
cond
} else if let Some(cond) = key.cond {
if cond {
"1"
} else {
"2"
}
} else {
"for"
}
}}
{{- else if let Some(_) = cond }}
{{- else if let Some(cond) = key.check }}
{{#-if cond -}}
baa
{{/-if }}
{{- else -}}
{{ cond.is_some() }}
{{/-if-}}
{{ cond.is_some() && true }}
{{-else if let Some(cond) = check }}
{{#-if cond -}}
bar
{{/-if}}
{{- else -}}
None
{{/-if
}}{{/each}}!
{{ let mut a = name.chars() }}
{{
let b: String = loop {
if a.next().is_none() && true {
let mut a = name.repeat(1);
a.push('!');
break a.repeat(2);
} else {
continue;
}
}
}}
{{ b }}
{{ let doubled = a.iter().map(|x| x * 2).collect::<Vec<_>>() }}
{{ let doubled: Vec<usize> = a.iter().map(|x| x * 2).collect() }}
{{#each doubled -}}
{{ key + 1 }}
{{/-each}}
路线图
- 在文本字面量中减少 html5
- 为生成定义的助手和过滤器生成构建器
-
>|
在 fmt::Formatter 上的过滤器 - 在 fmt::Formatter 上连接过滤器,类似 Unix(在可能的情况下)
- ... 你可以打开一个问题!
依赖关系
~2.5MB
~56K SLoC