Skip to content

Commit

Permalink
Extracted Container base class. Looking for internal template definit…
Browse files Browse the repository at this point in the history
…ions uses a Container stack.
  • Loading branch information
jdiamond committed Oct 28, 2010
1 parent 3899031 commit e88302c
Show file tree
Hide file tree
Showing 11 changed files with 158 additions and 165 deletions.
60 changes: 60 additions & 0 deletions Nustache.Core/Container.cs
@@ -0,0 +1,60 @@
using System.Collections.Generic;

namespace Nustache.Core
{
public class Container : Part
{
private readonly string _name;
private readonly List<Part> _children = new List<Part>();
private readonly Dictionary<string, TemplateDefinition> _templateDefinitions =
new Dictionary<string, TemplateDefinition>();

public Container(string name)
{
_name = name;
}

public string Name
{
get { return _name; }
}

public IEnumerable<Part> Children { get { return _children; } }

public void Load(IEnumerable<Part> parts)
{
foreach (var part in parts)
{
Add(part);
}
}

public void Add(Part child)
{
if (child is TemplateDefinition)
{
var templateDefinition = (TemplateDefinition)child;
_templateDefinitions.Add(templateDefinition.Name, templateDefinition);
}
else
{
_children.Add(child);
}
}

public TemplateDefinition GetTemplateDefinition(string name)
{
TemplateDefinition templateDefinition;
_templateDefinitions.TryGetValue(name, out templateDefinition);
return templateDefinition;
}

public override void Render(RenderContext context)
{
foreach (var child in _children)
{
child.Render(context);
}
}
}
}
1 change: 1 addition & 0 deletions Nustache.Core/Nustache.Core.csproj
Expand Up @@ -45,6 +45,7 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Container.cs" />
<Compile Include="TemplateDefinition.cs" />
<Compile Include="Render.cs" />
<Compile Include="RenderContext.cs" />
Expand Down
28 changes: 14 additions & 14 deletions Nustache.Core/Parser.cs
Expand Up @@ -6,57 +6,57 @@ public class Parser
{
public IEnumerable<Part> Parse(IEnumerable<Part> parts)
{
var sectionStack = new Stack<StartSection>();
StartSection startSection = null;
var containerStack = new Stack<Container>();
Container container = null;

foreach (var part in parts)
{
if (startSection != null)
if (container != null)
{
startSection.Add(part);
container.Add(part);
}
else
{
if (!(part is StartSection))
if (!(part is Container))
{
yield return part;
}
}

if (part is StartSection)
if (part is Container)
{
sectionStack.Push(startSection);
startSection = (StartSection)part;
containerStack.Push(container);
container = (Container)part;
}
else if (part is EndSection)
{
var endSection = (EndSection)part;

if (startSection == null)
if (container == null)
{
throw new NustacheException(
string.Format(
"End section {0} does not match any start section!",
endSection.Name));
}

if (endSection.Name != startSection.Name)
if (endSection.Name != container.Name)
{
throw new NustacheException(
string.Format(
"End section {0} does not match start section {1}!",
endSection.Name,
startSection.Name));
container.Name));
}

var lastStartSection = sectionStack.Pop();
var lastStartSection = containerStack.Pop();

if (lastStartSection == null)
{
yield return startSection;
yield return container;
}

startSection = lastStartSection;
container = lastStartSection;
}
}
}
Expand Down
71 changes: 37 additions & 34 deletions Nustache.Core/RenderContext.cs
Expand Up @@ -8,26 +8,26 @@ namespace Nustache.Core
public class RenderContext
{
private const int IncludeLimit = 1024;
private readonly Stack<Container> _containerStack = new Stack<Container>();
private readonly Stack<object> _dataStack = new Stack<object>();
private readonly Stack<Template> _templateStack = new Stack<Template>();
private object _data;
private readonly TextWriter _writer;
private readonly Func<string, Template> _templateLocator;
private int _includeLevel;

public RenderContext(object data, TextWriter writer, Func<string, Template> templateLocator)
public RenderContext(Template template, object data, TextWriter writer, Func<string, Template> templateLocator)
{
_data = data;
_containerStack.Push(template);
_dataStack.Push(data);
_writer = writer;
_templateLocator = templateLocator;
_includeLevel = 0;
}

public object GetValue(string name)
{
if (name == ".") return _data;
if (name == ".") return _dataStack.Peek();

var value = GetValue(name, _data);
var value = GetValue(name, _dataStack.Peek());

if (value != null)
{
Expand Down Expand Up @@ -88,27 +88,6 @@ public IEnumerable<object> GetValues(string name)
}
}

public void PushData(object data)
{
_dataStack.Push(_data);
_data = data;
}

public void PopData()
{
_data = _dataStack.Pop();
}

public void PushTemplate(Template template)
{
_templateStack.Push(template);
}

public void PopTemplate()
{
_templateStack.Pop();
}

public void Write(string text)
{
_writer.Write(text);
Expand All @@ -124,21 +103,45 @@ public void Include(string templateName)

_includeLevel++;

var currentTemplate = _templateStack.Peek();
TemplateDefinition templateDefinition = GetTemplateDefinition(templateName);

var childTemplate = currentTemplate.GetTemplate(templateName);

if (childTemplate != null)
if (templateDefinition != null)
{
childTemplate.Render(this);
templateDefinition.Render(this);
}
else if (_templateLocator != null)
{
var externalTemplate = _templateLocator(templateName);
externalTemplate.Render(this);
var template = _templateLocator(templateName);
template.Render(this);
}

_includeLevel--;
}

private TemplateDefinition GetTemplateDefinition(string name)
{
foreach (var container in _containerStack)
{
var templateDefinition = container.GetTemplateDefinition(name);

if (templateDefinition != null)
{
return templateDefinition;
}
}

return null;
}

public void Push(Container section, object data)
{
_containerStack.Push(section);
_dataStack.Push(data);
}

public void Pop()
{
_containerStack.Pop();
}
}
}
57 changes: 10 additions & 47 deletions Nustache.Core/StartSection.cs
@@ -1,59 +1,22 @@
using System.Collections.Generic;

namespace Nustache.Core
{
public class StartSection : Part
public class StartSection : Container
{
private readonly string _name;
private readonly List<Part> _children;
private readonly Dictionary<string, TemplateDefinition> _templateDefinitions =
new Dictionary<string, TemplateDefinition>();

public StartSection(string name, params Part[] children)
: base(name)
{
_name = name;
_children = new List<Part>(children);
}

public string Name
{
get { return _name; }
}

public IEnumerable<Part> Children { get { return _children; } }

public void Add(Part child)
{
if (child is TemplateDefinition)
{
var templateDefinition = (TemplateDefinition)child;
_templateDefinitions.Add(templateDefinition.Name, templateDefinition);
}
else
{
_children.Add(child);
}
}

public TemplateDefinition GetTemplateDefinition(string name)
{
TemplateDefinition templateDefinition;
_templateDefinitions.TryGetValue(name, out templateDefinition);
return templateDefinition;
Load(children);
}

public override void Render(RenderContext context)
{
foreach (var value in context.GetValues(_name))
foreach (var value in context.GetValues(Name))
{
context.PushData(value);
context.Push(this, value);

foreach (var child in _children)
{
child.Render(context);
}
base.Render(context);

context.PopData();
context.Pop();
}
}

Expand All @@ -63,7 +26,7 @@ public bool Equals(StartSection other)
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
return Equals(other._name, _name);
return Equals(other.Name, Name);
}

public override bool Equals(object obj)
Expand All @@ -76,12 +39,12 @@ public override bool Equals(object obj)

public override int GetHashCode()
{
return (_name != null ? _name.GetHashCode() : 0);
return (Name != null ? Name.GetHashCode() : 0);
}

public override string ToString()
{
return string.Format("StartSection(\"{0}\")", _name);
return string.Format("StartSection(\"{0}\")", Name);
}

#endregion
Expand Down

0 comments on commit e88302c

Please sign in to comment.