SharePoint Tip of the Day : Programmatically rollback to structural navigation in SharePoint 2013


Managed Navigation are the default choice when you create a publishing site in SharePoint 2013 but what do you need to do if you want to rollback programmatically to the old fashion structural navigation ?

The Navigation settings for each site are stored within the the property bag of the SPWeb and you can access it through

SPWeb.AllProperties[“_webnavigationsettings”] or through SharePoint Manager like showed hereunder

_webnavigationsettings

There is a new object WebNavigationSettings from the Microsoft.SharePoint.Publishing.Navigation dll that is responsible for managing (update & persist) the xml settings within the property bag.

Application pages like /_layouts/15/AreaNavigationSettings.aspx are adapting their UI based on these settings and by creating a new WebNavigationSettings with the current web as parameter to the constructor.

To rollback to the structural navigation, you can do all required configuration or use the built-in ResetToDefaults() method that will put back the PortalProvider instead of the Taxonomy one.

// Microsoft.SharePoint.Publishing.Navigation.WebNavigationSettings
public void ResetToDefaults()
{
    base.RequireNotFrozen();
    this.siteMapProviderSettingsByName.Clear();
    if (this.isRootWeb)
    {
        this.GlobalNavigation.Source = StandardNavigationSource.PortalProvider;
        this.CurrentNavigation.Source = StandardNavigationSource.PortalProvider;
    }
    else
    {
        this.GlobalNavigation.Source = (this.GlobalNavigation.InheritPortalSettingsFromParent ? StandardNavigationSource.InheritFromParentWeb : StandardNavigationSource.PortalProvider);
        this.CurrentNavigation.Source = (this.CurrentNavigation.InheritPortalSettingsFromParent ? StandardNavigationSource.InheritFromParentWeb : StandardNavigationSource.PortalProvider);
    }
    this.AddNewPagesToNavigation = true;
    this.CreateFriendlyUrlsForNewPages = true;
}

 

So in code, once you know it, it’s only a matter of doing

WebNavigationSettings webNavigationSettings = new WebNavigationSettings(rootWeb);
webNavigationSettings.ResetToDefaults(); // will rollback to PortalProvider
webNavigationSettings.Update();

To adapt the property bag and get the expected behaviour.

And if you’re wondering why it is the case by default, it is because the Portal Navigation properties feature which is part of the site definition of any publishing site (and stappled to a few others)  (Feature  Id= “541F5F57-C847-4e16-B59A-B31E90E6F9EA”) has a receiver that will do parse the feature properties and then always call the FriendlyUrlUtilities if the version is superior or equal to SharePoint 2013.

                if (publishingWeb.Web.Site.CompatibilityLevel >15)
                {
                    FriendlyUrlUtilities.ActivateManagedNavigation(publishingWeb.Web);
                }

And you guess it, that ActivateManagedNavigation will work with the WebNavigationSettings object and adapt it this time to support the Taxonomy Navigation.

_webnavigationsettings2

So if you’re stapling some feature with some receiver to rollback to the old way of working with navigation (and you should if you’re targeting a SharePoint 2013 Standard License !) make sure that you run after that receiver or execute it through PowerShell once the site is provisioned.

 

SharePoint Tip of the Day – Can’t find your custom site definition in SharePoint 2013 when creating your root variation label ?


As in previous SharePoint versions, whenever you create your root variation label, you’ll need to specify the template associated with all the labels.

Unfortunately the UI seems to only propose the Publishing Site (CMSPublishing#0) and the Publishing Site With Workflows (BlankInternet#2). While these two will fit most needs, I still find handy to have my own customized site definition, deriving from the OOTB ones that will only include the feature that I need and automatically do specific action upon provisioning.

01

So how can you add your own site definition to the list like in the image above ?Time to do a little bit of reflection to see how this administration page is working and let’s call ILSpy to the rescue !

The page is inheriting from Microsoft.SharePoint.Publishing.Internal.CodeBehind.VariationLabelPage

and will load available choices through its private method private SortedDictionary<string, string> PublishingTemplates which is getting the available templates from the site collection through GetCustomWebTemplates and filtering the results through VariationLabelPage.FindFilterCategory to only retain the ones which have a property FilterCategories with the value “PublishingSiteTemplate”…

02
03

Knowing that, it’s only a matter of adding that property to your webtemp entry and voilà, it’s now usable (do an IISReset to ensure the choices, loaded from SharePoint internal cache, are reloaded).

04

Hope it will help !