Hi Guys,
I have a scenario in our website where I need to display the Episerver tree on our view.
Like-
So I thought that we can use the “GetDescendents” method and it will render the tree but i was wrong. It basically give you all the page items in a single list so you need to build the tree by your own.
So to build the tree i wrote below code-
public class BlogItemTree
{
public int PageId { get; set; }
public int? ParentPageId { get; set; }
public PageData ContentPage { get; set; }
public List Children { get; set; }
}
public static class GenericExtensions
{
private static readonly IContentLoader _contentLoader;
static GenericExtensions()
{
_contentLoader = ServiceLocator.Current.GetInstance();
}
public static void FindDescendantsOfType(PageData page, ICollection descendants)
where T : class
{
var children = _contentLoader.GetChildren(page.PageLink);
foreach (var child in children)
{
if (child is T)
{
descendants.Add(child as T);
}
FindDescendantsOfType(child, descendants);
}
}
public static List BlogItemTrees(List descendants)
{
var blogItemTree = new List();
foreach (var blogItem in descendants)
{
var item = new BlogItemTree() { PageId = blogItem.PageLink.ID, ParentPageId = blogItem.ParentLink.ID };
blogItemTree.Add(item);
}
var tree = blogItemTree.BuildTree();
return tree;
}
public static List BuildTree(this IEnumerable source)
{
var groups = source.GroupBy(i => i.ParentPageId);
var roots = groups.FirstOrDefault().ToList();
if (roots.Count > 0)
{
var dict = groups.Where(g => g.Key.HasValue).ToDictionary(g => g.Key.Value, g => g.ToList());
for (int i = 0; i < roots.Count; i++)
{
var pageRef = new PageReference(roots[i].PageId);
roots[i].ContentPage = _contentLoader.Get(pageRef);
AddChildren(roots[i], dict);
}
}
return roots;
}
private static void AddChildren(BlogItemTree node, IDictionary> source)
{
if (source.ContainsKey(node.PageId))
{
node.Children = source[node.PageId];
var pageRef = new PageReference(node.PageId);
node.ContentPage = _contentLoader.Get(pageRef);
for (int i = 0; i < node.Children.Count; i++)
{
AddChildren(node.Children[i], source);
}
}
else
{
var pageRef = new PageReference(node.PageId);
node.ContentPage = _contentLoader.Get(pageRef);
node.Children = new List();
}
}
}
And then created one more class to call these functions and get the proper output
public class BlogListByYearBlockService
{
public List Descendants = new List();
private readonly IContentLoader _contentLoader;
public BlogListByYearBlockService(IContentLoader contentLoader)
{
_contentLoader = contentLoader ?? throw new ArgumentNullException(nameof(contentLoader));
}
public List GetTreeData(BlogListByYearBlock block)
{
GenericExtensions.FindDescendantsOfType(StartPage, Descendants);
List tree = GenericExtensions.BlogItemTrees(Descendants);
return tree;
}
}
Now the tree object will give you the exact same tree that is in your Episerver you just need to render this.
Thanks for reading this blog post I hope it helps
Thanks and regards
Ravindra S. Rathore