Back to News List

Developing with Advanced Sitemap in your Orchard site

Share This

This post is aimed at covering how a developer would go about implementing custom route providers for the Advanced Sitemap module for Orchard.

More general useage information can be found at the GitHub project's wiki page.

Extending the Sitemap

Advanced Sitemap is currently the only module to provide extensions points for developers who are doing a lot of custom development on their site. The basic use case of a module like this is very straightforward: take all of the content items and list out all of their urls in some sensible way. But what if you have routes that don't necessarily align with urls set in your content items? Entering custom routes in the admin can suffice if there aren't too many, but if you use a lot of custom routing in your MVC controllers, it would be nice to have these urls reflected accurately in the sitemap.

The concepts in use are very simple and involve the following interfaces:

  • ISitemapRouteProvider: Provides a list of sitemap nodes to include either in the sitemap xml, the displayed sitemap, or both.
  • ISitemapRouteFilter: Provides a filter function to restrict urls from being listed.

The module itself is built using two route provider implementations - one that generates nodes from your content (controlled by various settings) and another that generates them from pre-defined custom routes.

Let's look at the ISitemapRouteProvider interface:

Code snippet for ISitemapRouteProvider interface

The GetDisplayRoutes() and GetXmlRoutes() methods are called independently when needed and both return the same node structure. The Priority property determines which order the providers are queried in (Higher number is processed first). If a url is returned from a higher priority provider, it cannot be overwritten by a lower priority one.

Here is the structure of a node. The provider simply exports a list of these. For an explanation of these values, refer to the sitemap protocol.

Structure of a node

Telling Advanced Sitemap About Your Crazy Routes

Imagine if you had a large taxonomy that is correlated with information in a third-party source, like an e-commerce platform or something like that. You want to be able to use Orchard's taxonomy to generate the urls or to contain identifiers that link information in Orchard to information in this external service, but you want to use your own controller with those routes to deal with retrieving that data and displaying it. You know, like good ole' straight MVC.

So you have set up a controller called AwesomeServiceController with a routing pattern of "/AwesomeStuff/{term}" that gets information from the AwesomeService and displays it based on the term in the url.

  • /AwesomeStuff/Fun
  • /AwesomeStuff/Exciting
  • /AwesomeStuff/Dismal
  • /AwesomeStuff/NotVeryAwesome
  • /AwesomeStuff/...

Those actions are defined by a Taxonomy called AwesomeTypes.

You have a couple options here. You can add every url using the custom routes interface, or you can write a route provider that tells Advanced Sitemap to add all of these routes automatically. The second option sounds a lot better.

Code snippet

We are going to return the same list of routes for XML and for Display, so let's only write that function once:

Code snippet for returning same list of routes for XML and for Display

And we will use that to implement both XML and Display methods:

Using above code snippet to implement both methods

All of your custom routes will now show up. If you add taxonomy terms to AwesomeTypes, they will automatically appear in the sitemap.

This example makes some assumptions that you really shouldn't - namely that all of your term names will be url-friendly. You should probably use the id or slug in place of the term name for url generation.

Route Filtering

This one is quite a bit easier. Let's say you have a lot of static pages in a hierarchy, but you don't want anything after a certain url fragment to appear in the sitemap. Putting it in a nofollow directive in your robots.txt won't work if you are still submitting all those links via your sitemap. You need to filter them out of your sitemap completely.

Here, we'll implement ISitemapRouteFilter:

How to implement ISitemapRouteFilter

Now, every page like 'secrets/evil-plan' or 'secrets/money-embezzlement-program' will be excluded from the sitemap.


I regularly take pull requests at the GitHub project, so if there is a feature you want to see added, don't hesitate to submit it!

What's Next?

Back to Top