If you’re looking to generate a sitemap.xml file, this post contains a handy TBB to use as a starting point for your development.
Below you’ll find a c# template building block, that does the following:
- Loops all the structure groups and pages from the root
- Checks if the item is published to the correct target
- Checks page and structure group metadata for a flag ‘show_in_searchengine_sitemap’
Because this version needs to check the object for metadata values, the code is written to using the GetItems() function to obtain a list of objects, in the event you don’t need this, it’s recommended for performance to use the GetListItems() function as this will return XML meaning much better performance.
Anyway onto the code, I’ll highlight the important bits afterwards.
</p> <pre> using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Xml; using Tridion.Extensions.ContentManager.Templating; using Tridion.ContentManager.Templating; using Tridion.ContentManager.ContentManagement; using Tridion.ContentManager.CommunicationManagement; using Tridion.ContentManager.ContentManagement.Fields; using Tridion.ContentManager.Templating.Assembly; using Tridion.ContentManager; using Tridion.ContentManager.Publishing; namespace Tridion.Templates.Library.Common { class SearchEngineSiteMap : ITemplate { private Engine engine; private Package package; private static readonly TemplatingLogger log = TemplatingLogger.GetLogger(typeof(SearchEngineSiteMap)); public void Transform(Engine engine, Package package) { //Initialize this.engine = engine; this.package = package; StringBuilder siteMapContent = new StringBuilder(); Page page = null; Item pageItem = package.GetByType(ContentType.Page); if (pageItem != null) { page = engine.GetObject(pageItem.GetAsSource().GetValue("ID")) as Page; } else { throw new InvalidOperationException("No Page found. Verify that this template is used with a Page."); } // get the publication object Publication publication = page.ContextRepository as Publication; // use the root sg to generate the sitemap siteMapContent.Append("<?xml version=\"1.0\" encoding=\"utf-8\"?><urlset>"); siteMapContent.Append(GenerateSitemap(publication.RootStructureGroup)); siteMapContent.Append("</urlset>"); // Put the translate lables component into the package package.PushItem(Package.OutputName, package.CreateStringItem(ContentType.Text, siteMapContent.ToString())); } private string GenerateSitemap(RepositoryLocalObject reposityObj) { if (!ShowInOutput(reposityObj)) { return string.Empty; } else { StringBuilder siteMapString = new StringBuilder(); if (reposityObj.GetType() == typeof(StructureGroup)) { // process this structure group StructureGroup sg = (StructureGroup)reposityObj; siteMapString.Append("<url>"); siteMapString.AppendFormat("<loc>{0}</loc>", sg.PublishLocationUrl); siteMapString.AppendFormat("<lastmod>{0}</lastmod>", sg.RevisionDate.ToShortDateString()); siteMapString.AppendFormat(" <priority>{0}</priority>", "0.5"); // 0.5 is default - add your logic here siteMapString.Append("</url>"); // Get all the items inside the root sg foreach (RepositoryLocalObject repObject in sg.GetItems()) { //log.Debug("SiteMap processing id: " + repObject.Id); siteMapString.Append(GenerateSitemap(repObject)); } } else { // process the page Page page = (Page)reposityObj; siteMapString.Append("<url>"); siteMapString.AppendFormat("<loc>{0}</loc>", page.PublishLocationUrl); siteMapString.AppendFormat("<lastmod>{0}</lastmod>", page.RevisionDate.ToShortDateString()); siteMapString.AppendFormat(" <priority>{0}</priority>", "0.5"); // 0.5 is default - add your logic here siteMapString.Append("</url>"); } return siteMapString.ToString(); } } private bool ShowInOutput(RepositoryLocalObject pageOrSg) { log.Debug(engine.RenderMode.ToString()); if (engine.RenderMode != ContentManager.Publishing.RenderMode.Publish) { if (PublishEngine.IsPublished(pageOrSg, engine.PublishingContext.PublicationTarget)) { XmlElement xMeta = pageOrSg.Metadata; if (xMeta != null) { XmlNode showMetaNode = xMeta.SelectSingleNode("//show_in_searchengine_sitemap"); if (showMetaNode != null) { log.Debug("meta found : " + showMetaNode.OuterXml); if (showMetaNode.InnerText.ToLower() == "no") return true; } } } } return true; } } } </pre> <p>
So here are some of the things you might like (or need) to change:
Â
Line 73 and 89:
siteMapString.AppendFormat(” {0}”, “0.5”);
I’ve hard coded the priority in a real environment it might be worth having some logic to give priority to certain pages or sections.
Â
Line 108:
XmlNode showMetaNode = xMeta.SelectSingleNode(“//show_in_searchengine_sitemap”);
The value ‘show_in_searchengine_sitemap’ is based on the schema field in the metadata in my environment, you’ll need to change this to match the schema field in your set up, or if this isn’t needed remove this code altogether.
Â
Â
Â