Skip to content

Advanced Node Visibility

mawiseman edited this page Apr 2, 2012 · 3 revisions

In some situations, nodes should be visible in the breadcrumb trail but not in a complete sitemap. This can be solved using the concept of ISiteMapNodeVisibilityProvider, that can be specified globally for every node in the sitemap or granularly on a specific sitemap node.

It is possible to implement your own ISiteMapNodeVisibilityProvider, as is done in the sample application. There is also a standard FilteredSiteMapNodeVisibilityProvider, which filters sitemap node visibility based on the control that is currently rendering the sitemap node.

Using FilteredSiteMapNodeVisibilityProvider

In order to make use of FilteredSiteMapNodeVisibilityProvider, the following steps should be taken:

1 - Modify Web.config and set the attributesToIgnore attribute to contain "visibility", like so:

<siteMap defaultProvider="MvcSiteMapProvider" enabled="true"> 
  <providers> 
    <clear /> 
    <add name="MvcSiteMapProvider" 
         type="MvcSiteMapProvider.DefaultSiteMapProvider, MvcSiteMapProvider" 
         ...
         attributesToIgnore="visibility" 
         ...
         /> 
  </providers> 
</siteMap>

2 - If the *FilteredSiteMapNodeVisibilityProvider* should be used globally for all nodes in the sitemap, modify Web.config and set the siteMapNodeVisibilityProvider attribute to "MvcSiteMapProvider.FilteredSiteMapNodeVisibilityProvider, MvcSiteMapProvider". Here's an example: ```xml ```
3 - For every node, specify the visibility attribute. Here's an example: ```xml ```
The visibility attribute can contain a comma-separated list of controls in which the sitemap node should be rendered or not. These are processed left-to-right and can be inverted using an exclamation mark. Here's a break down of the above example:
Directive Meaning
SiteMapPathHelper The node is visible in the SiteMapPathHelper.
!* The node is invisible in any other control.

Note that an implicit * (The node is visible in any control) is added at the end of the list.

Creating a Custom SiteMapNodeVisibilityProvider

In order to create a custom SiteMapNodeVisibilityProvider, to following steps should be taken:

1 - Create a new class implementing ISiteMapNodeVisibilityProvider

using System.Collections.Generic;
using System.Web;
using MvcSiteMapProvider;
using MvcSiteMapProvider.Extensibility;

namespace MyCompany
{
    public class MyCustomVisibilityProvider : ISiteMapNodeVisibilityProvider
    {
        public bool IsVisible(SiteMapNode node, HttpContext context, IDictionary<string, object> sourceMetadata)
        {
            // Convert to MvcSiteMapNode
            var mvcNode = node as MvcSiteMapNode;
            if (mvcNode == null)
            {
                return true;
            }

            // Is a visibility attribute specified?
            string visibility = mvcNode["visibility"];
            if (string.IsNullOrEmpty(visibility))
            {
                return true;
            }
            visibility = visibility.Trim();
            
            //process visibility
            switch (visibility)
            {
                case "Condition1":
                    //...
                    return false;

                case "Condition2":
                    //...
                    return false;
            }

            return true;
        }
    }
}

2 - Modify Web.config and set the attributesToIgnore attribute to contain "visibility" and the siteMapNodeVisibilityProvider to contain your Visibility Provider namespace and assembly like so:

<siteMap defaultProvider="MvcSiteMapProvider" enabled="true"> 
  <providers> 
    <clear /> 
    <add name="MvcSiteMapProvider" 
         type="MvcSiteMapProvider.DefaultSiteMapProvider, MvcSiteMapProvider" 
         ...
         siteMapNodeVisibilityProvider="MyCompany.MyCustomVisibilityProvider, MyWebProject"          
         attributesToIgnore="visibility" 
         ...
         /> 
  </providers> 
</siteMap>

MyWebProject should be the name of the dll that is created by your MVC project

3 - For every node, specify the visibility attribute. Here's an example:

<mvcSiteMapNode title="Administration" area="Admin" visibility="Condition1" />
<mvcSiteMapNode title="Settings" area="Admin" visibility="Condition2" />