-
I'm testing minijinja (after trying tera) and I don't know how to register a custom function in an For example, I'm using tera / minijinja to have a static site generator to use at work and I'd like to have a It would be used in this way:
Thanks. EDIT: in tera, the |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 2 replies
-
There are many ways in which this can be done and depending on what you have in mind you might like one more than the other. In general state access happens with use minijinja::State;
use serde::Serialize;
#[derive(Serialize)]
pub struct SiteLanguage {
iso2_letters: String,
name: String,
is_active: bool,
}
fn get_languages(state: &State) -> Vec<Value> {
let mut rv = Vec::new();
let current_lang = state.lookup("CURRENT_LANGUAGE").unwrap();
let current_lang = current_lang.as_str().unwrap();
for lang in state.lookup("LANGUAGES").unwrap().try_iter().unwrap() {
let lang = lang.to_string();
rv.push(Value::from_serializable(&SiteLanguage {
is_active = current_lang == lang,
name: get_language_name(name), // todo: de -> German etc.
iso2_letters: lang,
}));
}
rv
}
let mut env = Environment::new();
env.add_function("languages", get_languages);
env.add_global("LANGUAGES", Value::from(vec!["de", "en"]));
env.add_global("CURRENT_LANGUAGE", "de"); This is a trivial example where calling If you need extra functionality you can for instance you can store a custom struct in the context that you look up and then use If for instance your state is can be put into an use std::sync::Arc;
use minijinja::{State, value::Object};
#[derive(Debug)]
pub struct AppState {
config: ...,
}
#[derive(Debug)]
pub struct AppStateHolder {
state: Arc<AppState>,
}
impl Object for AppStateHolder {}
fn with_app_state<R, F: FnOnce(&AppState) -> R>(state: &State, f: F) -> R {
let app_state_holder = state.lookup("APP").unwrap();
f(&app_state_holder.downcast_object_ref::<AppStateHolder>().unwrap().state)
}
fn print_config(state: &State) -> String {
with_app_state(state, |app_state| {
format!("{:?}", app_state.config);
})
}
env.add_global("print_config", print_config);
let tmpl = env.get_template("whatever.txt").unwrap();
tmpl.render(context! {
APP => Value::from_object(AppStateHolder { state: app_state.clone() }),
}); Hope this helps. |
Beta Was this translation helpful? Give feedback.
-
Also to address your edit:
You can also do that in MiniJinja. If you implement https://docs.rs/minijinja/latest/minijinja/value/trait.Object.html Macros for instance in the engine are just custom objects that are callable: https://github.com/mitsuhiko/minijinja/blob/main/minijinja/src/vm/macro_object.rs |
Beta Was this translation helpful? Give feedback.
Also to address your edit:
You can also do that in MiniJinja. If you implement
Object
you can create a callable object. Just register it withenv.add_global("my_function", Value::from_object(MyCallableStruct { ... }))
.https://docs.rs/minijinja/latest/minijinja/value/trait.Object.html
Macros for instance in the engine are just custom objects that are callable: https://github.com/mitsuhiko/minijinja/blob/main/minijinja/src/vm/macro_object.rs