Recently, I have found myself wanting to know what pages are referencing certain other pages, or sub pages for that matter, while surfing around in the EPiServer edit mode. Having worked with control adapters to extend built-in EPiServer functionality quite a lot lately, I decided to create a simple one that would make my life easier. Code at GitHub as usual.
There is really nothing complicated involved, all the adapter does is attaching an additional handler to the PageTreeViewItemDataBound event (22) during OnInit.
PageTreeViewTooltipAdapter.cs
public class PageTreeViewTooltipAdapter : ControlAdapter { protected override void OnInit(EventArgs e) { base.OnInit(e); var treeView = Control as PageTreeView; if(treeView == null) { return; } treeView.PageTreeViewItemDataBound += AddTooltipHandler; }
The handler then passes the page’s PageReference to the FindUsagesFor method (32) concatenating the results into a comma separated string; see section below. In order to add our new line of text to the EPiServer page tree tooltip, it is first necessary to create a new Attribute (33) that EPiServer will use assembling data.
private static void AddTooltipHandler(object sender, PageTreeViewEventArgs e) { var page = e.Item.DataItem as PageData; if(page == null) { return; } var ids = string.Join(", ", FindUsagesFor(page.PageLink)); e.Item.Attributes.Add("UsedOn", ids); }
EPiServer uses language files to define the tooltip markup. Hence, it is only a matter of adding the above UsedOn (33) identifier to the proper place (12) in order for it to render.
<?xml version="1.0" encoding="utf-8" standalone="yes"?> <languages> <language name="English" id="en"> <edit> <pageexplorer> <tooltip> Page Type: [PageTypeName]<br/> Created: [Created]<br/> Changed: [Changed]<br/> Page ID: [PageLink]<br /> Sort index: [PagePeerOrder][AdditionalInformation]<br /> Used on: [UsedOn]</tooltip>
Finding pages linking to the current page or one of its decending pages
Retriving the ids of all the pages that are referencing the current page or one of its decending pages is the easiest thing in this solution; the good people over at EPiServer has already done it for us. Feeding the method GetLinksToPages (39) with a PageReference will return a PageReferenceCollection containing what we want. If we do a bit of reflectoring we see that it also takes other page providers into account, not just the standard EPiServer.LocalPageProvider.
private static IEnumerable<string> FindUsagesFor(PageReference pageReference) { var references = DataFactory.Instance.GetLinksToPages(pageReference); if(references == null || !references.Any()) { return new[] {"-"}; } return references.Select(reference => reference.ID.ToString(CultureInfo.InvariantCulture)); }
I am aware that the Used on label does not accurately describe what it is that I am showing, but I blame a need to keep the text short together with a temporary lack of imagination. This was good enough to fulfill my requirements, but if you would like to single out the dependencies of a single page (not looking at decendants), I would suggest taking a peek at how EPiServer does things. Interesting methods may include EPiServer.DataFactory.GetLinksToPages(..), EPiServer.LocalPageProvider.GetReferencesToPages(..) as well as EPiServer.LocalPageProvider.GetReferencesToPageAndDescendents(..).