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 }