AI OnAI Off
- Level 1 - first node
-
Level 1 - second node
- Level 2 - first node
- Level 2 - second node
- Level 2 - third node
- Level 1 - third node
I'd like the implementation to be as flexible as possible, theoretically allowing as many levels I'd like. Practically I would strongly discourage anyone from showing more than three levels of depth at any one time (that means it is time to think about your content in another way). If you have the implementation, and also some example styles I'd really appreciate it. If code is needed to do this, I'll be happy with that too :-) /Steve
And there is a bit of code behind this file and in the Masterpage.
Unfortunately EPiServer is a huge fan of using
using System;
using System.Reflection;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using EPiServer;
using EPiServer.Core;
using EPiServer.Security;
namespace KnowIT.WebControls
{
///
///
///
public class PageTreeList : EPiServer.WebControls.PageTreeData, INamingContainer
{
private ITemplate _itemTemplate = null;
private ITemplate _rootTemplate = null;
private ITemplate _headerTemplate = null;
private ITemplate _footerTemplate = null;
private PageDataCollection _parentChain = null;
public PageTreeList()
{
}
public string ContainerID
{
set { ViewState["ContainerID"] = value; }
get { return ViewState["ContainerID"] != null ? ViewState["ContainerID"].ToString() : ""; }
}
public string CssClass
{
set { ViewState["CssClass"] = value; }
get { return ViewState["CssClass"] != null ? ViewState["CssClass"].ToString() : ""; }
}
public string LastItemClass
{
set { ViewState["LastItemClass"] = value; }
get { return ViewState["LastItemClass"] != null ? ViewState["LastItemClass"].ToString() : ""; }
}
public string FirstItemClass
{
set { ViewState["FirstItemClass"] = value; }
get { return ViewState["FirstItemClass"] != null ? ViewState["FirstItemClass"].ToString() : ""; }
}
public string SelectedClass
{
set { ViewState["SelectedClass"] = value; }
get { return ViewState["SelectedClass"] != null ? ViewState["SelectedClass"].ToString() : ""; }
}
public string ExpandedClass
{
set { ViewState["ExpandedClass"] = value; }
get { return ViewState["ExpandedClass"] != null ? ViewState["ExpandedClass"].ToString() : ""; }
}
public string AfterSelectedClass
{
set { ViewState["AfterSelectedClass"] = value; }
get { return ViewState["AfterSelectedClass"] != null ? ViewState["AfterSelectedClass"].ToString() : ""; }
}
public string BeforeSelectedClass
{
set { ViewState["BeforeSelectedClass"] = value; }
get { return ViewState["BeforeSelectedClass"] != null ? ViewState["BeforeSelectedClass"].ToString() : ""; }
}
public string ContainerTag
{
set { ViewState["ContainerTag"] = value; }
get { return ViewState["ContainerTag"] != null ? ViewState["ContainerTag"].ToString() : "ul"; }
}
protected virtual HtmlGenericControl CreateContainerControl(int level)
{
string cssClass = "";
HtmlGenericControl listContainer = new HtmlGenericControl(ContainerTag);
if ((level == 0 & ShowRootPage) | (level == 1 & !ShowRootPage))
{
cssClass = AppendClass(cssClass, CssClass);
if (ContainerID.Length > 0)
listContainer.Attributes.Add("id", ContainerID);
}
if (cssClass.Length > 0)
listContainer.Attributes.Add("class", cssClass);
return listContainer;
}
protected virtual string AppendClass(string currentClass, string addClass)
{
return AppendClass(currentClass, addClass, null);
}
protected virtual string AppendClass(string currentClass, string addClass, PageTreeReader reader)
{
if (addClass.Length > 0)
{
if (currentClass.IndexOf(addClass) < 0)
{
if (currentClass.Length > 0)
currentClass += " ";
if(reader != null)
if ((addClass.EndsWith("_lvl")) | (addClass.EndsWith("_level")) | (addClass.EndsWith("_lv")))
addClass += reader.CurrentIndent.ToString();
currentClass += addClass;
}
}
return currentClass;
}
protected virtual bool IsInParentChain(PageData page)
{
return ParentChain().Exists(page.PageLink);
}
protected virtual PageDataCollection ParentChain()
{
if (_parentChain == null)
{
_parentChain = new PageDataCollection();
PageData page = this.CurrentPage;
while (page.ParentLink != PageReference.EmptyReference)
{
_parentChain.Insert(0, page);
page = Global.EPDataFactory.GetPage(page.ParentLink, AccessControlList.NoAccess);
}
}
return _parentChain;
}
protected virtual HtmlGenericControl CreateListControl(PageTreeReader page)
{
string cssClass = "";
HtmlGenericControl listItem = new HtmlGenericControl("li");
if (page.IndentJump > 0)
cssClass = AppendClass(cssClass, FirstItemClass);
if (page.Page.PageLink.CompareToIgnoreWorkID(base.CurrentPage.PageLink))
cssClass = AppendClass(cssClass, SelectedClass, page);
if (IsInParentChain(page.Page))
cssClass = AppendClass(cssClass, ExpandedClass, page);
if (cssClass.Length > 0)
{
listItem.Attributes.Add("class", cssClass);
}
return listItem;
}
protected virtual void AppendToListControl(HtmlGenericControl listItem, string propertyName)
{
string cssClass = "";
if (listItem.Attributes["class"] != null && listItem.Attributes["class"] != "")
cssClass = listItem.Attributes["class"];
PropertyInfo property = this.GetType().GetProperty(propertyName);
if( property != null )
cssClass = AppendClass(cssClass, property.GetValue(this, null).ToString());
if (cssClass.Length > 0)
listItem.Attributes.Add("class", cssClass);
}
protected virtual void CreateContainer(PageTreeReader reader, Control appendTo)
{
Control workingControl = appendTo;
HtmlGenericControl listContainer = null;
HtmlGenericControl listItem = null;
int selectedLevel = -1;
while (reader.Read())
{
if (ShowRootPage && reader.Pages.Find(reader.Page.PageLink) == 0)
{
listContainer = CreateContainerControl(reader.CurrentIndent);
appendTo.Controls.Add(listContainer);
}
else
{
if (reader.IndentJump > 0)
{
listContainer = CreateContainerControl(reader.CurrentIndent);
if (listItem == null)
appendTo.Controls.Add(listContainer);
else
listItem.Controls.Add(listContainer);
}
else if (reader.IndentJump < 0)
{
for (int i = reader.IndentJump; i < 0; i++)
{
if (listItem != null)
AppendToListControl(listItem, "LastItemClass");
listItem = listContainer.Parent as HtmlGenericControl;
listContainer = listItem.Parent as HtmlGenericControl;
}
}
}
if (reader.Page.PageLink.CompareToIgnoreWorkID(base.CurrentPage.PageLink))
if (listContainer != null && listContainer.Controls.Count > 0)
AppendToListControl((HtmlGenericControl)listContainer.Controls[listContainer.Controls.Count - 1], "BeforeSelectedClass");
listItem = CreateListControl(reader);
if (selectedLevel == reader.CurrentIndent)
{
AppendToListControl(listItem, "AfterSelectedClass");
selectedLevel = -1;
}
if (reader.Page.PageLink.CompareToIgnoreWorkID(base.CurrentPage.PageLink))
selectedLevel = reader.CurrentIndent;
if(listContainer != null)
listContainer.Controls.Add(listItem);
PageTemplateContainer item = new PageTemplateContainer(reader.Page);
if (ShowRootPage && reader.Pages.Find(reader.Page.PageLink) == 0)
{
this.RootTemplate.InstantiateIn(item);
}
else
{
this.ItemTemplate.InstantiateIn(item);
}
listItem.Controls.Add(item);
}
if (listItem != null)
AppendToListControl(listItem, "LastItemClass");
}
protected override void CreateChildControls()
{
if (SetDefaultTemplates())
{
PageDataCollection pages = this.GetPages();
if (pages.Count > 0)
{
PageTreeReader reader = new PageTreeReader(pages);
PageReference currentPageLink = base.CurrentPage.PageLink;
PageData basePage = null;
if (this.PageLink != PageReference.EmptyReference)
{
basePage = GetPage(this.PageLink);
}
else if (pages[0].Indent == 0)
{
basePage = pages[0];
}
if (this.HeaderTemplate != null)
{
Control header = new PageTemplateContainer(basePage);
this.HeaderTemplate.InstantiateIn(header);
this.Controls.Add(header);
}
CreateContainer(reader, this);
if (this.FooterTemplate != null)
{
Control footer = new PageTemplateContainer(basePage);
this.FooterTemplate.InstantiateIn(footer);
this.Controls.Add(footer);
}
}
}
}
protected virtual bool SetDefaultTemplates()
{
if (this.ItemTemplate == null)
return false;
if (this.RootTemplate == null)
this.RootTemplate = this.ItemTemplate;
return true;
}
[TemplateContainer(typeof(PageTemplateContainer)), PersistenceMode(PersistenceMode.InnerProperty)]
public ITemplate RootTemplate
{
set { _rootTemplate = value; }
get { return _rootTemplate; }
}
[TemplateContainer(typeof(KnowIT.WebControls.PageTemplateContainer)), PersistenceMode(PersistenceMode.InnerProperty)]
public ITemplate ItemTemplate
{
set { _itemTemplate = value; }
get { return _itemTemplate; }
}
[TemplateContainer(typeof(KnowIT.WebControls.PageTemplateContainer))]
public ITemplate HeaderTemplate
{
set { _headerTemplate = value; }
get { return _headerTemplate; }
}
[TemplateContainer(typeof(KnowIT.WebControls.PageTemplateContainer))]
public ITemplate FooterTemplate
{
set { _footerTemplate = value; }
get { return _footerTemplate; }
}
}
}
HTML use