coil_runtime/render/
mod.rs1use super::*;
2use coil_i18n::I18nError;
3use coil_seo::SeoError;
4use coil_template::{DocumentRenderRequest, TemplateKind, TemplateModelError};
5use thiserror::Error;
6
7mod model;
8mod seo;
9mod templates;
10
11#[derive(Debug, Error)]
12pub enum RuntimeRenderError {
13 #[error(transparent)]
14 Template(#[from] TemplateModelError),
15 #[error(transparent)]
16 I18n(#[from] I18nError),
17 #[error(transparent)]
18 Seo(#[from] SeoError),
19 #[error(transparent)]
20 RouteUrl(#[from] RouteUrlError),
21}
22
23impl RuntimePlan {
24 pub fn render_page_response(
25 &self,
26 execution: &RequestExecution,
27 page: &PageResponse,
28 extra_metadata: Option<&TypedMetadata>,
29 ) -> Result<String, RuntimeRenderError> {
30 let selector = templates::template_selector(&page.template)?;
31 let namespaces = self.template_namespaces_for_execution(execution);
32 let model = self.render_model_for_execution(execution, &page.template, None)?;
33
34 let html = match self.template.runtime.render_document(
35 &namespaces,
36 DocumentRenderRequest::new(selector.clone(), model.clone()),
37 ) {
38 Ok(output) => output.html,
39 Err(TemplateModelError::TemplateNotFound { .. })
40 | Err(TemplateModelError::TemplateKindMismatch {
41 actual: TemplateKind::Fragment,
42 ..
43 }) => {
44 let content =
45 self.render_fragment_content(execution, &namespaces, &selector, model, None)?;
46 self.render_document_shell(execution, &page.template, content)?
47 }
48 Err(error) => return Err(error.into()),
49 };
50
51 self.decorate_page_document(execution, &page.template, html, extra_metadata)
52 }
53
54 pub fn render_fragment_response(
55 &self,
56 execution: &RequestExecution,
57 fragment: &FragmentResponse,
58 ) -> Result<String, RuntimeRenderError> {
59 let selector = templates::template_selector(&fragment.template)?;
60 let namespaces = self.template_namespaces_for_execution(execution);
61 let model = self.render_model_for_execution(
62 execution,
63 &fragment.template,
64 Some(fragment.fragment_id.as_str()),
65 )?;
66
67 self.render_fragment_content(
68 execution,
69 &namespaces,
70 &selector,
71 model,
72 Some(fragment.fragment_id.as_str()),
73 )
74 .map_err(Into::into)
75 }
76}