Loader re-loading every time #363
-
I am using |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 4 replies
-
It seems the solution is that I need to call This works: async fn init_jinja_env() -> minijinja::Environment<'static> {
let mut env = minijinja::Environment::new();
env.set_loader(minijinja::path_loader("templates"));
if std::env::var("DEV").is_err() {
for entry_res in std::fs::read_dir("templates").unwrap() {
let entry = entry_res.unwrap();
let file_name = entry.file_name().into_string().unwrap();
_ = env.get_template(&file_name);
}
}
env
} Unrelated, but thank you for the great library! |
Beta Was this translation helpful? Give feedback.
-
I'm confused how this is possible. The loader will only load a template once. You can easily validate this yourself: use std::collections::BTreeMap;
use std::sync::Mutex;
#[test]
fn test_load_once() {
let mut env = Environment::new();
let loaded = Mutex::<BTreeMap<String, usize>>::default();
env.set_loader(move |name| {
let mut loaded = loaded.lock().unwrap();
let x = loaded.entry(name.to_string()).or_default();
*x += 1;
Ok(Some(format!("loaded {} times", *x)))
});
let x = env.get_template("index.html").unwrap();
assert_eq!(x.render(()).unwrap(), "loaded 1 times");
let x = env.get_template("index.html").unwrap();
assert_eq!(x.render(()).unwrap(), "loaded 1 times");
} I wonder if what you run into is that the loader loads lazily which means that you might not have seen it before yet. That lazy loading behavior is quite intentional, but obviously iterating over known templates and loading them once will prime it. |
Beta Was this translation helpful? Give feedback.
-
I think the request handler being used by Axum is adding the template, but then it's returning to its initialized form for the next request. Here's the most common code I use to render a template: pub fn render(jinja: Environment<'_>, name: &str, ctx: Value) -> String {
let tmpl = jinja.get_template(name).expect("gets template");
tmpl.render(ctx).expect("renders template")
} This is called by an Axum handler like so: pub async fn home(State(state): State<AppState>) -> Html<String> {
Html(render(state.jinja, "home.jinja", context!()))
} The It seems the |
Beta Was this translation helpful? Give feedback.
It seems the solution is that I need to call
get_template
on each template when I initialize my Environment. I tried that before, but was confused because the code I found for extracting the filename from dir entries usingformat!("{:?}", entry.file_name())
was adding quote characters around the string, e.g."home.jinja"
instead ofhome.jinja
.This works: