/ src / template.rs
template.rs
 1  use crate::error::JournalError;
 2  use std::path::Path;
 3  use tera::{Context, Tera};
 4  
 5  const NEW_ENTRY: &str = r#"[[!meta title="{{ title }}"]]
 6  [[!meta date="{{ date }}"]]
 7  {% for topic in topics %}
 8  [[!meta link="{{ topic }}"]]
 9  {% endfor %}
10  
11  "#;
12  
13  const NEW_TOPIC: &str = r#"[[!meta title="{{ title }}"]]
14  
15  Describe the topic here.
16  
17  # Entries
18  
19  [[!inline pages="link(.)" archive=yes reverse=yes trail=yes]]
20  "#;
21  
22  pub struct Templates {
23      tera: Tera,
24  }
25  
26  impl Templates {
27      pub fn new(dirname: &Path) -> Result<Self, JournalError> {
28          let glob = format!("{}/.config/templates/*", dirname.display());
29          let mut tera = Tera::new(&glob).unwrap_or_default();
30          add_default_template(&mut tera, "new_entry", NEW_ENTRY);
31          add_default_template(&mut tera, "new_topic", NEW_TOPIC);
32          Ok(Self { tera })
33      }
34  
35      pub fn new_draft(&self, context: &Context) -> Result<String, JournalError> {
36          self.render("new_entry", context)
37      }
38  
39      pub fn new_topic(&self, context: &Context) -> Result<String, JournalError> {
40          self.render("new_topic", context)
41      }
42  
43      fn render(&self, name: &str, context: &Context) -> Result<String, JournalError> {
44          match self.tera.render(name, context) {
45              Ok(s) => Ok(s),
46              Err(e) => match e.kind {
47                  tera::ErrorKind::TemplateNotFound(x) => Err(JournalError::TemplateNotFound(x)),
48                  _ => Err(JournalError::TemplateRender(name.to_string(), e)),
49              },
50          }
51      }
52  }
53  
54  fn add_default_template(tera: &mut Tera, name: &str, template: &str) {
55      let context = Context::new();
56      if let Err(err) = tera.render(name, &context) {
57          if let tera::ErrorKind::TemplateNotFound(_) = err.kind {
58              tera.add_raw_template(name, template)
59                  .expect("Tera::add_raw_template");
60          }
61      }
62  }