@ -8,6 +8,8 @@ use crate::renderer::context_element::ContextElement;
use crate ::renderer ::errors ::CompileError ;
use crate ::renderer ::errors ::RenderError ;
use crate ::renderer ::errors ::WalkError ;
use crate ::renderer ::inline_partial_tree ::extract_inline_partials ;
use crate ::renderer ::inline_partial_tree ::InlinePartialTreeElement ;
use crate ::renderer ::parameters_context ::ParametersContext ;
use crate ::renderer ::walking ::walk_path ;
use std ::collections ::HashMap ;
@ -52,6 +54,15 @@ impl<'a> DustRenderer<'a> {
& ' a self ,
name : & str ,
breadcrumbs : & Vec < & ' a dyn ContextElement > ,
) -> Result < String , RenderError > {
self . render_template ( name , breadcrumbs , None )
}
fn render_template (
& ' a self ,
name : & str ,
breadcrumbs : & Vec < & ' a dyn ContextElement > ,
blocks : Option < & ' a InlinePartialTreeElement < ' a > > ,
) -> Result < String , RenderError > {
let main_template = match self . templates . get ( name ) {
Some ( tmpl ) = > tmpl ,
@ -59,13 +70,16 @@ impl<'a> DustRenderer<'a> {
return Err ( RenderError ::TemplateNotFound ( name . to_owned ( ) ) ) ;
}
} ;
self . render_body ( & main_template . contents , breadcrumbs )
let extracted_inline_partials = extract_inline_partials ( main_template ) ;
let new_blocks = InlinePartialTreeElement ::new ( blocks , extracted_inline_partials ) ;
self . render_body ( & main_template . contents , breadcrumbs , & new_blocks )
}
fn render_body (
& ' a self ,
body : & ' a Body ,
breadcrumbs : & Vec < & ' a dyn ContextElement > ,
blocks : & ' a InlinePartialTreeElement < ' a > ,
) -> Result < String , RenderError > {
let mut output = String ::new ( ) ;
for elem in & body . elements {
@ -73,7 +87,7 @@ impl<'a> DustRenderer<'a> {
TemplateElement ::TEIgnoredWhitespace ( _ ) = > { }
TemplateElement ::TESpan ( span ) = > output . push_str ( span . contents ) ,
TemplateElement ::TETag ( dt ) = > {
output . push_str ( & self . render_tag ( dt , breadcrumbs )? ) ;
output . push_str ( & self . render_tag ( dt , breadcrumbs , blocks )? ) ;
}
}
}
@ -84,6 +98,7 @@ impl<'a> DustRenderer<'a> {
& ' a self ,
tag : & ' a DustTag ,
breadcrumbs : & Vec < & ' a dyn ContextElement > ,
blocks : & ' a InlinePartialTreeElement < ' a > ,
) -> Result < String , RenderError > {
match tag {
DustTag ::DTComment ( _comment ) = > ( ) ,
@ -120,7 +135,7 @@ impl<'a> DustRenderer<'a> {
// original context before walking the path as
// the context for rendering the else block
return match & container . else_contents {
Some ( body ) = > self . render_body ( & body , breadcrumbs ),
Some ( body ) = > self . render_body ( & body , breadcrumbs , blocks ),
None = > Ok ( "" . to_owned ( ) ) ,
} ;
} else {
@ -132,7 +147,7 @@ impl<'a> DustRenderer<'a> {
. map ( | array_elem | {
let mut new_breadcumbs = breadcrumbs . clone ( ) ;
new_breadcumbs . push ( array_elem ) ;
self . render_body ( & body , & new_breadcumbs )
self . render_body ( & body , & new_breadcumbs , blocks )
} )
. collect ( ) ;
let rendered_slice : & [ String ] = & rendered_results ? ;
@ -146,13 +161,13 @@ impl<'a> DustRenderer<'a> {
let loop_elements : Vec < & dyn ContextElement > = self . get_loop_elements ( val ) ;
if loop_elements . is_empty ( ) {
return match & container . else_contents {
Some ( body ) = > self . render_body ( & body , breadcrumbs ),
Some ( body ) = > self . render_body ( & body , breadcrumbs , blocks ),
None = > Ok ( "" . to_owned ( ) ) ,
} ;
} else {
return match & container . contents {
None = > Ok ( "" . to_owned ( ) ) ,
Some ( body ) = > self . render_body ( & body , breadcrumbs ),
Some ( body ) = > self . render_body ( & body , breadcrumbs , blocks ),
} ;
}
}
@ -161,28 +176,52 @@ impl<'a> DustRenderer<'a> {
let loop_elements : Vec < & dyn ContextElement > = self . get_loop_elements ( val ) ;
if ! loop_elements . is_empty ( ) {
return match & container . else_contents {
Some ( body ) = > self . render_body ( & body , breadcrumbs ),
Some ( body ) = > self . render_body ( & body , breadcrumbs , blocks ),
None = > Ok ( "" . to_owned ( ) ) ,
} ;
} else {
return match & container . contents {
None = > Ok ( "" . to_owned ( ) ) ,
Some ( body ) = > self . render_body ( & body , breadcrumbs ),
Some ( body ) = > self . render_body ( & body , breadcrumbs , blocks ),
} ;
}
}
DustTag ::DTPartial ( partial ) = > {
if partial . params . is_empty ( ) {
let rendered_content = self . render ( & partial . name , breadcrumbs ) ? ;
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 ( & partial . name , & new_breadcrumbs ) ? ;
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 ( ) ) ;
}
DustTag ::DTBlock ( named_block ) = > {
match blocks . get_block ( named_block . name ) {
None = > match & named_block . contents {
None = > return Ok ( "" . to_owned ( ) ) ,
Some ( body ) = > {
let rendered_content = self . render_body ( body , breadcrumbs , blocks ) ? ;
return Ok ( rendered_content ) ;
}
} ,
Some ( interior ) = > match interior {
None = > return Ok ( "" . to_owned ( ) ) ,
Some ( body ) = > {
let rendered_content = self . render_body ( body , breadcrumbs , blocks ) ? ;
return Ok ( rendered_content ) ;
}
} ,
} ;
}
_ = > ( ) , // TODO: Implement the rest
}
Ok ( "" . to_owned ( ) )