Rust动态模板引擎rocket_dyn_templates的使用,支持快速构建类型安全的Web页面渲染
Rust动态模板引擎rocket_dyn_templates的使用,支持快速构建类型安全的Web页面渲染
这个crate为Rocket添加了动态模板渲染支持。它能自动发现模板,提供Responder
来渲染模板,并在调试模式下自动重新加载模板。目前支持Handlebars和Tera。
使用方法
- 启用与您选择的模板引擎对应的
rocket_dyn_templates
特性:
[dependencies.rocket_dyn_templates]
version = "0.2.0"
features = ["handlebars", "tera"]
-
在可配置的
template_dir
目录(默认:{rocket_root}/templates
)中编写Handlebars(.hbs
)和/或Tera(.tera
)模板文件。 -
附加
Template::fairing()
并使用Template::render()
返回一个Template
,提供模板文件名(减去最后两个扩展名):
use rocket_dyn_templates::{Template, context};
#[get("/")]
fn index() -> Template {
Template::render("template-name", context! { field: "value" })
}
#[launch]
fn rocket() -> _ {
rocket::build().attach(Template::fairing())
}
完整示例
以下是一个完整的Rocket web应用示例,使用rocket_dyn_templates
渲染动态模板:
// Cargo.toml
[dependencies]
rocket = "0.5.0"
rocket_dyn_templates = { version = "0.2.0", features = ["tera"] }
// src/main.rs
#[macro_use] extern crate rocket;
use rocket_dyn_templates::{Template, context};
// 定义路由
#[get("/")]
fn index() -> Template {
Template::render("index", context! {
title: "Rocket Templates",
items: vec!["Item 1", "Item 2", "Item 3"],
})
}
#[get("/user/<name>")]
fn user(name: &str) -> Template {
Template::render("user", context! {
username: name,
})
}
#[launch]
fn rocket() -> _ {
rocket::build()
.attach(Template::fairing()) // 添加模板支持
.mount("/", routes![index, user])
}
<!-- templates/index.tera -->
<!DOCTYPE html>
<html>
<head>
<title>{{ title }}</title>
</head>
<body>
<h1>{{ title }}</h1>
<ul>
{% for item in items %}
<li>{{ item }}</li>
{% endfor %}
</ul>
</body>
</html>
<!-- templates/user.tera -->
<!DOCTYPE html>
<html>
<head>
<title>User {{ username }}</title>
</head>
<body>
<h1>Welcome, {{ username }}!</h1>
</body>
</html>
这个示例展示了:
- 创建一个简单的Rocket web应用
- 使用Tera模板引擎渲染动态页面
- 传递上下文数据到模板
- 处理路由参数
- 使用列表渲染
模板文件应放在项目的templates
目录下,Rocket会自动发现它们并在开发模式下热重载。
完整示例demo
下面是一个更完整的示例,展示如何使用rocket_dyn_templates
构建一个博客系统:
// Cargo.toml
[dependencies]
rocket = "0.5.0"
rocket_dyn_templates = { version = "0.2.0", features = ["tera"] }
serde = { version = "1.0", features = ["derive"] }
// src/main.rs
#[macro_use] extern crate rocket;
use rocket_dyn_templates::{Template, context};
// 博客文章结构体
#[derive(Debug)]
struct Post {
id: u32,
title: String,
content: String,
published: bool,
}
// 模拟数据库
fn get_all_posts() -> Vec<Post> {
vec![
Post {
id: 1,
title: "Rocket入门".to_string(),
content: "学习Rocket框架的基础知识".to_string(),
published: true,
},
Post {
id: 2,
title: "模板引擎".to_string(),
content: "使用rocket_dyn_templates渲染页面".to_string(),
published: true,
},
]
}
// 首页路由 - 显示所有文章
#[get("/")]
fn index() -> Template {
let posts = get_all_posts();
Template::render("blog/index", context! {
title: "我的博客",
posts: posts,
})
}
// 文章详情页
#[get("/post/<id>")]
fn post(id: u32) -> Option<Template> {
get_all_posts()
.into_iter()
.find(|p| p.id == id && p.published)
.map(|post| {
Template::render("blog/post", context! {
title: &post.title,
post: post,
})
})
}
#[launch]
fn rocket() -> _ {
rocket::build()
.attach(Template::fairing())
.mount("/", routes![index, post])
}
<!-- templates/blog/index.tera -->
<!DOCTYPE html>
<html>
<head>
<title>{{ title }}</title>
</head>
<body>
<h1>{{ title }}</h1>
<div class="posts">
{% for post in posts %}
<article>
<h2><a href="/post/{{ post.id }}">{{ post.title }}</a></h2>
<p>{{ post.content|truncate(length=50) }}</p>
</article>
{% endfor %}
</div>
</body>
</html>
<!-- templates/blog/post.tera -->
<!DOCTYPE html>
<html>
<head>
<title>{{ title }}</title>
</head>
<body>
<h1>{{ post.title }}</h1>
<p>{{ post.content }}</p>
<a href="/">返回首页</a>
</body>
</html>
这个更完整的示例展示了:
- 使用结构体组织数据
- 实现简单的文章列表和详情页
- 使用Tera模板的过滤器功能(truncate)
- 处理可选路由(返回Option<Template>)
- 更复杂的模板组织结构
1 回复