Skip to main content

trillium_tera/
tera_handler.rs

1use std::{path::PathBuf, sync::Arc};
2use tera::{Context, Tera};
3use trillium::{Conn, Handler};
4
5/// A trillium handler for the Tera template engine
6#[derive(Clone, Debug)]
7pub struct TeraHandler(Arc<Tera>);
8
9impl From<PathBuf> for TeraHandler {
10    fn from(dir: PathBuf) -> Self {
11        dir.to_str().unwrap().into()
12    }
13}
14
15impl From<&str> for TeraHandler {
16    fn from(glob: &str) -> Self {
17        let mut tera = Tera::new();
18        tera.load_from_glob(glob).unwrap();
19        tera.into()
20    }
21}
22
23impl From<&String> for TeraHandler {
24    fn from(glob: &String) -> Self {
25        glob.as_str().into()
26    }
27}
28
29impl From<String> for TeraHandler {
30    fn from(glob: String) -> Self {
31        glob.as_str().into()
32    }
33}
34
35impl From<Tera> for TeraHandler {
36    fn from(tera: Tera) -> Self {
37        Self(Arc::new(tera))
38    }
39}
40
41impl From<&[&str]> for TeraHandler {
42    fn from(dir_parts: &[&str]) -> Self {
43        dir_parts.iter().collect::<PathBuf>().into()
44    }
45}
46
47impl TeraHandler {
48    /// Construct a new TeraHandler from either a `&str` or PathBuf that represents
49    /// a directory glob containing templates, or from a
50    /// [`tera::Tera`] instance
51    /// ```
52    /// # fn main() -> tera::TeraResult<()> {
53    /// use std::{iter::FromIterator, path::PathBuf};
54    /// use trillium_tera::TeraHandler;
55    ///
56    /// let handler = TeraHandler::new(PathBuf::from_iter([".", "examples", "**", "*.html"]));
57    ///
58    /// // or
59    ///
60    /// let handler = TeraHandler::new("examples/*.html");
61    ///
62    /// // or
63    ///
64    /// let mut tera = trillium_tera::Tera::default();
65    /// tera.add_raw_template("hello.html", "hello {{name}}")?;
66    /// let handler = TeraHandler::new(tera);
67    /// # Ok(()) }
68    /// ```
69    pub fn new(tera: impl Into<Self>) -> Self {
70        tera.into()
71    }
72
73    pub(crate) fn tera(&self) -> &Tera {
74        &self.0
75    }
76}
77
78impl Handler for TeraHandler {
79    async fn run(&self, conn: Conn) -> Conn {
80        conn.with_state(self.clone()).with_state(Context::new())
81    }
82}