Advanced node visibility

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:
<siteMap defaultProvider="MvcSiteMapProvider" enabled="true"> 
  <providers> 
    <clear /> 
    <add name="MvcSiteMapProvider" 
         type="MvcSiteMapProvider.DefaultSiteMapProvider, MvcSiteMapProvider" 
         ...
         attributesToIgnore="visibility" 
         ...
         siteMapNodeVisibilityProvider="MvcSiteMapProvider.FilteredSiteMapNodeVisibilityProvider, MvcSiteMapProvider"
         /> 
  </providers> 
</siteMap>
  • 3. For every node, specify the visibility attribute. Here's an example:
<mvcSiteMapNode title="Administration" area="Admin" clickable="false" visibility="SiteMapPathHelper,!*" />

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.

Last edited Jul 23, 2010 at 8:56 AM by maartenba, version 1

Comments

Tweet Feb 9, 2012 at 12:44 PM 
jgoemat:
I had the same problem. This seems to work (with FilteredSiteMapNodeVisibilityProvider, anyway)...

{{
public static MvcHtmlString Menu(this HtmlHelper helper)
{
var menu = new StringBuilder();
foreach (SiteMapNode node in SiteMap.RootNode.ChildNodes)
{
if (node.GetType() == typeof(MvcSiteMapNode))
{
var mvcnode = (MvcSiteMapNode) node;
bool visible = mvcnode.VisibilityProvider.IsVisible(mvcnode, HttpContext.Current,
new Dictionary<string, object> { { "HtmlHelper", helper } });
if (visible)
{
menu.AppendFormat("<a href='{0}'>{1}</a>", node.Url, helper.Encode(node.Title));
}
}
}
return MvcHtmlString.Create(menu.ToString());
}
}}

jgoemat Nov 26, 2010 at 6:37 AM 
What is a SiteMapPathHelper? Is there any way to do this if I create my own menu and breadcrumbs? The Attributes on a node are not public so I can't access the visibility attribute...

MikeFoden Sep 13, 2010 at 5:32 AM 
It would be good if this was able to also be used within an Attribute within a controller.