When I switched to using BlogEngine.NET on this blog a while ago i was going to publish some software that i was writing. Mostly small applications but never the less something that could be of some importance. I figured that i could use the pages section for this purpose and nest the pages so that i would be able to visually differentiate the subpages from the main pages. Finally it was dont, but with some effort i must say.

The problem is that the data structure in BlogEngine.NET (concerning pages) is not a hierarchical structure - as you might think since you are able to specify a parent on a particular page. All pages are structured in one list and each Page object has a property named ParentId that refers to the Page with an equal Id as its parent, simplified this looks like this:

First Page
Id = 1
Parent = 0

Second Page
Id = 2
Parent = 0

Third Page
Id = 3
Parent = 1

Fourth Page
Id = 4
Parent = 2

This setup shows a structure where "First Page" and "Second Page" is on root level and the pages "Third Page" and "Fourth Page" is sub pages to each of the root pages. The solution to making this a nested list was to edit in the code file that generated the HTML that is used for displaying these pages and add levels into that structure. The following is the changes that were necessary:

  1. Modify the PageList.cs file to generate proper HTML
  2. Modify the style.css file to display the list properly

 The first step is to edit in the PageList class modifying the private method BindPages() method to look like the following:


private HtmlGenericControl BindPages()
{
    HtmlGenericControl div = new HtmlGenericControl("div");
    div.Attributes.Add("class", "pagelist");
    div.ID = "pagelist";
    foreach (BlogEngine.Core.Page page in BlogEngine.Core.Page.Pages)
    {
        if (page.ShowInList && page.IsVisibleToPublic && page.Parent.ToString() == "00000000-0000-0000-0000-000000000000")
        {
            div.Controls.Add(BuildSubPages(div, page));
        }
    }
    return div;
}

 Additional methods are required to build the nested structure, the following two methods should be added to the class as well:

private List<BlogEngine.Core.Page> FindChildPages(BlogEngine.Core.Page page)
{
    List<BlogEngine.Core.Page> result = new List<BlogEngine.Core.Page>();
    foreach (BlogEngine.Core.Page subpage in BlogEngine.Core.Page.Pages)
    {
        if (page.Id == subpage.Parent)
        {
            result.Add(subpage);
        }
    }
    return result;
}

private HtmlGenericControl BuildSubPages(HtmlGenericControl parentElement, BlogEngine.Core.Page page)
{
    HtmlGenericControl ul = new HtmlGenericControl("ul");
    HtmlGenericControl li = new HtmlGenericControl("li");
    ul.Controls.Add(li);
    HtmlAnchor anc = new HtmlAnchor();
    anc.HRef = page.RelativeLink.ToString();
    anc.InnerHtml = page.Title;
    anc.Title = page.Description;
    li.Controls.Add(anc);
    List<BlogEngine.Core.Page> subPages = FindChildPages(page);
    foreach (BlogEngine.Core.Page p in subPages)
    {
        li.Controls.Add(BuildSubPages(li, p));
    }
    parentElement.Controls.Add(ul);
    return ul;
}

 

Now the list is made up uf properly nested unordered lists and list items. The last task is to modify the stylesheet to override the default behavior and make your indentation etc. The style tag to look for is the "pagelist" class and the lists below that one.