use serde::Serialize;
use super::tera_builtins;
use crate::{controller::views::ViewRenderer, Result};
pub static DEFAULT_ASSET_FOLDER: &str = "assets";
include!(concat!(
env!("OUT_DIR"),
"/generated_code/view_templates.rs"
));
#[derive(Clone, Debug)]
pub struct TeraView {
pub tera: tera::Tera,
pub default_context: tera::Context,
}
impl TeraView {
pub fn build() -> Result<Self> {
Self::from_embedded_templates()
}
pub fn from_embedded_templates() -> Result<Self> {
let mut tera = tera::Tera::default();
Self::load_templates_into_tera(&mut tera)?;
tera_builtins::filters::register_filters(&mut tera);
let ctx = tera::Context::default();
Ok(Self {
tera,
default_context: ctx,
})
}
fn load_templates_into_tera(tera: &mut tera::Tera) -> Result<()> {
let templates: indexmap::IndexMap<String, &'static str> = get_embedded_templates();
Self::log_template_info(&templates);
Self::add_templates_to_tera(tera, templates)
}
fn log_template_info(templates: &indexmap::IndexMap<String, &'static str>) {
tracing::info!("Initializing embedded templates feature");
tracing::info!("Found {} embedded templates", templates.len());
}
fn add_templates_to_tera(
tera: &mut tera::Tera,
templates: indexmap::IndexMap<String, &'static str>,
) -> Result<()> {
for (name, content) in templates {
tracing::debug!("Adding template '{}' to Tera", name);
if let Err(e) = tera.add_raw_template(&name, content) {
tracing::error!("Failed to add template '{}': {}", name, e);
return Err(e.into());
}
}
if let Err(e) = tera.build_inheritance_chains() {
tracing::error!("Failed to build template inheritance chains: {}", e);
return Err(e.into());
}
Ok(())
}
}
impl ViewRenderer for TeraView {
fn render<S: Serialize>(&self, key: &str, data: S) -> Result<String> {
let context = tera::Context::from_serialize(data)?;
match self.tera.render(key, &context) {
Ok(result) => Ok(result),
Err(e) => {
if e.to_string().contains("not found") {
tracing::warn!("Template '{}' not found", key);
let template_names: Vec<String> =
self.tera.get_template_names().map(String::from).collect();
tracing::debug!("Available templates: {:?}", template_names);
}
Err(e.into())
}
}
}
}