If you're a competent .NET programmer, you can create your own custom Module Sitemap Provider. Even a basic programmer should be able to master the steps. They can be written in any .NET language, including C#, VB.NET and others. In this example, you will see YourModuleName and YourNamespace. Just substitute your module name and namespace in these areas, and don't include the square brackets.

All of the source code for the example providers are available on the downloads page, so it's worth downloading one of the providers that closely match one of the existing modules. The simplest example would be the Wiki sitemap generator. The ActiveForums provider is written in VB.NET for a VB example.

Making a Simple Sitemap Generator

Step 1: Create a new Project in Visual Studio, call it YourModuleNameSiteMapProvider.

Step 2: Add a Project reference to the DotNetNuke.Providers.SearchEngineSiteMapProvider.dll - you can obtain this from the download package of the Base Search Engine Sitemap Provider.

Step 3: Add a new class to your project, and make this class inherit from the DotNetNuke.Providers.SearchEngineSiteMapProvider.SiteMapProvider class. Set the namespace for your module to the YourNamespace value.

public class YourModuleNameSiteMapProvider : DotNetNuke.Providers.SearchEngineSiteMapProvider.SiteMapProvider

Public Class YourModuleNameSiteMapProvider
Inherits DotNetNuke.Providers.SearchEngineSiteMapProvider.SiteMapProvider

It's a good idea to name your Class file the same as your Class name, ie YourModuleNameSiteMapProvider.cs

Step 4 : Implement a class constructor for the class, like this.

public YourModuleSiteMapProvider(string name, System.Collections.Specialized.NameValueCollection config) : base (name, config)
_myModuleSetting = GetSafeSetting(config, "myModuleSetting", true);

Public Sub New(ByVal name As String, ByVal config As System.Collections.Specialized.NameValueCollection)
MyBase.New(name, config)
m_myModuleSetting = GetSafeSetting(config, "myModuleSetting", true)
End Sub

Your constructor will be supplied with the provider name, and the config object. The config object is a NameValueCollection of any attributes in the configuration class. You can use a built-in base method called 'GetSafeSetting(config, name, defaultValue)' to easily return a particular typed value from any custom xml Attributes you may want to add for your provider. The above example shows the returning of a config setting (myModuleSetting="true") from the config entry into a provider-level member variable.

Step 5 : Implement an overridden SitePagesForTab method for the class. This is the method which is called by the base provider in order to request a list of Sitemap entries which are specific to the module.

public override List<SitePage> SitePagesForTab(DotNetNuke.Entities.Portals.PortalAliasInfo portalAlias, DotNetNuke.Entities.Tabs.TabInfo tab, DotNetNuke.Services.Localization.Locale locale, int sitemapNum, int urlCount, int startingCount, int endingCount)

Public Overrides Function SitePagesForTab(portalAlias As DotNetNuke.Entities.Portals.PortalAliasInfo, tab As DotNetNuke.Entities.Tabs.TabInfo, locale As Locale, sitemapNum As Integer, urlCount As Integer, startingCount As Integer, endingCount As Integer) As System.Collections.Generic.List(Of DotNetNuke.Providers.SearchEngineSiteMapProvider.SitePage)
End Function

The SitePagesForTab() method will return a list of SitePage objects. Each SitePage object refers to a single sitemap entry, with a <loc>, <lastmod>, <changefreq> and <priority> value.

Step 6 : Write your custom code to complete the SitePagesForTab method retrieve all of the module entries that are specific to the particular tab.

The basic pseudo-code for this method is something like the following:

List<SitePage> sitePages = new List<SitePage>();
List<ModuleItemInfo> moduleItems = YourModuleController.GetListOfItems(tab.PortalId, tab.TabId)
foreach (ModuleItemInfo item in moduleItems)
SitePage sitemapEntry = new SitePage();
sitemapEntry.Loc = base.GetTabUrl(tab, locale.Language, "itemId=" + item.ItemId.ToString());
sitemapEntry.LastMod = item.UpdateDate;
sitemapEntry.ChangeFreq = _defaultPageUpdateFrequency;
sitemapEntry.priority = _defaultPriority;
return sitePages;

Note that the defaultPageUpdateFrequency and defaultPriority are automatically set by the provider when it is loaded.

base.GetTabUrl() is an underlying method of the base provider which wraps the DotNetNuke.Common.Globals.NavigateUrl() call. This obfuscates the need to select the correct portal Alias, portalSettings are other items which are handled by the base provider for you.

For more advanced usage, you can use data like page views, updates and other information your underlying module data may contain in the calculation of higher update frequencies for certain items, or higher priorities for some pages than others (ie, archive vs normal blog pages).

Step 7 : Compile your code - if it compiles OK, then copy the output Assembly file from your project to your website\bin directory.

Step 8 : Determine the Module Name of the module that is linked to the output. Do this by running the following Sql in your Host->Sql page:
select ModuleName from {databaseOwner}{objectQualifier}DesktopModules

Either pick the name out that you know is correct, or filter the list by looking at the FriendlyName column as well. This name is required to link the sitemap to your installed module.

NOTE: Some modules have multiple DesktopModules entries. Choose the one that correlates with the 'View' module of the project - the particular module type that is used to display the actual content.

Step 9 : Modify your web.config to include your new provider. You will need to locate the <searchEngineSitemap> section in the config file, and add a new entry for your new provider, using the moduleName value found in Step 8.

<add name="moduleName.SearchEngineSiteMapProvider" type="YourNamespace.YourModuleNameSiteMapProvider, YourModuleNameSiteMapProvider" defaultPagePriority="0.5" defaultPageUpdateFrequency="daily" />

If you created any extra attributes for the module, include them in the config entry.

Step 10 : Save the web.config file and you're all finished. Request the {domainname}/SearchEngineSitemap.aspx file and check the results for entries relating to your module.

Common Errors :
  • Module Sitemap is not loaded : You haven't got the correct moduleName value from the DesktopModules table, so the sitemap isn't found. The name must match exactly.
  • Module Sitemap is not loaded, and an commented error is in the sitemap : The type could not be loaded because your 'type' definition in your web.config file doesn't match. Double check the namespace, type and assembly name so that they are correct. A hint is to use the Object Browser in Visual Studio to double check these values.

Further debugging : You can request your sitemap with the ?smpDebug=true querystring, which will output more debugging messages (in the form of xml comments) in the sitemap. Example : {domainname}/SearchEngineSitemap.aspx?smpDebug=true - this will include more information about what the sitemap logic is doing while it is running.

More Advanced Methods

Sitemap Indexing

The sitemap base has the option to be split into individual sitemaps (the 'useSitemapIndex' option). When this is switched on, the SitePagesForTab call will have the range of Urls specified. This means the module provider will be called with the range of Urls, and any returned more than this will be discarded for that sitemap. If you have very large numbers of sitemap entries (>50,000 for your module) then you can implement this logic to break up your module entries across multiple sitemaps, or restrict the Urls to the top 50,000 most important Urls.

Getting Data out of modules

In many cases (and particularly if you don't have access to the source code of the module) the module will not provide a suitable way of returning a list of Urls for the content within the module. In these cases, it's recommended to write your own Data Provider and stored procedures to extract the data. Once you have written your own stored procedure, it becomes much easier to sort, group and restrict the number of sitemap entries being returned. See the Blog and Forum providers source code for examples on how to utiilise this type of data retrieval.

Packaging and Redistributing the Provider

If you have built a provider and you wish to package it along with your module, you can easily include the information in your DotNetNuke manifest file, or distribute the provider as a separate installation. You can use any of the example source code .dnn manifest files as a pattern to copy on how to have a third-party sitemap provider packaged into an installable DotNetNuke extension.

Including your Provider on this page

If you've built a provider and would like it hosted on this page, please get in contact. This codeplex project site is designed in order to provide a collection of sitemap providers built in this format.

Last edited Sep 14, 2012 at 4:28 AM by brucerchapman, version 1


No comments yet.