loco 框架目前的文档还是有点简陋,想通过直接看文档来上手,不太现实。 还是需要自己结合代码去查看三方的依赖库的文档。
目录结构
注意,后台模板及相关的资源文件是在 assets 目录下。 而不是 frontend 目录下,frontend 是 vite 创建的纯前端部分 (前后端分离的方案, loco 的默认首页就是在 frontend 中)。
Loco SaaS 项目,初始化的 assets 目录结构:
> tree assets/
assets/
├── i18n
│ ├── de-DE
│ │ └── main.ftl
│ ├── en-US
│ │ └── main.ftl
│ └── shared.ftl
├── static
│ ├── 404.html
│ └── image.png
└── views
└── home
└── hello.html
view
后台 HTML 模板存放在 assets/views 目录下,这点有点像 laravel, 不叫 template,而称之为 view。
Loco Views 分为两类:
- JSON view: 其实就是 API 接口的 JSON 返回。但是独立到一个文件中进行定义,确实代码简洁了不少。例如,用户接口的 JSON 返回,就定义在了 src/views/user.rs 中。
- Template view: 这个就是后台 HTML 模板。
但是 Loco Template View 有一点不一样,就是需要先封装在 src/views 中,然后才能在 src/controllers 中使用。 这在之前用过的 web 框架中从未见过,其他框架都是直接在 controller 中使用就行了。
官方的一个示例:
// src/views/dashboard.rs
pub fn home(v: impl ViewRenderer) -> Result<impl IntoResponse> {
format::render().view(&v, "home/hello.html", json!({}))
}
// src/controllers/dashboard.rs
pub async fn render_home(ViewEngine(v): ViewEngine<TeraView>) -> Result<impl IntoResponse> {
views::dashboard::home(v)
}
如何传递参数呢?
下面是 github issue 中的一段伪代码:
// controller.rs
render_home(e: Engine<TeraView>) -> Result<impl IntoResponse> {
views::dashboard::home(e, current_user)
}
// src/views/dashboard.rs
home(e: eng, user: User) -> impl ...{
format::template(e, "dashboard/home.html", json!(name: user.name))
}
Tera 模板引擎
https://keats.github.io/tera/
A powerful, easy to use template engine for Rust. Inspired by Jinja2 and Django templates.
看来是借鉴了 python 主流 web 框架的模板语法。 看了一下文档, 功能非常强大,不逊色于 django template。
示例:
<title>{% block title %}{% endblock title %}</title>
<ul>
{% for user in users -%}
<li><a href="{{ user.url }}">{{ user.username }}</a></li>
{%- endfor %}
</ul>
I18N 多语言支持
默认的 hello.html 中包含了一个示例:
<html><body>
<img src="/static/image.png" width="200"/>
<br/>
find this tera template at <code>assets/views/home/hello.html</code>:
<br/>
<br/>
{{ t(key="hello-world", lang="en-US") }},
<br/>
{{ t(key="hello-world", lang="de-DE") }}
</body></html>
比较奇怪的是 lang 参数,是否可以省略?
从 view 的配置文件 src/initializers/view_engine.rs 可以看到:
use fluent_templates::{ArcLoader, FluentLoader};
fluent-templates lets you to easily integrate Fluent localisation into your Rust application or library.
https://github.com/XAMPPRocky/fluent-templates
Cargo.toml
# view engine i18n
fluent-templates = { version = "0.8.0", features = ["tera"] }
unic-langid = "0.9.4"
# /view engine
回到正题,是否可以省略 lang,看起来不太容易:
In handlebars, fluent-templates will read the lang field in your handlebars::Context while rendering.
通过模板参数传过去看起来是省不了。
github issue 中有一个相关的讨论,不过目前还没有结论。
https://github.com/loco-rs/loco/pull/389
继续阅读
动手篇:rust web 框架 Loco 新建一个 HTML 页面
参考
- https://loco.rs/docs/the-app/views/
- https://keats.github.io/tera/
微信关注我哦 👍
我是来自山东烟台的一名开发者,有感兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊, 查看更多联系方式