A small, fast, static site generator
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 90 lines 2.4 kB view raw
1use anyhow::Result; 2use minijinja::value::Value; 3use serde::Serialize; 4use std::{ 5 fs, 6 path::{Path, PathBuf}, 7}; 8use walkdir::WalkDir; 9 10use crate::{ 11 config::Config, 12 markdown::{FrontMatter, Page}, 13}; 14 15#[derive(Serialize)] 16pub struct TemplateContext<'a> { 17 pub pages: &'a [Page], 18 pub meta: &'a FrontMatter, 19 pub content: &'a String, 20 pub path: &'a PathBuf, 21} 22 23impl<'a> TemplateContext<'a> { 24 /// Create a new `TemplateContext` object given a page list 25 /// and current page. 26 pub fn new(pages: &'a Vec<Page>, page: &'a Page) -> Self { 27 Self { 28 pages, 29 meta: &page.meta, 30 content: &page.content, 31 path: &page.rel_path, 32 } 33 } 34} 35 36pub struct TemplateEnvironment<'a> { 37 env: minijinja::Environment<'a>, 38} 39 40impl<'a> TemplateEnvironment<'a> { 41 /// Returns a new, empty, template environment. 42 pub fn new() -> Self { 43 Self { 44 env: minijinja::Environment::new(), 45 } 46 } 47 48 /// Load all templates from the templates directory. 49 /// 50 /// This function succeeds if all templates are valid, or if the `templates` 51 /// directory doesn't exist. 52 pub fn load_templates(&mut self, config: &Config) -> Result<()> { 53 let tmpl_root = Path::new(&config.build.template_dir); 54 55 // If the templates directory doesn't exist, don't try to load anything. 56 if !tmpl_root.is_dir() { 57 return Ok(()); 58 } 59 60 for entry in WalkDir::new(tmpl_root) { 61 let entry = entry?; 62 let path = entry.path(); 63 64 // Get the path inside `templates` 65 let name = path.strip_prefix(tmpl_root)?.to_string_lossy().into_owned(); 66 67 if path.is_file() { 68 let tmpl_str = fs::read_to_string(path)?; 69 70 self.env.add_template_owned(name.clone(), tmpl_str)?; 71 72 println!("Loaded template {name}"); 73 } 74 } 75 76 self.env 77 .add_global("site", Value::from_serialize(&config.site)); 78 self.env 79 .add_global("extra", Value::from_serialize(&config.extra)); 80 81 Ok(()) 82 } 83 84 /// Render a template given context and name. 85 pub fn render_template(&self, context: &TemplateContext, tmpl_name: &str) -> Result<String> { 86 let tmpl = self.env.get_template(tmpl_name)?; 87 let render_str = tmpl.render(context)?; 88 Ok(render_str) 89 } 90}