Skip to content

Instantly share code, notes, and snippets.

@AaronSadlerUK
Created October 13, 2021 09:55
Show Gist options
  • Save AaronSadlerUK/28dd6921aa5b24b53b41c2302c7a2f56 to your computer and use it in GitHub Desktop.
Save AaronSadlerUK/28dd6921aa5b24b53b41c2302c7a2f56 to your computer and use it in GitHub Desktop.
How to create an Xml Sitemap in Umbraco V9
public interface ISiteMapXmlService
{
public string GenerateXml();
}
using Umbraco.Cms.Core.Models.PublishedContent;
using Umbraco.Extensions;
public static class PublishedContentExtensions
{
public static bool HasTemplate(this IPublishedContent content) => content.TemplateId > 0;
public static bool IsInSiteMap(this IPublishedContent content) => !content.Value<bool>("hideFromXmlSitemap", defaultValue: false) && content.HasTemplate();
}
using System.Linq;
using System.Xml.Linq;
using Umbraco.Cms.Core.Models.PublishedContent;
using Umbraco.Cms.Core.Web;
using Umbraco.Extensions;
/// <summary>
/// Generates an XML sitemap
/// </summary>
public class SiteMapXmlService : ISiteMapXmlService
{
private readonly IUmbracoContextFactory _umbracoContextFactory;
private static readonly XNamespace Xmlns = "http://www.sitemaps.org/schemas/sitemap/0.9";
public SiteMapXmlService(IUmbracoContextFactory umbracoContextFactory)
{
_umbracoContextFactory = umbracoContextFactory;
}
public string GenerateXml()
{
using var context = _umbracoContextFactory.EnsureUmbracoContext();
var rootNode = context.UmbracoContext.Content.GetByXPath("//home").First();
var nodes = rootNode
.DescendantsOrSelf()
.Where(x => x.HasTemplate())
.Where(x => x.IsVisible())
.Where(x => x.Value<bool>("hideFromXmlSitemap") == false);
XElement root = new XElement(Xmlns + "urlset");
foreach (var node in nodes)
{
var urlElement = new XElement(Xmlns + "url",
new XElement(Xmlns + "loc", node.Url(mode: UrlMode.Absolute)),
new XElement(Xmlns + "lastmod", node.UpdateDate.ToString("yyyy-MM-dd")));
var changeFreqency = node.Value<string>("searchEngineChangeFrequency");
if (string.IsNullOrWhiteSpace(changeFreqency) == false)
{
urlElement.Add(new XElement(Xmlns + "changefreq", changeFreqency.ToLower()));
}
var priority = node.Value<decimal>("searchEngineRelativePriority");
if (priority > 0)
{
urlElement.Add(new XElement(Xmlns + "priority", priority));
}
root.Add(urlElement);
}
XDocument document = new XDocument(root);
var sitemapXml = document.ToString();
return sitemapXml;
}
}
using System.Text;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core.Cache;
using Umbraco.Cms.Core.Logging;
using Umbraco.Cms.Core.Routing;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Core.Web;
using Umbraco.Cms.Infrastructure.Persistence;
using Umbraco.Cms.Web.Website.Controllers;
public class XmlSiteMapSurfaceController : SurfaceController
{
private readonly ISiteMapXmlService _xmlSiteMapXmlService;
[Route("sitemap.xml")]
[ResponseCache(Duration = 900)]
public ContentResult Index()
{
return Content(_xmlSiteMapXmlService.GenerateXml(), "text/xml", Encoding.UTF8);
}
public XmlSiteMapSurfaceController(IUmbracoContextAccessor umbracoContextAccessor, IUmbracoDatabaseFactory databaseFactory, ServiceContext services, AppCaches appCaches, IProfilingLogger profilingLogger, IPublishedUrlProvider publishedUrlProvider, ISiteMapXmlService xmlSiteMapXmlService)
: base(umbracoContextAccessor, databaseFactory, services, appCaches, profilingLogger, publishedUrlProvider)
{
_xmlSiteMapXmlService = xmlSiteMapXmlService;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment