How to get the Sitefinity Sitemap Globalized

By default Sitefinity provides functionality to generate sitemap content for search engines. There is a solution to seperate the output in the sitemap for each implemented content language.

Sitefinity Sitemap

Onze technische blogs zijn in hetEngels. Dit doen wij omdat wij menen dat technische kennis van Sitecore en Sitefinity grensoverschrijdend moet zijn. Wij leren veel van buitenlandse developers, wij delen onze kennis ook graag met hen. Mochten er in de code fouten zitten of punten ter verbetering, dan gaan we graag het gesprek aan.

Sitemap content with custom code

For a specific project that contains multiple custom content, we ended up in serving sitemap content with custom code. This project uses multiple languages and in this particular case it is required to output only content for a given language

The customer in this matter has its localized websites registered as separate websites in Google Webmastertools (www.sf-website.com/en/ , www.sf-website.com/nl/, www.sf-website.com/mx/, etc.

In webmastertools, the sitemap for each locale website needs to be provided (www.sf-website.com/en/sitemap, www.sf-website.com/nl/sitemap) and each locale should output only the content of its own language.

This is how we solved this: In the webroot, we created a sitemap handler called “Sitemap.ashx” which is a HttpHandler.

{

public class SiteMap : IHttpHandler

{

private string langCode = String.Empty;

public void ProcessRequest(HttpContext context)

{

langCode = [ code to extract langCode from url, or extract from CultureInfo in current thread ]

 

string xmlData = this.CreateSitemapXml();

 

context.Response.Clear();

context.Response.ContentType = "text/xml";

context.Response.Charset = "UTF-8";

context.Response.Write(xmlData);

context.Response.End();

}

 

private string CreateSitemapXml()

{

XNamespace xmlNamespace = "http://www.sitemaps.org/schemas/sitemap/0.9";

XElement xmlRoot = new XElement(xmlNamespace + "urlset");

 

var pages = App.WorkWith().Pages()

.LocatedIn(PageLocation.Frontend)

.Where(page => page.ApprovalWorkflowState == "Published" && page.ShowInNavigation == true)

.Get().ToList();

 

foreach (var page in pages)

{

CultureInfo culture = page.AvailableCultures.FirstOrDefault(ac => ac.ToString().Equals(langCode, StringComparison.OrdinalIgnoreCase));

string pageUrl = PageHelper.GetLanguageUrl(page.Id, culture);

 

xmlRoot.Add(

new XElement(

xmlNamespace + "url",

new XElement(xmlNamespace + "loc", pageUrl),

new XElement(xmlNamespace + "lastmod", page.LastModified.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture)),

new XElement(xmlNamespace + "changefreq", "daily"),

new XElement(xmlNamespace + "priority", "0.5")));

}

XDocument xmlDocument = new XDocument();

xmlDocument.Add(xmlRoot);

 

return "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>" + xmlDocument.ToString();

}

}

}

This is a stripped down sample which outputs the page urls for the language given by the url. The PageHelper is a library to resolve the url from a page object. Now all we have to do is to set custom routing to lead url’s like www.sf-website.com/nl/sitemap to the sitemap.ashx.

In the Global.asax we need to add a route to the routetable:

RouteTable.Routes.Add("CustomSiteMapRouting", new Route("{country}/sitemap", new SiteMapRoutingHandler()));

And this SiteMapRoutingHandler is a custom RouteHandler which leads to the custom Sitemap handler:

{

public IHttpHandler GetHttpHandler(RequestContext requestContext)

{

return new SitefinityHandlers.SiteMap();

}

}

And then we are done here, www.sf-website.com/nl/sitemap will output only dutch content url’s.

Mind that for more obvious Sitemap functionality you should use the default Sitefinity functionality for generating a sitemap. The solution above can be used for similar requirements.