Added DynamicNodeWalker and implementation on DynamicNode and DynamicNodeList
DynamicNodeWalker is our secret weapon in the fight against the Rebel XSLT Alliance Navigate nodes by calling Up(), Down(), Next() and Previous() on them Next(1) will jump two items along within the current list, whereas Next() will walk by one within the list Previous(1) will move two items backwards within the current list Up() is a special wrapper around .Parent which has an overload .Up(int) to replace @Model.Parent.Parent.Parent... [.Up(2)] Down() will take you to the first Child item and is equivilent to .Children.First(), use .Down(1) to replace .Children.First().Children If one of the NodeWalker functions fails to find a node at the requested position, it will return null
This commit is contained in:
@@ -19,8 +19,9 @@ namespace umbraco.MacroEngines
|
||||
{
|
||||
public class DynamicNode : DynamicObject
|
||||
{
|
||||
internal DynamicNodeList ownerList;
|
||||
|
||||
private readonly INode n;
|
||||
internal readonly INode n;
|
||||
public DynamicNode(INode n)
|
||||
{
|
||||
if (n != null)
|
||||
@@ -53,6 +54,39 @@ namespace umbraco.MacroEngines
|
||||
//Empty constructor for a special case with Generic Methods
|
||||
}
|
||||
|
||||
public DynamicNode Up()
|
||||
{
|
||||
return DynamicNodeWalker.Up(this);
|
||||
}
|
||||
public DynamicNode Up(int number)
|
||||
{
|
||||
return DynamicNodeWalker.Up(this, number);
|
||||
}
|
||||
public DynamicNode Down()
|
||||
{
|
||||
return DynamicNodeWalker.Down(this);
|
||||
}
|
||||
public DynamicNode Down(int number)
|
||||
{
|
||||
return DynamicNodeWalker.Down(this, number);
|
||||
}
|
||||
public DynamicNode Next()
|
||||
{
|
||||
return DynamicNodeWalker.Next(this);
|
||||
}
|
||||
public DynamicNode Next(int number)
|
||||
{
|
||||
return DynamicNodeWalker.Next(this, number);
|
||||
}
|
||||
public DynamicNode Previous()
|
||||
{
|
||||
return DynamicNodeWalker.Previous(this);
|
||||
}
|
||||
public DynamicNode Previous(int number)
|
||||
{
|
||||
return DynamicNodeWalker.Previous(this, number);
|
||||
}
|
||||
|
||||
public DynamicNodeList GetChildrenAsList
|
||||
{
|
||||
get
|
||||
|
||||
@@ -22,11 +22,15 @@ namespace umbraco.MacroEngines
|
||||
}
|
||||
public DynamicNodeList(IEnumerable<DynamicNode> items)
|
||||
{
|
||||
Items = items.ToList();
|
||||
List<DynamicNode> list = items.ToList();
|
||||
list.ForEach(node => node.ownerList = this);
|
||||
Items = list;
|
||||
}
|
||||
public DynamicNodeList(IEnumerable<INode> items)
|
||||
{
|
||||
Items = items.Select(x => new DynamicNode(x)).ToList();
|
||||
List<DynamicNode> list = items.Select(x => new DynamicNode(x)).ToList();
|
||||
list.ForEach(node => node.ownerList = this);
|
||||
Items = list;
|
||||
}
|
||||
|
||||
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using umbraco.interfaces;
|
||||
|
||||
namespace umbraco.MacroEngines
|
||||
{
|
||||
public static class DynamicNodeWalker
|
||||
{
|
||||
public static DynamicNode Up(this DynamicNode context)
|
||||
{
|
||||
return context.Up(0);
|
||||
}
|
||||
public static DynamicNode Up(this DynamicNode context, int number)
|
||||
{
|
||||
if (number == 0)
|
||||
{
|
||||
return context.Parent;
|
||||
}
|
||||
else
|
||||
{
|
||||
while ((context = context.Parent) != null && --number >= 0) ;
|
||||
return context;
|
||||
}
|
||||
}
|
||||
public static DynamicNode Down(this DynamicNode context)
|
||||
{
|
||||
return context.Down(0);
|
||||
}
|
||||
public static DynamicNode Down(this DynamicNode context, int number)
|
||||
{
|
||||
DynamicNodeList children = new DynamicNodeList(context.ChildrenAsList);
|
||||
if (number == 0)
|
||||
{
|
||||
return children.Items.First();
|
||||
}
|
||||
else
|
||||
{
|
||||
DynamicNode working = context;
|
||||
while (number-- >= 0)
|
||||
{
|
||||
working = children.Items.First();
|
||||
children = new DynamicNodeList(working.ChildrenAsList);
|
||||
}
|
||||
return working;
|
||||
}
|
||||
}
|
||||
public static DynamicNode Next(this DynamicNode context)
|
||||
{
|
||||
return context.Next(0);
|
||||
}
|
||||
public static DynamicNode Next(this DynamicNode context, int number)
|
||||
{
|
||||
if (context.ownerList != null)
|
||||
{
|
||||
List<DynamicNode> container = context.ownerList.Items.ToList();
|
||||
int currentIndex = container.IndexOf(context);
|
||||
if (currentIndex != -1)
|
||||
{
|
||||
return container.ElementAtOrDefault(currentIndex + (number + 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new IndexOutOfRangeException(string.Format("Node {0} belongs to a DynamicNodeList but could not retrieve the index for it's position in the list", context.Id));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ArgumentNullException(string.Format("Node {0} has been orphaned and doesn't belong to a DynamicNodeList", context.Id));
|
||||
}
|
||||
}
|
||||
public static DynamicNode Previous(this DynamicNode context)
|
||||
{
|
||||
return context.Previous(0);
|
||||
}
|
||||
public static DynamicNode Previous(this DynamicNode context, int number)
|
||||
{
|
||||
if (context.ownerList != null)
|
||||
{
|
||||
List<DynamicNode> container = context.ownerList.Items.ToList();
|
||||
int currentIndex = container.IndexOf(context);
|
||||
if (currentIndex != -1)
|
||||
{
|
||||
return container.ElementAtOrDefault(currentIndex + (number - 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new IndexOutOfRangeException(string.Format("Node {0} belongs to a DynamicNodeList but could not retrieve the index for it's position in the list", context.Id));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ArgumentNullException(string.Format("Node {0} has been orphaned and doesn't belong to a DynamicNodeList", context.Id));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -63,29 +63,30 @@
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="BaseContext.cs" />
|
||||
<Compile Include="DynamicNodeList.cs" />
|
||||
<Compile Include="DynamicQueryable.cs" />
|
||||
<Compile Include="DynamicXml.cs" />
|
||||
<Compile Include="ExtensionMethods.cs" />
|
||||
<Compile Include="RazorUmbracoFactory.cs" />
|
||||
<Compile Include="RazorUmbracoHost.cs" />
|
||||
<Compile Include="UmbracoCultureDictionary.cs" />
|
||||
<Compile Include="RazorCore\BaseContext.cs" />
|
||||
<Compile Include="RazorDynamicNode\DynamicNodeList.cs" />
|
||||
<Compile Include="RazorDynamicNode\DynamicNodeWalker.cs" />
|
||||
<Compile Include="RazorDynamicNode\DynamicQueryable.cs" />
|
||||
<Compile Include="RazorDynamicNode\DynamicXml.cs" />
|
||||
<Compile Include="RazorDynamicNode\ExtensionMethods.cs" />
|
||||
<Compile Include="RazorCore\RazorUmbracoFactory.cs" />
|
||||
<Compile Include="RazorCore\RazorUmbracoHost.cs" />
|
||||
<Compile Include="RazorCore\UmbracoCultureDictionary.cs" />
|
||||
<Compile Include="DLRScriptingEngine.cs" />
|
||||
<Compile Include="DynamicDictionary.cs" />
|
||||
<Compile Include="DynamicNodeListExtensionMethods.cs" />
|
||||
<Compile Include="DynamicNodeListOrdering.cs" />
|
||||
<Compile Include="DynamicQueryableBinders.cs" />
|
||||
<Compile Include="DynamicMedia.cs" />
|
||||
<Compile Include="DynamicNode.cs" />
|
||||
<Compile Include="DynamicNodeContext.cs" />
|
||||
<Compile Include="ICultureDictionary.cs" />
|
||||
<Compile Include="IMacroContext.cs" />
|
||||
<Compile Include="IParameterDictionary.cs" />
|
||||
<Compile Include="UmbracoParameterDictionary.cs" />
|
||||
<Compile Include="RazorDynamicNode\DynamicDictionary.cs" />
|
||||
<Compile Include="RazorDynamicNode\DynamicNodeListExtensionMethods.cs" />
|
||||
<Compile Include="RazorDynamicNode\DynamicNodeListOrdering.cs" />
|
||||
<Compile Include="RazorDynamicNode\DynamicQueryableBinders.cs" />
|
||||
<Compile Include="RazorDynamicNode\DynamicMedia.cs" />
|
||||
<Compile Include="RazorDynamicNode\DynamicNode.cs" />
|
||||
<Compile Include="RazorDynamicNode\DynamicNodeContext.cs" />
|
||||
<Compile Include="RazorCore\ICultureDictionary.cs" />
|
||||
<Compile Include="RazorCore\IMacroContext.cs" />
|
||||
<Compile Include="RazorCore\IParameterDictionary.cs" />
|
||||
<Compile Include="RazorCore\UmbracoParameterDictionary.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="RazorBuildProvider.cs" />
|
||||
<Compile Include="RazorMacroEngine.cs" />
|
||||
<Compile Include="RazorCore\RazorBuildProvider.cs" />
|
||||
<Compile Include="RazorCore\RazorMacroEngine.cs" />
|
||||
<Compile Include="Scripting\MacroScript.cs" />
|
||||
<Compile Include="Scripting\ScriptEngine.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
Reference in New Issue
Block a user