1use crate::utils::{Result, TrackError};
4use minijinja::{path_loader, AutoEscape, Environment};
5use std::path::PathBuf;
6use std::sync::Arc;
7
8pub struct Templates {
10 env: Environment<'static>,
11}
12
13impl Templates {
14 #[allow(dead_code)]
16 pub fn new(template_dir: PathBuf) -> Self {
17 let mut env = Environment::new();
18 env.set_loader(path_loader(template_dir));
19 env.set_auto_escape_callback(|name| {
20 if name.ends_with(".html") {
21 AutoEscape::Html
22 } else {
23 AutoEscape::None
24 }
25 });
26
27 Self { env }
28 }
29
30 pub fn embedded() -> Self {
32 let mut env = Environment::new();
33 env.set_auto_escape_callback(|name| {
34 if name.ends_with(".html") {
35 AutoEscape::Html
36 } else {
37 AutoEscape::None
38 }
39 });
40
41 env.add_template("base.html", include_str!("../../templates/base.html"))
43 .expect("Failed to add base.html template");
44 env.add_template("index.html", include_str!("../../templates/index.html"))
45 .expect("Failed to add index.html template");
46 env.add_template(
47 "partials/todo_list.html",
48 include_str!("../../templates/partials/todo_list.html"),
49 )
50 .expect("Failed to add todo_list.html template");
51 env.add_template(
52 "partials/scrap_list.html",
53 include_str!("../../templates/partials/scrap_list.html"),
54 )
55 .expect("Failed to add scrap_list.html template");
56 env.add_template(
57 "partials/description.html",
58 include_str!("../../templates/partials/description.html"),
59 )
60 .expect("Failed to add description.html template");
61 env.add_template(
62 "partials/ticket.html",
63 include_str!("../../templates/partials/ticket.html"),
64 )
65 .expect("Failed to add ticket.html template");
66 env.add_template(
67 "partials/links.html",
68 include_str!("../../templates/partials/links.html"),
69 )
70 .expect("Failed to add links.html template");
71 env.add_template(
72 "partials/repos.html",
73 include_str!("../../templates/partials/repos.html"),
74 )
75 .expect("Failed to add repos.html template");
76 env.add_template(
77 "partials/calendar.html",
78 include_str!("../../templates/partials/calendar.html"),
79 )
80 .expect("Failed to add calendar.html template");
81
82 Self { env }
83 }
84
85 pub fn render<S: serde::Serialize>(&self, name: &str, ctx: S) -> Result<String> {
87 let tmpl = self
88 .env
89 .get_template(name)
90 .map_err(|err| TrackError::TemplateRenderFailed {
91 name: name.to_string(),
92 detail: err.to_string(),
93 })?;
94 tmpl.render(ctx)
95 .map_err(|err| TrackError::TemplateRenderFailed {
96 name: name.to_string(),
97 detail: err.to_string(),
98 })
99 }
100}
101
102pub type SharedTemplates = Arc<Templates>;