Usman ur Rehman Ahmed's blog

Extending DNN by forking an intrinsic DNN provider

Dot Net Nuke (DNN) as a CMS is developed for expansibility and the core framework is designed to make this achievable. This post does discuss extensibility in detail. It is hoped that it will be found beneficial for analysts or technology advisors whom are considering DNN for porting their businesses on DNN for ease of administration.

It is more or less a practice while developing on top of DNN, not to alter the source code often regarded as following,

“DNN’s core will remain un-altered during the course of development for this project”

Then how do you exactly achieve extensibility if you don’t really change the core? DNN heavily utilize the concept of providers from data access to navigation. As a developer or an architect, if you are restricted by an intrinsic feature of DNN, what you can do is to develop on top of existing framework by forking an existing provider.

By forking we mean that you take the source code of that particular provider (since that is redistributable as being open source), duplicate that yet following the standard inheritance chain in set of classes and create a new provider project. Then you simply plug the new provider entry in the web.config file.

Here we will consider a simple case of forking DNN’s sitemap provider. We only want to filter the Urls listed in sitemap of which parent Tab (DNN’s pages are termed tabs) are of type Url. This is pretty simple and will explain the concept of forking.

At the time of this writing the latest version of DNN’s (5.6.2 beta) sitemap provider can be found at,

http://dotnetnuke.codeplex.com/SourceControl/changeset/view/58582#608945

Duplicate this class in your own provider project. To explain that DNN’s default language (VB) doesn’t limit the extensibility during forking process, I have done so in a C# project,

namespace DNN.Providers.SampleSitemapProvider

{

    public class TestSitemapProvider : DotNetNuke.Services.Sitemap.SitemapProvider

    {

         

The only change we will have to bring in the code of this file to filter the Urls as per our need will be in method,

   private SitemapUrl GetPageUrl(TabInfo objTab, string language)

      {

           

Just before the line that says,

            pageUrl.Priority = GetPriority(objTab);

place a method call,

            //Filter Url

            if (!CheckParentTabType(objTab))

            {

                return null;

            }

And introduce a private method in the very file,

        private bool CheckParentTabType(TabInfo objTab)

        {

            try

            {

                if (objTab != null)

                {

                    if (objTab.ParentId != -1)

                    {

                        TabController tabController = new TabController();

                        TabInfo parentTabInfo = tabController.GetTab(objTab.ParentId);

                        if (parentTabInfo != null)

                        {

                            if (parentTabInfo.TabType == TabType.Url)

                            {

                                return true;

                            }

                        }

                    }

             }

            catch (Exception ex)

            {

                DotNetNuke.Services.Exceptions.Exceptions.LogException(ex);

            }

            return false;

        }

That is all. Verify the build output path points to bin folder and bring following change in provider section for sitemap for this new provider to trigger when sitemap.aspx page is requested,

    <sitemap defaultProvider="coreSitemapProvider">

      <providers>

        <clear />

        <add name="coreSitemapProvider" type="DotNetNuke.SitemapProviders.CoreSitemapProvider, DotNetNuke.SitemapProviders.CoreSitemapProvider" providerPath="~\Providers\MembershipProviders\Sitemap\CoreSitemapProvider\" />

      </providers>

    </sitemap>

So we will only have to add a new node in this section as following,

        <add name="sampleSitemapProvider" type="DNN.Providers.SampleSitemapProvider.TestSitemapProvider, TKCarsites.Providers.SampleSitemapProvider" providerPath="~\Providers\MembershipProviders\Sitemap\CoreSitemapProvider\" />

And flip the default sitemap entry from

    <sitemap defaultProvider="coreSitemapProvider">

to

    <sitemap defaultProvider="SampleSitemapProvider">

For our sitemap to take effect. Off course for a production deployment this makes more sense to be performed using manifest file config section. The complete project is attached for quick review.

11
To Posterous, Love Metalab