Typically I see this breadcrumb being generated in the front-end from the Sitemap, which is not a very expensive operation but still a very silly approach. If an editor creates a page in a given Structure Group and publishes it, we already know the page's location at publish time, so why would we waste some CPU cycles on the front-end determining this?
Since I had to write this Building Block just now I thought I could share it with you.
using System.Text.RegularExpressions; using System.Xml; using Tridion.ContentManager; using Tridion.ContentManager.CommunicationManagement; using Tridion.ContentManager.ContentManagement; using Tridion.ContentManager.Templating; using Tridion.ContentManager.Templating.Assembly; namespace TridionTemplates { public class GetPageBreadcrumb : ITemplate { private const string _separator = " » "; private const string RegexPattern = @"^[\d]* "; private const string indexPagePattern = "index"; private readonly Regex _regex = new Regex(RegexPattern, RegexOptions.None); public void Transform(Engine engine, Package package) { TemplatingLogger log = TemplatingLogger.GetLogger(GetType()); if (package.GetByName(Package.PageName) == null) { log.Info("Do not use this template building block in Component Templates"); return; } Page page = (Page)engine.GetObject(package.GetByName(Package.PageName)); string output = StripNumbersFromTitle(page.OrganizationalItem.Title); foreach (OrganizationalItem parent in page.OrganizationalItem.GetAncestors()) { output = GetLinkToSgIndexPage((StructureGroup)parent, engine.GetSession()) + _separator + output; } package.PushItem("breadcrumb", package.CreateStringItem(ContentType.Html, output)); } private string StripNumbersFromTitle(string title) { return Regex.Replace(title, RegexPattern, string.Empty); } private string GetLinkToSgIndexPage(StructureGroup sg, Session session) { OrganizationalItemItemsFilter filter = new OrganizationalItemItemsFilter(session); filter.ItemTypes = new[] { ItemType.Page }; string title = StripNumbersFromTitle(sg.Title); string pageLinkFormat = "<a tridion:href=\"{0}\">{1}</a>"; string result = null; foreach (XmlElement page in sg.GetListItems(filter).ChildNodes) { if (page.Attributes["Title"].Value.ToLower().Contains(indexPagePattern)) { result = string.Format(pageLinkFormat, page.Attributes["ID"].Value, title); break; } } if (string.IsNullOrEmpty(result)) { result = title; } return result; } } }
Yes, it does quite a lot more than just create a breadcrumb, I'll leave it up to you figure that out :)
PS - I am using OrganizationalItem.GetAncestors() in this code, which means it will only work with SDL Tridion 2011 SP1.
1 comment:
Nice way of looking for index pages.
If you want to use it on older versions, you can do something like:
StructureGroup parent = page.OrganizationalItem as StructureGroup;
while (parent != null)
{
output = ... + output;
parent = parent.OrganizationalItem as StructureGroup;
}
Post a Comment