diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 58e38e3..30184b2 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -8,6 +8,7 @@ pub use parser::DustTag; pub use parser::Filter; pub use parser::KVPair; pub use parser::OwnedLiteral; +pub use parser::PartialNameElement; pub use parser::RValue; pub use parser::Special; pub use parser::Template; diff --git a/src/parser/parser.rs b/src/parser/parser.rs index 56df718..a2f6290 100644 --- a/src/parser/parser.rs +++ b/src/parser/parser.rs @@ -193,6 +193,24 @@ impl From> for PartialNameElement { } } +impl<'a> From<&'a PartialNameElement> for TemplateElement<'a> { + fn from(original: &'a PartialNameElement) -> Self { + match original { + PartialNameElement::PNSpan { contents } => { + TemplateElement::TESpan(Span { contents: contents }) + } + PartialNameElement::PNReference { path, filters } => { + TemplateElement::TETag(DustTag::DTReference(Reference { + path: Path { + keys: path.into_iter().map(|s| s.as_str()).collect(), + }, + filters: filters.into_iter().map(|f| f.clone()).collect(), + })) + } + } + } +} + /// Any element significant to dust that isn't plain text /// /// These elements are always wrapped in curly braces diff --git a/src/renderer/renderer.rs b/src/renderer/renderer.rs index bf0b083..866c6d5 100644 --- a/src/renderer/renderer.rs +++ b/src/renderer/renderer.rs @@ -2,6 +2,7 @@ use crate::parser::template; use crate::parser::Body; use crate::parser::DustTag; use crate::parser::KVPair; +use crate::parser::PartialNameElement; use crate::parser::RValue; use crate::parser::Special; use crate::parser::Template; @@ -108,6 +109,23 @@ impl<'a> DustRenderer<'a> { Ok(output) } + fn render_partial_name( + &'a self, + body: &'a Vec, + breadcrumbs: &Vec<&'a dyn ContextElement>, + blocks: &'a InlinePartialTreeElement<'a>, + ) -> Result { + let converted_to_template_elements: Vec> = + body.into_iter().map(|e| e.into()).collect(); + self.render_body( + &Body { + elements: converted_to_template_elements, + }, + breadcrumbs, + blocks, + ) + } + fn render_tag( &'a self, tag: &'a DustTag, @@ -199,6 +217,21 @@ impl<'a> DustRenderer<'a> { return Ok(rendered_content); } } + DustTag::DTNewPartial(partial) => { + let partial_name = self.render_partial_name(&partial.name, breadcrumbs, blocks)?; + if partial.params.is_empty() { + let rendered_content = + self.render_template(&partial_name, breadcrumbs, Some(blocks))?; + return Ok(rendered_content); + } else { + let injected_context = ParametersContext::new(breadcrumbs, &partial.params); + let mut new_breadcrumbs = breadcrumbs.clone(); + new_breadcrumbs.insert(new_breadcrumbs.len() - 1, &injected_context); + let rendered_content = + self.render_template(&partial_name, &new_breadcrumbs, Some(blocks))?; + return Ok(rendered_content); + } + } DustTag::DTInlinePartial(_named_block) => { // Inline partials are blank during rendering (they get injected into blocks) return Ok("".to_owned());