diff --git a/js/test_cases/sections/main.dust b/js/test_cases/sections/main.dust
index 7394d2b..8f5d538 100644
--- a/js/test_cases/sections/main.dust
+++ b/js/test_cases/sections/main.dust
@@ -1,5 +1,5 @@
{#things}
Thing: {.}
{:else}
-No things
+No things {.}
{/things}
diff --git a/src/parser/parser.rs b/src/parser/parser.rs
index 25fc802..480cd68 100644
--- a/src/parser/parser.rs
+++ b/src/parser/parser.rs
@@ -90,9 +90,9 @@ pub struct Span<'a> {
#[derive(Clone, Debug, PartialEq)]
pub struct Container<'a> {
- path: Path<'a>,
- contents: Option
>,
- else_contents: Option>,
+ pub path: Path<'a>,
+ pub contents: Option>,
+ pub else_contents: Option>,
}
#[derive(Clone, Debug, PartialEq)]
diff --git a/src/renderer/context_element.rs b/src/renderer/context_element.rs
index 6b8f7e2..14f1aae 100644
--- a/src/renderer/context_element.rs
+++ b/src/renderer/context_element.rs
@@ -22,7 +22,5 @@ pub trait Loopable {
/// once with the context being the element at that path. Finally,
/// if its an array-like value then it will render n-times, once
/// for each element of the array.
- ///
- /// TODO: Should this return an iterator instead of a vec?
fn get_loop_elements(&self) -> Result, RenderError>;
}
diff --git a/src/renderer/renderer.rs b/src/renderer/renderer.rs
index 4af3d3c..b98e77c 100644
--- a/src/renderer/renderer.rs
+++ b/src/renderer/renderer.rs
@@ -91,6 +91,42 @@ impl<'a> DustRenderer<'a> {
return val?.render(&reference.filters);
}
}
+ DustTag::DTSection(container) => {
+ let val = walk_path(context, &container.path.keys);
+ if let Err(RenderError::WontWalk { .. }) = val {
+ // If reference does not exist in the context, it becomes an empty string
+ return Ok("".to_owned());
+ } else {
+ let loop_elements: Vec<&dyn ContextElement> = val?.get_loop_elements()?;
+ if loop_elements.is_empty() {
+ // Oddly enough if the value is falsey (like
+ // an empty array or null), Dust uses the
+ // original context before walking the path as
+ // the context for rendering the else block
+ //
+ // TODO: do filters apply? I don't think so
+ // but I should test
+ return match &container.else_contents {
+ Some(body) => self.render_body(&body, context),
+ None => Ok("".to_owned()),
+ };
+ } else {
+ match container.contents {
+ None => Ok("".to_owned()),
+ Some(body) => {
+ let rendered_results: Result, RenderError> =
+ loop_elements
+ .into_iter()
+ .map(|array_elem| self.render_body(&body, array_elem))
+ .collect();
+ let rendered_slice: &[String] = &rendered_results?;
+ return Ok(rendered_slice.join(""));
+ }
+ };
+ return Ok("".to_owned());
+ }
+ }
+ }
_ => (), // TODO: Implement the rest
}
Ok("".to_owned())