Skip to main content

doido_view/
renderer.rs

1use crate::{engine::TemplateEngine, response::ViewResponse};
2use doido_core::Result;
3use std::sync::Arc;
4
5pub struct Renderer {
6    engine: Arc<dyn TemplateEngine>,
7    default_layout: String,
8}
9
10impl Renderer {
11    pub fn new(engine: Arc<dyn TemplateEngine>, default_layout: impl Into<String>) -> Self {
12        Self {
13            engine,
14            default_layout: default_layout.into(),
15        }
16    }
17
18    pub fn render(&self, response: &ViewResponse) -> Result<String> {
19        let content = self.engine.render(&response.template, &response.context)?;
20
21        let layout = match &response.layout {
22            Some(l) if l.is_empty() => return Ok(content),
23            Some(l) => l.clone(),
24            None => self.default_layout.clone(),
25        };
26
27        if layout.is_empty() {
28            return Ok(content);
29        }
30
31        let mut layout_ctx = response.context.clone();
32        if let Some(obj) = layout_ctx.as_object_mut() {
33            obj.insert(
34                "content_for_layout".to_string(),
35                serde_json::Value::String(content),
36            );
37        }
38        self.engine
39            .render(&format!("layouts/{}", layout), &layout_ctx)
40    }
41}