use crate::error::JournalError; use std::path::Path; use tera::{Context, Tera}; const NEW_ENTRY: &str = r#"[[!meta title="{{ title }}"]] [[!meta date="{{ date }}"]] {% for topic in topics %} [[!meta link="{{ topic }}"]] {% endfor %} "#; const NEW_TOPIC: &str = r#"[[!meta title="{{ title }}"]] Describe the topic here. # Entries [[!inline pages="link(.)" archive=yes reverse=yes trail=yes]] "#; pub struct Templates { tera: Tera, } impl Templates { pub fn new(dirname: &Path) -> Result { let glob = format!("{}/.config/templates/*", dirname.display()); let mut tera = if let Ok(tera) = Tera::new(&glob) { tera } else { Tera::default() }; add_default_template(&mut tera, "new_entry", NEW_ENTRY); add_default_template(&mut tera, "new_topic", NEW_TOPIC); Ok(Self { tera }) } pub fn new_draft(&self, context: &Context) -> Result { self.render("new_entry", context) } pub fn new_topic(&self, context: &Context) -> Result { self.render("new_topic", context) } fn render(&self, name: &str, context: &Context) -> Result { 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"); } } }