Почему Tera говорит TemplateNotFound при рендеринге шаблона?
Я экспериментирую с созданием веб-приложения на Rust с помощью Tera, и каждый раз паника
render()
звоните ниже. Пример фрагмента кода:
async fn login(tera: web::Data<Tera>) -> impl Responder {
let mut data = Context::new();
data.insert("title", "Login");
let rendered = tera.render("login.html", &data).unwrap();
HttpResponse::Ok().body(rendered)
}
Ссылка на мое репо для обзора: https://github.com/ClusterberrySquirrels/oasis/blob/oasis_db/src/main.rs
Я получаю следующий панический звонок:
thread 'actix-rt:worker:0' panicked at 'called `Result::unwrap()` on an `Err` value: Error { kind: TemplateNotFound("login.html"), source: None }', src/main.rs:101:53
Что-то устранило эту панику, когда у меня была такая же проблема в начале этого проекта на
index.html
страница. Сначала я подумал, что проблема вызвана Tera, но я не нашел никаких шагов, чтобы исправить это. В конце концов что-то, что я сделал, заставило его вести себя так, как задумано, и до сих пор все было в порядке. Буду признателен за любой совет о том, как это исправить и избежать этого в будущем.
Файловая структура:
Project Folder\
templates\
login.html
index.html
src\
main.rs
Устранение неисправностей на моей стороне не обязательно по порядку:
- Переключите инструментальную цепочку по умолчанию со стабильного -> сборка / запуск груза на ночь -> сборка / запуск груза и обратно.
- обновление rustup
- sudo apt update
- sudo apt upgrade
- wsl --set-default-version 2
- груз чистый
- Удалите целевую папку, затем очистите груз, сборку груза, пробег груза
- обновление груза
Обновление вопроса: минимальный воспроизводимый пример.
use actix_web::{HttpServer, App, web, HttpResponse, Responder};
use tera::{Tera, Context};
async fn index(tera: web::Data<Tera>) -> impl Responder {
let mut data = Context::new();
let posts = [
Post {
title: String::from("This is the first link"),
link: String::from("https://example.com"),
author: String::from("Nutrition-Tracker"),
},
Post {
title: String::from("This is the second Link"),
link: String::from("https://example.com"),
author: String::from("Other cool app"),
},
];
data.insert("title", "index");
data.insert("posts", &posts);
let rendered = tera.render("index.html", &data).unwrap(); // TemplateNotFound??
HttpResponse::Ok().body(rendered)
}
async fn login(tera: web::Data<Tera>) -> impl Responder {
let mut data = Context::new();
data.insert("title", "Login");
let rendered = tera.render("login.html", &data).unwrap(); // TemplateNotFound??
HttpResponse::Ok().body(rendered)
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| {
let tera = Tera::new("templates/**/*").unwrap();
App::new()
.data(tera)
.route("/", web::get().to(index))
.route("/login", web::get().to(login))
})
.bind("127.0.0.1:8000")?
.run()
.await
}
2 ответа
Что касается вашей отладки, у меня была аналогичная проблема, и теперь я ее решил, поэтому делюсь этим.
TemplateNotFound
— это правильное сообщение об ошибке, другими словами, среда выполнения Rust может не распознать шаблон. Посоветую по отладке.
Вы объявляете каталог шаблонов tera для чтения следующим образом:
let tera = Tera::new(concat!(env!("CARGO_MANIFEST_DIR"), "/templates/**/*")).unwrap();
// Let's check this
println!("tera root {:?}", concat!(env!("CARGO_MANIFEST_DIR"), "/templates/**/*"));
Моя проблема заключалась в том, что место, где распознается среда выполнения, различается между dev-env и prod-env. Это вызвано моим процессом развертывания (я создавал dev-env и развертывал его в prod env).
Я разобрался в проблеме. Я также использую кубернеты для этого приложения, и порты, которые я выбирал, были заняты кубернетами в случайное время. Я убил все процессы, однако проблема все еще остается, и это проблема для другого потока.