|
Article relates to
|
Sitefinity 3.2
|
|
Created by
|
Yasen Kiprov
|
HOW TO
Customize the sitemap in order to see only specific pages in navigation?
DESCRIPTION
The included navigation controls in Sitefinity (Site Menu, Site Panelbar, Site Tabstrip and Site Treeview) all share a common data source, representing the site structure.
The site structure information comes from a sitemap provider, which implements the SiteMapProvider class.
Every page is represented by a CmsSiteMapNode object, extending the System.Web.SiteMapNode class.
By default, Sitefinity uses the Telerik.Cms.Web.CmsSiteMapProvider to manage the pages that are included and shown in the site map.
There are several conditions that are checked before a page appears in the navigation controls:
First the “show in navigation” property is checked, and if it is set to false, the page is not even included in the sitemap.
Then the “anonymous access” property is checked. Only if it is set to allow, the page is shown in navigation.
Finally, if it is set to deny, roles and page permissions are checked for the current user. The page is shown only if the currently logged in user is granted the View permissions. For anonymous users the page is not visible.
SOLUTION
The solution is to override the provider functionality in order to customize page nodes.
The first checked page property - “show in navigation” - is not manageable because its purpose is to hide pages from navigation. However, the other two are processed in the IsAccessibleToUser method of the CmsSiteMapProvider class.
The following class alters the functionality provided by IsAccessibleToUser. If you use it, all users will see all pages in the navigation controls.
| using System; |
| using System.Web; |
| using Telerik.Cms.Web; |
| |
| /// <summary> |
| /// Custom site map provider that overrides the IsAccessibleToUser method. |
| /// </summary> |
| public class CustomSiteMapProvider : CmsSiteMapProvider |
| { |
| /// <param name="context">The context, from which current user is taken.</param> |
| /// <param name="node">The current page node for which the method decides to include it or not.</param> |
| public override bool IsAccessibleToUser(HttpContext context, SiteMapNode node) |
| { |
| // Always returns true - all pages will be included in the navigation. |
| return true; |
| |
| } |
| } |
| |
Furthermore, if you need only authenticated users to see all pages in the navigation, while not logged in users to see none of the pages, change “return true;” to:
| if (context.User.Identity.IsAuthenticated) |
| return true; |
| return false; |
| |
You could make a change only for one page, for instance “Registration”, while logic for all other pages remains unchanged. If you need to exclude “Registration” from the navigation only for authenticated users, but users that are not logged in to see it, use this code:
| if (context.User.Identity.IsAuthenticated == false |
| && node.Title.Equals("Registration", StringComparison.OrdinalIgnoreCase)) |
| return true; |
| return base.IsAccessibleToUser(context, node); |
Any further customizations, based on the current user and current page node are possible.
In order to use this provider instead of the default one, you should add the class to the App_Code folder and change the provider type in the web.config file:
| <siteMap defaultProvider="CmsSiteMapProvider" enabled="true"> |
| <providers> |
| <clear/> |
| <add name="CmsSiteMapProvider" description="Displays Cms Pages" type="CustomSiteMapProvider"/> |
| </providers> |
NOTE: Hiding pages in navigation does not mean they are not accessible for users. The pages are still accessible if you directly type their urls in the browser, they are just missing in navigation controls.
Enjoy :)