Sitemap issues
I know there was a thread on SP1 that was referring to issues with the sitemap. I think the issue is still there in 4.1. Here is the setup that is failing.
I created a brand new 4.1 site. I added one page and three subpages. I used the I created a brand new 4.1 site. I added one page and three subpages. I used the "Right Sidebar, Header, Footer" template for all pages. I then went to the "Right Sidebar, Header, Footer" template and added a Site Map Data Source control and set the starting node offset to 1. I then added a rad panel bar and set it's datasourceid property to the id of the Site Map Data Source. When viewing any page, the panel bar is not being populated.
Is there a fix for this?
I also decided to try and use the NavigationControl and set the type to vertical and then set the page display to "All sibling pages of currently opened page". I then navigated to my top level page and the navigation is still not showing.
Edit: the NavigationControl works. I just had to re-publish my pages for the template changes to apply. This was something that was figured out in another forum post. Shouldn't the cache for the pages be cleared if you update a template?
After some digging around, I found that the only way that I was able to get the RadPanelBar control to work was to implement it into the NavigationControl. I created a new class that inherited the IExpandableSiteMapControl interface and also inherited the RadPanelBar. I then added the appropriate methods that the interface require. After getting my control to compile, I then downloaded the NavigationControl.ascx from Reflector. This allowed me to edit the template and place my panel bar control in the conditional template that had a right side value of CustomNavigation. Using the new control, I was able to set the Sitemap properties I wanted and the panel bar finally worked.
I still think that we should be able to just drop the RadPanelBar and SiteMapDataSource controls on a page and hook the two together and it should work. So I still think that this is a bug, but have found a workaround for our situation. I guess if you wanted, you could replace the control for any of the ConditionalTemplate nodes.
I am guessing, but I would assume the reason that the SiteMapDataSource is not working is because of the incorrect provider? I was looking through the SiteMapDataSource to see if there was something that I could override to get this functionality. The only thing I could think of was the Provider. Looking at the code for the NavigationControl, it appears the control is using the standard SiteMapDataSource, but it is also setting the Provider. This is where the idea came from. Rather than re-creating the SiteMapDataSource and setting the Provider as is in the NavigationControl, I just decided to create a new SiteMap navigtion control which is what I did for the RadPanelBar.
Hello Richard Baugh,
I've attached a sample video showing my setup of SiteMap DataSource and RadpanelBar. Can you please try setting the SiteMap's property ShowStartingNode to False, instead of using StartingNodeOffset 1? Generally there should be no problem using the described functionality - please try it and make sure that the DataSourceID in RadPanelBar is set appropriately - this might be the case, as well. If the problems persist, or you are testing with a different use case scenario than the one I've used in the video, please write back.
Concerning the issue with templates not applying until you republish the page, please excuse us for the inconvenience - we have registered this behavior as a bug and are working on fixing it. You can track the bug status and vote for it in PITS on this URL.
Kind regards,
Boyan Barnev
the Telerik team
Thanks for the reply. We are using it in a different scenario. We are adding the RadPanelBar and SiteMapDataSource to a Page Template. So we need to set the StartingNodeOffset to 1 since we want it to only show the the navigation starting from the second level on. Your example is on a page so you can set the starting url.
With the workaround I posted about, I am using the NavigationControl and just changed out the ascx file with one that uses this new control derived from the RadPanelBar and the IExpandableSiteMapControl interface. When I add the NavigationControl to the page, I simply set the CustomLayoutTemplatePath to the ascx file, and then I set the StartingNodeOffset to 1. This works just fine, but if I try to add the SiteMapDataSource and RadPanelBar and set the SiteMapDataSource to StartingNodeOffset to 1, then I don't get any navigation.
As for the ShowStartingNode, it is set to false also. The problem is that we are adding this to a template and can't specify the StartingNodeUrl like you have on the page. Try moving your RadPanelBar and SiteMapDataSource to a Page Template and then set the ShowStartingNode to false, and the StartingNodeOffset to 1. Ideally you should get the same results as what is in your video, only the controls are on the template. Then it would allow you to add another top level section and the panel bar in the template would also work for the other section. From my original post, I stated that I tried this in an upgraded site and also on a fresh 4.1 and both failed to show the navigation when the controls combo was added to a template.
From what I can see, the only difference from the normal SiteMapDataSource and the SiteMapDataSource that is used in the NavigationControl, when set to CustomNavigation and no other settings except the StartingNodeOffset, is that the NavigationControl also sets the Provider of the SiteMapDataSource through the GetProvider which uses the SiteMapBase class that was mentioned in another post as a fix for getting the correct current page and such.
If I need to create a ticket and attach the files I can, but there really isn't much that I have done other than adding the RadPanelBar as the option for the CustomNavigation conditional rather than RadSiteMap that is in the Sitefinity build.
Hello Richard Baugh,
Thanks for getting back to me. Generally setting the StartingNodeOffset through the UI does not work properly (indeed due to the Provider not being set, as you correctly observed) . Please take a look at the attached sample control which uses RadPanelBar and SiteMapDataSource with StartingNodeOffset set to 1, and setting properly the SiteMapProvider through code. I've tested using this control on a page template and it renders fine when previewing/ viewing a page. There's some issue getting the SiteMapProvider in edit page mode, that's why the message "Object reference not set to an instance of an object.". Please try the provided control and tell me if it suits the desired functionality. I'll get back to you when I have updated information on the control displaying properly in page edit mode.
Presentation part:
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="SMDataSourceCustom.ascx.cs" Inherits="SitefinityWebApp.Controls.SMDataSourceCustom" %><asp:SiteMapDataSource runat="server" ID="SiteMapDataSource1" /><telerik:RadPanelBar runat="server" ID="PanelBar1" DataSourceID="SiteMapDataSource1" ></telerik:RadPanelBar>using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Web.UI;using System.Web.UI.WebControls;using Telerik.Sitefinity.Pages.Model;using Telerik.Sitefinity.Web;namespace SitefinityWebApp.Controls public partial class SMDataSourceCustom : System.Web.UI.UserControl protected void Page_Load(object sender, EventArgs e) SiteMapDataSource1.StartingNodeOffset = 1; protected override void OnInit(EventArgs e) SiteMapDataSource1.Provider = SiteMapBase.GetCurrentProvider(); base.OnInit(e); Thanks for the response. As I mentioned before, I altered the template that is normally used for the Navigation control.
NavigationControl.ascx
<%@ Control Language="C#" %><%@ Register Assembly="Telerik.Sitefinity" Namespace="Telerik.Sitefinity.Web.UI" TagPrefix="sf" %><%@ Register Assembly="Telerik.Sitefinity" Namespace="Telerik.Sitefinity.Web.UI.NavigationControls.SiteMapNavigations" TagPrefix="navcontrols" %><%@ Register Assembly="SitefinityWebApp" Namespace="SitefinityWebApp.Widgets.Navigation" TagPrefix="navcontrols" %><%@ Register Assembly="Telerik.Web.UI" Namespace="Telerik.Web.UI" TagPrefix="telerik" %><sf:ConditionalTemplateContainer ID="conditionalTemplate" runat="server"> <Templates> <sf:ConditionalTemplate ID="ConditionalTemplate1" Left="NavigationMode" Operator="Equal" Right="HorizontalSimple" runat="server"> <navcontrols:SiteMapNavigationTabStrip ID="siteMapControl_horizontalsimple" runat="server" Skin="Sitefinity"> </navcontrols:SiteMapNavigationTabStrip> </sf:ConditionalTemplate> <sf:ConditionalTemplate ID="ConditionalTemplate2" Left="NavigationMode" Operator="Equal" Right="HorizontalDropDownMenu" runat="server"> <navcontrols:SiteMapNavigationMenu ID="siteMapControl_horizontaldropdownmenu" runat="server" Skin="Sitefinity" /> </sf:ConditionalTemplate> <sf:ConditionalTemplate ID="ConditionalTemplate3" Left="NavigationMode" Operator="Equal" Right="HorizontalTabs" runat="server"> <navcontrols:SiteMapNavigationTabStrip ID="siteMapControl_horizontaltabs" runat="server" Skin="Sitefinity"> </navcontrols:SiteMapNavigationTabStrip> </sf:ConditionalTemplate> <sf:ConditionalTemplate ID="ConditionalTemplate4" Left="NavigationMode" Operator="Equal" Right="VerticalSimple" runat="server"> <navcontrols:SiteMapNavigationTabStrip ID="siteMapControl_verticalsimple" runat="server" Orientation="VerticalLeft" MaxDataBindDepth="1" Skin="Sitefinity"> </navcontrols:SiteMapNavigationTabStrip> </sf:ConditionalTemplate> <sf:ConditionalTemplate ID="ConditionalTemplate5" Left="NavigationMode" Operator="Equal" Right="SiteMapInColumns" runat="server"> <navcontrols:SitemapNavigationSiteMapControl ID="siteMapControl_sitemapincolumns" runat="server" MaxDataBindDepth="2" Skin="Sitefinity"> <LevelSettings> <telerik:SiteMapLevelSetting Level="0"> <ListLayout RepeatDirection="Vertical" RepeatColumns="10" /> </telerik:SiteMapLevelSetting> </LevelSettings> </navcontrols:SitemapNavigationSiteMapControl> </sf:ConditionalTemplate> <sf:ConditionalTemplate ID="ConditionalTemplate6" Left="NavigationMode" Operator="Equal" Right="SiteMapInRows" runat="server"> <navcontrols:SitemapNavigationSiteMapControl ID="siteMapControl_sitemapinrows" runat="server" MaxDataBindDepth="2" Skin="Sitefinity"> <LevelSettings> <telerik:SiteMapLevelSetting> <ListLayout RepeatColumns="1" AlignRows="true" /> </telerik:SiteMapLevelSetting> <telerik:SiteMapLevelSetting Layout="Flow" SeparatorText="┊" /> </LevelSettings> </navcontrols:SitemapNavigationSiteMapControl> </sf:ConditionalTemplate> <sf:ConditionalTemplate ID="ConditionalTemplate7" Left="NavigationMode" Operator="Equal" Right="CustomNavigation" runat="server"> <navcontrols:SiteMapNavigationPanelBar ID="siteMapControl_customnavigation" runat="server" Skin="Sitefinity" /> </sf:ConditionalTemplate> <sf:ConditionalTemplate ID="ConditionalTemplate8" Left="NavigationMode" Operator="Equal" Right="VerticalTree" runat="server"> <navcontrols:SiteMapNavigationTreeView runat="server" id="siteMapControl_verticaltree" Skin="Sitefinity"> </navcontrols:SiteMapNavigationTreeView> </sf:ConditionalTemplate> </Templates></sf:ConditionalTemplateContainer><script type="text/javascript"> function radMenuOnClick(sender, args) var state = args.get_item().get_attributes().getAttribute("ExpandOnClick"); args.get_item().get_attributes().setAttribute("ExpandOnClick", "true") args.get_item().open(); function radMenuOnOpening(sender, args) var state = args.get_item().get_attributes().getAttribute("ExpandOnClick"); if (state != "true") args.set_cancel(true); args.get_item().get_attributes().setAttribute("ExpandOnClick", "false") </script>using System;using System.Collections.Generic;using System.Linq;using System.Web;using Telerik.Sitefinity.Web.UI.NavigationControls;using Telerik.Web.UI;using System.Web.UI.WebControls;using Telerik.Sitefinity.Web;namespace SitefinityWebApp.Widgets.Navigation public class SiteMapNavigationPanelBar : RadPanelBar, IExpandableSiteMapControl #region Private Variables private bool _allowCollapsing = false; private bool _showExpanded = true; private int _levelsToExpand = 0; private NavigationAction _navigationAction = NavigationAction.OnClick; private string _currentPageUrl = string.Empty; #endregion #region Properties public bool AllowCollapsing get return this._allowCollapsing; set this._allowCollapsing = value; public string CurrentPageURL get return this._currentPageUrl; set this._currentPageUrl = value; public int LevelsToExpand get return this._levelsToExpand; set this._levelsToExpand = value; public NavigationAction NavigationAction get return this._navigationAction; set this._navigationAction = value; public bool ShowExpanded get return this._showExpanded; set this._showExpanded = value; #endregion protected override void OnInit(EventArgs e) base.OnInit(e); if (!this.AllowCollapsing) base.OnClientItemCollapse = "function(sender, eventArgs) eventArgs.set_cancel(true);"; base.ItemDataBound += new RadPanelBarEventHandler(this.SiteMapNavigationPanelBar_ItemDataBound); protected override void OnPreRender(EventArgs e) string currentUrl = SiteMapBase.GetCurrentNode().Url; foreach (RadPanelItem item in base.GetAllItems()) if (currentUrl.Equals(item.NavigateUrl, StringComparison.OrdinalIgnoreCase)) item.Selected = true; item.Expanded = true; item.ExpandParentItems(); break; base.OnPreRender(e); void SiteMapNavigationPanelBar_ItemDataBound(object sender, RadPanelBarEventArgs e) SetNavigationItemTarget(e.Item); internal void SetNavigationItemTarget(NavigationItem item) ISitefinitySiteMapNode dataItem = item.DataItem as ISitefinitySiteMapNode; if (dataItem != null) string[] values = dataItem.Attributes.GetValues("target"); if ((values != null) && (values.Length == 1)) item.Target = values[0]; Hi Richard Baugh,
We really appreciate your help on the forums, thanks a lot for the time spent sharing this information witheveryone while we are working on delivering a solution for the issue at hand. It's great to have customers actively participate sharing their solutions in this community resource, once again thank you.
All the best,
Boyan Barnev
the Telerik team
Hi Richard-
In your solution where did you set the StartingNodeOffset to 1? Is it in the Advanced settings of the navigation control? I couldn't find that setting.
Thanks a bunch!
Brett
Hi Brett Winklesky,
I have replied to you in the support thread you have opened, you can check my response there. For your convenience I'm pasting my reply below:
"You should set the StartingNodeOffset in the SiteMapDataSource settings and then provide the ID of the SiteMapDataSource control as DataSource ID to a suitable RadControl (e.g. RadTreeView, RadMenu, RadTabStrip etc.)" If you need any additional information, please let us know.
Best wishes,
Boyan Barnev
the Telerik team
Dear Boyan
As you can see many are looking for the panel bar as a secondary navigation option.
Is there any change you can take all the code from the community programmers and have a panelbar solution build in sooner then Q2?
Markus
Brett,
I forgot that I altered the NavigationControl also. Below is the code that I am using as my navigation control.
using System;using System.Collections.Generic;using System.Globalization;using System.Linq;using System.Web;using System.Web.UI;using System.Web.UI.WebControls;using Telerik.Sitefinity;using Telerik.Sitefinity.Abstractions;using Telerik.Sitefinity.Localization;using Telerik.Sitefinity.Localization.UrlLocalizationStrategies;using Telerik.Sitefinity.Modules.Pages;using Telerik.Sitefinity.Pages.Model;using Telerik.Sitefinity.Services;using Telerik.Sitefinity.Web;using Telerik.Sitefinity.Web.UI;using Telerik.Sitefinity.Web.UI.NavigationControls;using Telerik.Sitefinity.Web.UI.Templates;using Telerik.Web;namespace SitefinityWebApp.Widgets.Navigation public class NavigationalControl : Telerik.Sitefinity.Web.UI.NavigationControls.NavigationControl #region Private Variables private BaseDataBoundControl _currentNavigationControl; private bool _showChildControls = false; private bool _showStartingNode = false; private int _startingNodeOffset = 0; private SiteMapDataSource _currentSiteMapDataSource; private SiteMapProvider _provider; private string _startingNodeResolvedUrl = string.Empty; #endregion #region Public Properties public bool ShowChildPages get return this._showChildControls; set this._showChildControls = value; public bool ShowStartingNode get return this._showStartingNode; set this._showStartingNode = value; public int StartingNodeOffset get return this._startingNodeOffset; set this._startingNodeOffset = value; internal virtual BaseDataBoundControl CurrentNavigationControl get return this._currentNavigationControl; set this._currentNavigationControl = value; protected override string LayoutTemplateName get return "SitefinityWebApp.Resources.Templates.PublicControls.NavigationControl.ascx"; #endregion protected override void InitializeControls(Telerik.Sitefinity.Web.UI.GenericContainer container) this.InitializeCurrentNavigationControl(); this.InitializeSiteMapDataSource(); this.SetControlSettings(); private void InitializeCurrentNavigationControl() this.CurrentNavigationControl = this.Container.GetControl<BaseDataBoundControl>(); if (this.CurrentNavigationControl == null) throw new ArgumentException("Unable to find a BaseDataBoundControl derived control in the template"); internal virtual SiteMapProvider GetProvider() if (this._provider == null) try if (string.IsNullOrEmpty(this.SiteMapProviderName)) this._provider = SiteMapBase.GetSiteMapProvider("FrontendSiteMap"); ((SitefinitySiteMap)this._provider).FallbackUrls.Add(this.StartingNodeResolvedUrl); else this._provider = SiteMapBase.GetSiteMapProvider(this.SiteMapProviderName); catch (Exception) this._provider = null; return this._provider; internal virtual string StartingNodeResolvedUrl get if ((this._startingNodeResolvedUrl == null) && this.StartingNodeUrl.IsGuid()) SiteMapProvider provider = this.GetProvider(); if (provider != null) PageSiteNode node = provider.FindSiteMapNodeFromKey(this.StartingNodeUrl) as PageSiteNode; if (node == null) return null; string url = node.GetUrl(CultureInfo.CurrentUICulture, true); if (ObjectFactory.Resolve<UrlLocalizationService>().UnResolveUrl(url) == "~/") return null; url = url.Replace("~", ""); this._startingNodeResolvedUrl = url; return this._startingNodeResolvedUrl; internal void InitializeSiteMapDataSource() this._currentSiteMapDataSource = new SiteMapDataSource(); this._currentSiteMapDataSource.Provider = this.GetProvider(); this._currentSiteMapDataSource.ShowStartingNode = this.ShowStartingNode; switch (this.SelectionMode) case PageSelectionModes.SelectedPageChildren: string startingNodeResolvedUrl = this.StartingNodeResolvedUrl; if (startingNodeResolvedUrl == null) this._currentSiteMapDataSource.StartingNodeUrl = ""; break; this._currentSiteMapDataSource.StartingNodeUrl = startingNodeResolvedUrl; break; case PageSelectionModes.SelectedPages: List<SiteMapNode> list = new List<SiteMapNode>(); SiteMapNodeCollection collection = new SiteMapNodeCollection(); foreach (SelectedPage page in this.CustomSelectedPagesInternal) SiteMapNode node = null; if (page.IsExternal) node = new SiteMapNode(this._currentSiteMapDataSource.Provider, "ext", page.Url, page.Title); else node = this._currentSiteMapDataSource.Provider.FindSiteMapNodeFromKey(page.Id); if (node != null) list.Add(node); collection.Add(node); if (this.ShowChildPages) this.CurrentNavigationControl.DataSource = collection; else this.CurrentNavigationControl.DataSource = list; return; case PageSelectionModes.CurrentPageChildren: this._currentSiteMapDataSource.StartFromCurrentNode = true; break; case PageSelectionModes.CurrentPageSiblings: this._currentSiteMapDataSource.StartFromCurrentNode = true; this._currentSiteMapDataSource.StartingNodeOffset = -1; break; default: this._currentSiteMapDataSource.StartingNodeOffset = this.StartingNodeOffset; break; this.CurrentNavigationControl.DataSource = this._currentSiteMapDataSource; internal void SetControlSettings() Predicate<string> match = null; if (this.CurrentNavigationControl is IExpandableSiteMapControl) IExpandableSiteMapControl currentNavigationControl = (IExpandableSiteMapControl)this.CurrentNavigationControl; currentNavigationControl.AllowCollapsing = this.AllowCollapsing; currentNavigationControl.LevelsToExpand = this.LevelsToExpand; if (this.MaxDataBindDepth != 0) currentNavigationControl.MaxDataBindDepth = this.MaxDataBindDepth; currentNavigationControl.NavigationAction = this.NavigationAction; currentNavigationControl.ShowExpanded = this.ShowExpanded; if (this._currentSiteMapDataSource != null) SiteMapNode currentNode = this._currentSiteMapDataSource.Provider.CurrentNode; if (currentNode != null) currentNavigationControl.CurrentPageURL = currentNode.Url; if (!string.IsNullOrEmpty(this.Skin)) ISkinnableControl control2 = this.CurrentNavigationControl as ISkinnableControl; if (control2 != null) if (match == null) match = delegate(string name) return name == this.Skin; ; if (control2.GetEmbeddedSkinNames().Exists(match)) control2.EnableEmbeddedSkins = true; else control2.EnableEmbeddedSkins = false; control2.Skin = this.Skin; protected override void OnPreRender(EventArgs e) //base.OnPreRender(e); PageManager.ConfigureScriptManager(this.Page, ScriptRef.JQuery | ScriptRef.JQueryValidate | ScriptRef.MicrosoftAjaxWebForms | ScriptRef.MicrosoftAjaxAdoNet | ScriptRef.MicrosoftAjax | ScriptRef.MicrosoftAjaxTemplates); if (this._currentSiteMapDataSource != null) ((SiteMapBase)this._currentSiteMapDataSource.Provider).IsNodeAccessible += new EventHandler<IsAccessibleArgs>(this.NavigationControl_IsNodeAccessible); try this.CurrentNavigationControl.DataBind(); catch (ArgumentException exception) if (this.SelectionMode != PageSelectionModes.SelectedPageChildren) throw exception; if (this.IsDesignMode()) Literal child = new Literal(); child.Text = Res.Get<Labels>().StartingPageUnpublished; this.Controls.Add(child); finally ((SiteMapBase)this._currentSiteMapDataSource.Provider).IsNodeAccessible -= new EventHandler<IsAccessibleArgs>(this.NavigationControl_IsNodeAccessible); internal void NavigationControl_IsNodeAccessible(object sender, IsAccessibleArgs e) if ((this._currentSiteMapDataSource.StartingNodeUrl == e.Node.Url.Replace("~/", "")) && !string.IsNullOrEmpty(e.Node.Title)) e.IsAccessible = true; else PageSiteNode node = e.Node as PageSiteNode; if (node == null) throw new NotSupportedException("The supported types are 'TaxonSiteNode' or 'PageSiteNode'."); if ((!node.ShowInNavigation || (!node.IsGroupPage && node.Hidden)) || (string.IsNullOrEmpty(node.Title) && (node.Id != SiteInitializer.FrontendRootNodeId))) e.IsAccessible = false; else if (node.IsGroupPage && (node.ChildNodes.Count < 1)) e.IsAccessible = false; else e.IsAccessible = true; ?xml version="1.0" encoding="utf-8"?><toolboxesConfig xmlns:config="urn:telerik:sitefinity:configuration" xmlns:type="urn:telerik:sitefinity:configuration:type" config:version="4.0.1098.0"> <toolboxes> <toolbox name="PageControls"> <sections> <add name="NavigationControlsSection"> <tools> <add type="SitefinityWebApp.Widgets.Navigation.NavigationalControl, SitefinityWebApp" name="Navigation" /> </tools> </add> </sections> </toolbox> </toolboxes></toolboxesConfig>