kumo_template/lib.rs
1use minijinja::Environment;
2pub use minijinja::{context, Error, Template, Value};
3use minijinja_contrib::add_to_environment;
4use self_cell::self_cell;
5
6/// Holds a set of templates
7pub struct TemplateEngine {
8 env: Environment<'static>,
9}
10
11impl Default for TemplateEngine {
12 fn default() -> Self {
13 Self::new()
14 }
15}
16
17impl TemplateEngine {
18 pub fn new() -> Self {
19 let mut env = Environment::new();
20 env.set_unknown_method_callback(minijinja_contrib::pycompat::unknown_method_callback);
21 add_to_environment(&mut env);
22 Self { env }
23 }
24
25 /// Add a named template with the specified source.
26 /// If name ends with `.html` then automatical escaping of html entities
27 /// will be performed on substitutions.
28 pub fn add_template<N, S>(&mut self, name: N, source: S) -> Result<(), Error>
29 where
30 N: Into<String>,
31 S: Into<String>,
32 {
33 self.env.add_template_owned(name.into(), source.into())
34 }
35
36 /// Get a reference to a named template
37 pub fn get_template(&self, name: &str) -> Result<Template<'_, '_>, Error> {
38 self.env.get_template(name)
39 }
40
41 /// Define a global value that can be reference by all templates
42 pub fn add_global<N, V>(&mut self, name: N, value: V)
43 where
44 N: Into<String>,
45 V: Into<Value>,
46 {
47 self.env.add_global(name.into(), value)
48 }
49
50 pub fn render<CTX>(&self, name: &str, source: &str, context: CTX) -> Result<String, Error>
51 where
52 CTX: serde::Serialize,
53 {
54 self.env.render_named_str(name, source, context)
55 }
56}
57
58pub type TemplateList<'a> = Vec<Template<'a, 'a>>;
59
60self_cell!(
61 /// CompiledTemplates is useful when you have a set of templates
62 /// that you will expand frequently in a tight loop.
63 /// Because the underlying crate returns only references to `Template`s,
64 /// it is a covariant, self-referential structure that needs to be
65 /// constructed like this:
66 ///
67 /// ```rust
68 /// fn get_templates<'b>(
69 /// engine: &'b TemplateEngine
70 /// ) -> anyhow::Result<TemplateList<'b>> {
71 /// let mut templates = vec![];
72 /// templates.push(engine.get_template("something")?);
73 /// Ok(templates)
74 /// }
75 ///
76 /// let engine = TemplateEngine::new();
77 /// engine.add_template("something", "some text")?;
78 /// let compiled = CompiledTemplates::try_new(engine, |engine| {
79 /// get_templates(engine)
80 /// });
81 /// ```
82 pub struct CompiledTemplates {
83 owner: TemplateEngine,
84 #[covariant]
85 dependent: TemplateList,
86 }
87);