Create a gist now

Instantly share code, notes, and snippets.

XML sitemap for Umbraco 7 (based on Cultiv Search Engine Sitemap package). See http://www.alexlindgren.com/archive/dynamically-generated-xml-sitemaps-with-umbraco-7/
@inherits Umbraco.Web.Mvc.UmbracoTemplatePage
@using System.Linq;
@{
Layout = null;
Response.ContentType = "text/xml";
}<?xml version='1.0' encoding='UTF-8' ?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">
@ListChildNodes(Umbraco.TypedContent(UmbracoContext.Current.PageId).AncestorOrSelf(1))
</urlset>
@helper ListChildNodes(IPublishedContent startNode)
{
foreach (var node in startNode.Children.Where("hideInXmlSitemap == false"))
{
if (node.TemplateId > 0)
{
<url>
<loc>@GetUrlWithDomainPrefix(node.Url)</loc>
<lastmod>@(string.Format("{0:s}+00:00", node.UpdateDate))</lastmod>
</url>
}
if (node.Level <= 100 && node.Children.Count() > 0)
{
@ListChildNodes(node)
}
}
}
@functions {
private static string GetUrlWithDomainPrefix(string url)
{
if (url.StartsWith("/"))
url = url.Substring(1);
var domainPrefix = string.Format("http://{0}/", HttpContext.Current.Request.ServerVariables["HTTP_HOST"]);
if (url.StartsWith(domainPrefix))
return url;
else
return domainPrefix + url;
}
}
@garpur
garpur commented May 6, 2015

I have a site that has more than one "root"
so I put the sitemap in the root and modified the template with the following:

@foreach (var node in Umbraco.ContentAtRoot()) {

@GetUrlWithDomainPrefix(node.Url)
@(string.Format("{0:s}+00:00", node.UpdateDate))

@ListChildNodes(node);

}

instead of @ListChildNodes(Umbraco.TypedContent(UmbracoContext.Current.PageId).AncestorOrSelf(1))

thx, for the blog and code it was just what I needed.

@niallmccabe

There is also an issue with the urls in the sitemap if your site uses https as opposed to http. This can be solved by amending the GetUrlWithDomainPrefix function as follows:

private static string GetUrlWithDomainPrefix(string url)
{
if (url.StartsWith("/"))
url = url.Substring(1);

    if (url.StartsWith("http://"))
    {
        url = url.Replace("http://", "https://");
    }

    var domainPrefix = string.Format("https://{0}/", HttpContext.Current.Request.ServerVariables["HTTP_HOST"]);

    if (url.StartsWith(domainPrefix))
        return url;
    else
        return domainPrefix + url;
}
@BarryFogarty

Useful script! Thanks for sharing. NB in Umbraco 7 we can use

node.UrlWithDomain()

and thus dispense with the GetUrlWithDomainPrefix() helper function.

In my case, I don't use a flag to exclude nodes from the sitemap, I do it by document type alias, as follows:

var docTypeExclusions = new List<string>()
    {
        "Basket", "Checkout", "Receipt", "etc"
    };
foreach (var node in startNode.Children.Where(x => !x.DocumentTypeAlias.ContainsAny(docTypeExclusions)))
{ ... }
@biapar
biapar commented Mar 22, 2016

In Umbraco 6 there is NiceUrlWithDomain to bypass GetUrlWithDomainPrefix

@biapar
biapar commented Mar 22, 2016

Frequency: how to setup?

@jclementson

Excellent. Nice and simple and saved a lot of time. Thanks for sharing!

One typo - xsi:schemalocation should be xsi:schemaLocation

@alindgren
Owner

@jclementson: thanks - I've updated the Gist with xsi:schemaLocation

@ryanology

I was running into a problem where the view was adding an extra line at the beginning so that the xml declaration was on line 2, and thus invalid (getting the error "error on line 2 at column 6: XML declaration allowed only at the start of the document");

The fix that made it work for me was to write out the xml declaration in the response stream at the beginning of the view page. So the top looked like this instead:

@{
Response.Write("");
Response.ContentType = "text/xml";
Layout = null;
}
@inherits Umbraco.Web.Mvc.UmbracoTemplatePage
@using System.Linq;
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">
@ListChildNodes(Umbraco.TypedContent(UmbracoContext.Current.PageId).AncestorOrSelf(1))
</urlset>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment