How to generate an Umbraco XML Sitemap dynamically

Today, I implemented an XML sitemap in my Umbraco 7.7.9 installation. Here are the things I had to do:

  1. Create a Sitemap document type
  2. Create a Sitemap macro
  3. Create a rule for IIS URL rewriting of the sitemap.xml
  4. Author the Sitemap content page

Sitemap document type

My document type involves two properties which will allow content authors to:

  • Exclude content from the sitemap
  • Hide page from the navigation – In Umbraco, if you want a document type to utilise the “IsVisible” property of IPublishedContent, you will need to create a property with the alias as “umbracoNaviHide”

Screen-Shot-2018-03-05-at-9.03.54-pm

My Sitemap document template view has the following code:

@inherits Umbraco.Web.Mvc.UmbracoTemplatePage<ContentModels.Sitemap>
@using ContentModels = Umbraco.Web.PublishedContentModels;
@{
    Layout = null;
    umbraco.library.ChangeContentType("text/xml");
}
@Umbraco.RenderMacro("GetSitemap", new {})

Sitemap macro

The reason why I wanted to use a Macro is to utilise its caching features. I didn’t want to dynamically generate the sitemap on the fly. I only want it to dynamically generate once a day.

Note: I set my cache period to 86,400 seconds (equivalent to a day). No parameters are required

Screen-Shot-2018-03-05-at-9.08.42-pm

My macro view has the following implementation:

@inherits Umbraco.Web.Macros.PartialViewMacroPage
@{
    var rootCache = UmbracoContext.Current.ContentCache.GetAtRoot();
    var exclusions = (List<IPublishedContent>)CurrentPage.Exclusions;
    var rootList = rootCache.Except(exclusions);
}
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
    @foreach (var root in rootList)
    {
        <url>
            <loc>@root.UrlAbsolute()</loc>
            <lastmod>@root.UpdateDate.ToString("yyyy-MM-ddTHH:mm:00")+00:00</lastmod>
            @if (root.HasValue("updateFrequency"))
            {
                <changefreq>@root.GetPropertyValue("updateFrequency")</changefreq>
            }
        </url>
        var descendants = root.Descendants().Except(exclusions);
        foreach (var content in descendants)
        {
            <url>
                <loc>@content.UrlAbsolute()</loc>
                <lastmod>@content.UpdateDate.ToString("yyyy-MM-ddTHH:mm:00")+00:00</lastmod>
                @if (content.HasValue("updateFrequency"))
                {
                    <changefreq>@content.GetPropertyValue("updateFrequency")</changefreq>
                }
            </url>
        }
    }
</urlset>

IIS Rewrite Rule

On the web.config, I added the following rewrite rule inside the <system.webServer>:

Note: The sitemapxml is the name I will use to create the Sitemap content page in the next step

<rewrite>
   <rules>
      <rule name="Sitemap XML" enabled="true" stopProcessing="true">
         <match url="sitemap.xml" />
         <action type="Rewrite" url="sitemapxml" appendQueryString="false"/>
      </rule>
   </rules>
</rewrite>

Sitemap Content Page

On the CMS Content, an author can now instantiate a Sitemap page:

Screen-Shot-2018-03-05-at-9.29.54-pm

Works on my Umbraco 7.7.9 🙂

%d