summaryrefslogtreecommitdiff
path: root/src/template.rs
blob: 89c1a1518c35ba1f7dd30dbb7861f141df2f5b5b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
use crate::error::JournalError;
use std::path::Path;
use tera::{Context, Tera};

const NEW_ENTRY: &str = r#"[[!meta title="{{ title }}"]]
[[!meta date="{{ date }}"]]

This is the default template.
"#;

pub struct Templates {
    tera: Tera,
}

impl Templates {
    pub fn new(dirname: &Path) -> Result<Self, JournalError> {
        let glob = format!("{}/.config/templates/*", dirname.display());
        let mut tera = Tera::new(&glob).expect("Tera::new");
        add_default_template(&mut tera, "new_entry", NEW_ENTRY);
        Ok(Self { tera })
    }

    pub fn new_draft(&self, context: &Context) -> Result<String, JournalError> {
        self.render("new_entry", &context)
    }

    fn render(&self, name: &str, context: &Context) -> Result<String, JournalError> {
        match self.tera.render(name, &context) {
            Ok(s) => Ok(s),
            Err(e) => match e.kind {
                tera::ErrorKind::TemplateNotFound(x) => Err(JournalError::TemplateNotFound(x)),
                _ => Err(JournalError::TemplateRender(name.to_string(), e)),
            },
        }
    }
}

fn add_default_template(tera: &mut Tera, name: &str, template: &str) {
    let context = Context::new();
    if let Err(err) = tera.render(name, &context) {
        if let tera::ErrorKind::TemplateNotFound(_) = err.kind {
            tera.add_raw_template(name, template)
                .expect("Tera::add_raw_template");
        }
    }
}