/// <summary> /// Renders the enumerable content. /// </summary> /// <param name="enumerable">The enumerable instance.</param> /// <param name="context">The render context.</param> /// <param name="children">The child block to render for each item.</param> /// <param name="alternateChildren">Alternative content to render when no content is available.</param> protected internal void RenderEnumerable(IEnumerable enumerable, RenderContext context, IEnumerable <SyntaxTreeNode> children, IEnumerable <SyntaxTreeNode> alternateChildren = null) { int index = 0; bool hasItems = false; var dict = enumerable as IDictionary; if (dict != null) { int maxIndex = dict.Count - 1; foreach (var key in dict.Keys) { hasItems = true; var item = dict[key]; using (var scope = context.BeginScope(item)) { scope.ScopeContext.SetVariable("first", (index == 0)); scope.ScopeContext.SetVariable("last", (index == maxIndex)); scope.ScopeContext.SetVariable("index", index); scope.ScopeContext.SetVariable("key", key); foreach (var child in children) { RenderChild(child, scope.ScopeContext); } } index++; } } else { var array = (enumerable is Array) ? (object[])enumerable : (((IEnumerable)enumerable).Cast <object>().ToArray()); int maxIndex = array.Length - 1; for (index = 0; index <= maxIndex; index++) { hasItems = true; var item = array[index]; using (var scope = context.BeginScope(item)) { scope.ScopeContext.SetVariable("first", (index == 0)); scope.ScopeContext.SetVariable("last", (index == maxIndex)); scope.ScopeContext.SetVariable("index", index); foreach (var child in children) { RenderChild(child, scope.ScopeContext); } } } } if (!hasItems && alternateChildren != null && alternateChildren.Any()) { RenderChildren(alternateChildren, context); } }
/// <summary> /// Renders the content of a block helper. /// </summary> /// <param name="children">The children of the helper block.</param> /// <param name="context">The render context.</param> /// <param name="data">The new data model.</param> /// <returns>The string content of the result.</returns> private string RenderHelperChildren(IEnumerable<SyntaxTreeNode> children, RenderContext context, object data) { RenderContext targetContext = context; RenderContextScope scope = null; if (data != null) { scope = context.BeginScope(data); targetContext = scope.ScopeContext; } using (var writer = new StringWriter()) { var renderer = new RenderingParserVisitor(writer, targetContext, context.ModelMetadataProvider); foreach (var node in children) { node.Accept(renderer); } if (scope != null) { scope.Dispose(); } return writer.GetStringBuilder().ToString(); } }
/// <inheritdoc /> protected override void Render(Block block, object[] arguments, Dictionary<string, object> maps, RenderContext context, TextWriter writer) { if (context.Service == null) { // No service, can't do anything. return; } var span = block.Children.FirstOrDefault(c => !c.IsBlock && ((Span)c).Kind == SpanKind.Expression) as Span; if (span == null) { // Malformed tag? return; } string name = span.Content; object model = arguments.FirstOrDefault(); if (model != null) { using (var scope = context.BeginScope(model)) { Write(scope.ScopeContext, writer, new SafeString(context.Service.RunPartial(name, scope.ScopeContext))); } } else { Write(context, writer, new SafeString(context.Service.RunPartial(name, context))); } }
/// <summary> /// Renders the content of a block helper. /// </summary> /// <param name="children">The children of the helper block.</param> /// <param name="context">The render context.</param> /// <param name="data">The new data model.</param> /// <returns>The string content of the result.</returns> private string RenderHelperChildren(IEnumerable <SyntaxTreeNode> children, RenderContext context, object data) { RenderContext targetContext = context; RenderContextScope scope = null; if (data != null) { scope = context.BeginScope(data); targetContext = scope.ScopeContext; } using (var writer = new StringWriter()) { var renderer = new RenderingParserVisitor(writer, targetContext, context.ModelMetadataProvider); foreach (var node in children) { node.Accept(renderer); } if (scope != null) { scope.Dispose(); } return(writer.GetStringBuilder().ToString()); } }
/// <inheritdoc /> protected override void Render(Block block, object[] arguments, Dictionary <string, object> maps, RenderContext context, TextWriter writer) { var children = block.Children.ToList(); children.RemoveAt(0); children.RemoveAt(children.Count - 1); var elseChildren = new List <SyntaxTreeNode>(); // Determine if there is an alternate {{else}} block which denotes content to display when predicate is false. var elseNode = children.Find(n => n.IsBlock && (((Block)n).Name == "else" || ((Block)n).Name == "^")); if (elseNode != null) { int elseIndex = children.IndexOf(elseNode); elseChildren = children.Skip(elseIndex + 1).ToList(); children = children.Take(elseIndex).ToList(); } if (IsTruthy(arguments[0])) { // Create a scope around the arguments. using (var scope = context.BeginScope(arguments[0])) { RenderChildren(children, scope.ScopeContext); } } else if (elseChildren.Count > 0) { RenderChildren(elseChildren, context); } }
/// <inheritdoc /> protected override void Render(Block block, object[] arguments, Dictionary <string, object> maps, RenderContext context, TextWriter writer) { if (context.Service == null) { // No service, can't do anything. return; } var span = block.Children.FirstOrDefault(c => !c.IsBlock && ((Span)c).Kind == SpanKind.Expression) as Span; if (span == null) { // Malformed tag? return; } string name = span.Content; object model = arguments.FirstOrDefault(); if (model != null) { using (var scope = context.BeginScope(model)) { Write(scope.ScopeContext, writer, new SafeString(context.Service.RunPartial(name, scope.ScopeContext))); } } else { Write(context, writer, new SafeString(context.Service.RunPartial(name, context))); } }
/// <inheritdoc /> protected override void Render(Block block, object[] arguments, Dictionary<string, object> maps, RenderContext context, TextWriter writer) { var children = block.Children.ToList(); children.RemoveAt(0); children.RemoveAt(children.Count - 1); var elseChildren = new List<SyntaxTreeNode>(); // Determine if there is an alternate {{else}} block which denotes content to display when predicate is false. var elseNode = children.Find(n => n.IsBlock && (((Block)n).Name == "else" || ((Block)n).Name == "^")); if (elseNode != null) { int elseIndex = children.IndexOf(elseNode); elseChildren = children.Skip(elseIndex + 1).ToList(); children = children.Take(elseIndex).ToList(); } if (IsTruthy(arguments[0])) { // Create a scope around the arguments. using (var scope = context.BeginScope(arguments[0])) { RenderChildren(children, scope.ScopeContext); } } else if (elseChildren.Count > 0) { RenderChildren(elseChildren, context); } }
/// <summary> /// Renders the enumerable content. /// </summary> /// <param name="enumerable">The enumerable instance.</param> /// <param name="context">The render context.</param> /// <param name="children">The child block to render for each item.</param> /// <param name="alternateChildren">Alternative content to render when no content is available.</param> protected internal void RenderEnumerable(IEnumerable enumerable, RenderContext context, IEnumerable<SyntaxTreeNode> children, IEnumerable<SyntaxTreeNode> alternateChildren = null) { int index = 0; bool hasItems = false; var dict = enumerable as IDictionary; if (dict != null) { int maxIndex = dict.Count - 1; foreach (var key in dict.Keys) { hasItems = true; var item = dict[key]; using (var scope = context.BeginScope(item)) { scope.ScopeContext.SetVariable("first", (index == 0)); scope.ScopeContext.SetVariable("last", (index == maxIndex)); scope.ScopeContext.SetVariable("index", index); scope.ScopeContext.SetVariable("key", key); foreach (var child in children) { RenderChild(child, scope.ScopeContext); } } index++; } } else { var array = (enumerable is Array) ? (object[])enumerable : (((IEnumerable)enumerable).Cast<object>().ToArray()); int maxIndex = array.Length - 1; for (index = 0; index <= maxIndex; index++) { hasItems = true; var item = array[index]; using (var scope = context.BeginScope(item)) { scope.ScopeContext.SetVariable("first", (index == 0)); scope.ScopeContext.SetVariable("last", (index == maxIndex)); scope.ScopeContext.SetVariable("index", index); foreach (var child in children) { RenderChild(child, scope.ScopeContext); } } } } if (!hasItems && alternateChildren != null && alternateChildren.Any()) { RenderChildren(alternateChildren, context); } }
/// <inheritdoc /> protected override void Render(Block block, object[] arguments, Dictionary <string, object> maps, RenderContext context, TextWriter writer) { string name = block.Name; var children = block.Children.ToList(); // Get the TagElement block. var tagElement = (Block)children[0]; // Determine if the block prefix symbol (either # or ^) is a caret. bool isNegatedSection = tagElement.Children.Cast <Span>().Where(s => s.Kind == SpanKind.MetaCode).ToArray()[1].Content == "^"; children.RemoveAt(0); children.RemoveAt(children.Count - 1); if (string.IsNullOrEmpty(name)) { // Nothing we can do. return; } object value = context.ResolveValue(name, false); if (value == null && !isNegatedSection) { // No value, nothing we can do :-( return; } if ((value is IEnumerable) && !(value is string) && !isNegatedSection) { RenderEnumerable((IEnumerable)value, context, children, null); } else { bool isTruthy = IsTruthy(value); // Treat this as a conditional block. if (isTruthy != isNegatedSection) { if (isTruthy) { // Create a scope around the value. using (var scope = context.BeginScope(value)) { RenderChildren(children, context); } } else { RenderChildren(children, context); } } } }
/// <inheritdoc /> protected override void Render(Block block, object[] arguments, Dictionary<string, object> maps, RenderContext context, TextWriter writer) { string name = block.Name; var children = block.Children.ToList(); // Get the TagElement block. var tagElement = (Block)children[0]; // Determine if the block prefix symbol (either # or ^) is a caret. bool isNegatedSection = tagElement.Children.Cast<Span>().Where(s => s.Kind == SpanKind.MetaCode).ToArray()[1].Content == "^"; children.RemoveAt(0); children.RemoveAt(children.Count - 1); if (string.IsNullOrEmpty(name)) { // Nothing we can do. return; } object value = context.ResolveValue(name, false); if (value == null && !isNegatedSection) { // No value, nothing we can do :-( return; } if ((value is IEnumerable) && !(value is string) && !isNegatedSection) { RenderEnumerable((IEnumerable)value, context, children, null); } else { bool isTruthy = IsTruthy(value); // Treat this as a conditional block. if (isTruthy != isNegatedSection) { if (isTruthy) { // Create a scope around the value. using (var scope = context.BeginScope(value)) { RenderChildren(children, context); } } else { RenderChildren(children, context); } } } }