我正在使用 Axum 制作一个网络应用程序。我想向 Minijinja 模板中的活动链接添加属性和样式(例如 aria-current)。为了做到这一点,我需要每个模板中的请求路径,包括错误页面的模板。
到目前为止,我所拥有的是普通页面,我使用
OriginalUri
提取器将请求路径传递到上下文中。对于错误页面,我为我的应用程序错误类型实现了 IntoResponse
,它无权访问请求。我想过更新中间件中的minijinja::Environment
,但由于我将它作为应用程序状态传递,所以它是只读的。
如何确保每个模板都可以访问请求路径?
我认为 axum/examples/templates-minijinja 是你指的模板。
通常您可以编辑模板上下文,但您提到需要支持
IntoResponse
,而它没有request
。目前尚不清楚为什么 IntoResponse
能够访问 AppState
/Environment
,但你的问题暗示它可以。
您可以尝试用其他上下文来补充您的错误,允许您将
OriginalUri
传递到 context!
内的 IntoResponse
:
pub struct ContextualizedError {
pub error: Error,
pub original_uri: OriginalUri
}
impl IntoResponse for ContextualizedError {
fn into_response(self) -> Response {
let Self{error, original_uri} = self;
// However you got the template before.
let env = Environment::new();
let template = env.get_template("error.txt").unwrap();
let result = template.render(context! { error => error, path => original_uri.0.path() }).unwrap();
result.into_response()
}
}
或者,您可以制作一个中间件,从
Environment
克隆 AppState
,将路径添加为全局变量,然后 将其存储为请求扩展。这种替代解决方案的问题是在 Environment
内克隆多个内部数据结构效率低下。
我没有看到一种创建新环境、引用旧环境的方法,除了添加一个额外的全局变量,这是有效执行中间件方法所必需的。