askama 是什么
Askama implements a template rendering engine based on Jinja. It generates Rust code from your templates at compile time based on a user-defined struct to hold the template's context.
askama 即一套模板系统,可以集成到 rust 项目中,并不局限于 axum 中,也不局限于 HTML,任何的模板使用场景都是可以的。
类似 golang 内置的模板系统,及 php laravel 中的 blade,python django 的模板。语法都非常类似。
项目地址:
https://github.com/djc/askama
为何要使用 askama 这里的模板系统
- 可以将 HTML 代码写在独立的文件中,这样就不需要像上一篇 axum 介绍中 axum 返回 HTML form 表单,并处理 post 请求,将 HTML 代码混在 rust 代码中。这样不方便编辑,也无法高效利用编辑器或 IDE 的增强功能。
- 可以基于 base 模板做继承,方便保证一个网站所有页面的风格统一,及 HTML 代码的模块化,及复用。
- 在代码中实现一些 if,及 for 逻辑。
askama V.S. minijinja
- 2.6K https://github.com/djc/askama
- 1.1K https://github.com/mitsuhiko/minijinja
添加 askama 依赖
编辑 Cargo.toml 配置文件,增加 askama 及 askama_axum 依赖
[dependencies]
askama = { version = "0.12", features = ["with-axum", "mime", "mime_guess"] }
askama_axum = "0.3.0"
axum = "0.6"
新增模板目录
mkdir templates
新增 html 模板
例如,base.html
内容可以随便写,即一个简单的 HTML 文件。
<h1>Hello </h1>
axum 中使用
use askama::Template;
#[derive(Template)]
#[template(path = "base.html")]
struct HelloTemplate<'a> {
name: &'a str,
}
async fn hello_template() -> HelloTemplate<'static> {
HelloTemplate { name: "world" }
}
然后 route 中使用这个 hello_template 即可
let app = Router::new()
.route("/some_path", get(hello_template))
;
到此,axum 与 askama 的集成完成。以下是测试过程中遇到的问题。
单引号 a 与生命周期
下面 rust 代码中,单引号 a 的作用是什么:
struct HelloTemplate<'a> {
name: &'a str,
}
在 Rust 代码中,单引号 'a
用于定义一个生命周期参数。在这个特定的代码片段中,'a
是用于泛型结构体 HelloTemplate
的生命周期参数。
生命周期参数用于描述引用的有效期,以确保在引用的数据不再有效之前,引用本身仍然有效。在这种情况下,'a
表示 name
字段的引用的生命周期。
HelloTemplate
结构体中的 name
字段的类型是 &'a str
,意味着它是一个指向字符串的引用,该引用的生命周期与结构体的生命周期参数 'a
相关联。这意味着 name
字段的引用不能超过 'a
所表示的生命周期。
通过使用生命周期参数,Rust 的借用检查器可以在编译时验证引用的有效性,防止悬垂引用或无效引用的出现,从而提供内存安全性和避免潜在的错误。
askama 模板继承
https://djc.github.io/askama/template_syntax.html#child-template
{% extends "base.html" %}
{% block title %}Index{% endblock %}
{% block head %}
<style>
</style>
{% endblock %}
{% block content %}
<h1>Index</h1>
<p>Hello, world!</p>
{% call super() %}
{% endblock %}
askama 官方依赖配置示例
https://djc.github.io/askama/integrations.html#axum-integration
Enabling the with-axum feature appends an implementation of Axum's IntoResponse trait for each template type. This makes it easy to trivially return a value of that type in a Axum handler. See the example from the Askama test suite for more on how to integrate.
如官方 github 的 axum 整合示例中的 Cargo.toml 依赖配置
https://github.com/djc/askama/blob/main/askama_axum/Cargo.toml
[dependencies]
askama = { version = "0.12", path = "../askama", default-features = false, features = ["with-axum", "mime", "mime_guess"] }
需要 enable with-axum feature。
而,我之前配置的是:
[dependencies]
askama = "0.12.1"
于是我参考官方配置修改成了
askama = { version = "0.12", default-features = false, features = ["with-axum", "mime", "mime_guess"] }
askama 官方代码示例
https://github.com/djc/askama/blob/main/askama_axum/tests/basic.rs
could not find askama_axum
in the list of imported crates
error[E0433]: failed to resolve: could not find `askama_axum` in the list of imported crates
--> src/main.rs:101:10
|
101 | #[derive(Template)]
| ^^^^^^^^ could not find `askama_axum` in the list of imported crates
|
= note: this error originates in the derive macro `Template` (in Nightly builds, run with -Z macro-backtrace for more info)
在 Cargo.toml 中添加了 askama_axum 之后,就可以了。
[dependencies]
askama = { version = "0.12", features = ["with-axum", "mime", "mime_guess"] }
askama_axum = "0.3.0"
axum = "0.6"
unknown field
error[E0609]: no field `title` on type `&HelloTemplate<'a>`
--> src/main.rs:101:10
|
101 | #[derive(Template)]
| ^^^^^^^^ unknown field
|
= note: available fields are: `name`
= note: this error originates in the derive macro `Template` (in Nightly builds, run with -Z macro-backtrace for more info)
将模板文件中的 title 改为 name,就可以编译通过了。
rust 三方依赖包,为何会有 features 的概念
在 Rust 的第三方依赖包中,features 的概念用于启用或禁用库的特定功能或选项。 这允许你根据你的项目需求,在构建依赖包时进行选择性地启用或禁用功能。
许多依赖包提供了一些可选的功能,但不是所有用户都需要或希望使用这些功能。 为了保持库的灵活性和轻量性,开发人员将这些功能作为可选项提供,而不是默认包含在库中。
查看合集
📖 Rust web 框架 axum 教程:从入门到遥遥领先
参考
- https://www.reddit.com/r/rust/comments/11gizhc/axum_sqlite_minijinja_htmx_winning_website_combo/
- bootstrap 模板: https://getbootstrap.com/docs/5.3/examples/jumbotron/
- askama 的官方整合教程: https://github.com/djc/askama/blob/main/askama_axum/tests/basic.rs
- 基于 axum/askama/htmx 的教程: https://www.joeymckenzie.tech/blog/templates-with-rust-axum-htmx-askama/
微信关注我哦 👍
我是来自山东烟台的一名开发者,有感兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊, 查看更多联系方式