+1-888-365-2779
Try Now
More in this section

Forums / General Discussions / Need help with dual navigation

Need help with dual navigation

16 posts, 0 answered
  1. Marko
    Marko avatar
    148 posts
    Registered:
    30 Jul 2008
    09 Sep 2008
    Link to this post
    Hi all,

    I'm developing a site which will have dual navigation (two navigation menus, each for a set of pages).  I started organizing my pages like this:

    [SiteMap]
      --Home
         -----Page 1
         -----Page 2
         -----Page 3
         -----Page 4
         -----Page 5
         -----Page 6

    Let's say that navigation menu 1 will contain pages 1, 2, and 3, while navigation menu 2 will have pages 4, 5, and 6.  These navigation bars are part of the template, and need to be visible on every page.

    So, how can I achieve this best?  For now, I set the pages 4, 5, and 6 NOT to be shown in navigation, which takes care of my nav menu #1.  But then to show pages 4, 5, 6 I have to hardcode links to them in a Master page or something.  I can do that in the worst-case scenario (especially because for those pages, specifically, I don't need any speicial Javascript flyout menus or anything like that), but what else would I be able to do?  If I have to reorganize my sitemap a little bit to achieve this, that's OK, but I wanted all my breadcrumbs to show HOME --> [whatver page], so that's why I started the sitemap the way I did.  now if I could just have both navigation menus work via SiteMap or something like that, that would be neat.

    Any suggestions?
  2. Gabe Sumner
    Gabe Sumner avatar
    440 posts
    Registered:
    09 Sep 2007
    09 Sep 2008
    Link to this post

    Hey Marko,

    Please tell me if this would work;

    [SiteMap]
      -- Home
        ---- Group 1
            ------ Page 1
            ------ Page 2
            ------ Page 3
            ------ Page 4
        ---- Group 2
            ------ Page 5
            ------ Page 6
            ------ Page 7
            ------ Page 8

    Next, I'm going to recommend that you get a hold of the "Links" control from the Goondocks Sitefinity Controls:

    http://goondocks.com/projects/goondocks-sitefinity-controls.aspx

    You can then drag 2 instances of this control onto your Sitefinity page.  Associate one of these controls with the "Group 1" node and the other with the "Group 2" node.   Each control will dynamically display links to the children of these groups.

    This will impact your breadcrumbs (Home -> Group 1 -> Page 2), but this might be okay.  From what you're describing there is something that differentiates these links (that's why you want the links grouped differently).  It probably won’t be bad for this to be shown in the breadcrumbs.

    This is how I solved this issue with my own web sites.  However, I would like to get your feedback.  Does this work for you?  What issues do you see with this approach?

    Gabe Sumner

  3. Marko
    Marko avatar
    148 posts
    Registered:
    30 Jul 2008
    09 Sep 2008
    Link to this post
    Hi Gabe, thanks for replying!

    I have seen your Links control before [I've been reading your blog--thanks for all the good info, btw], but I don't think it would work in this case.  Part of the functionality I need from something like SiteMenu is the drop-down and flyout menus for the first group of pages (let's say for Page 1, 2, and 3).  I failed to mention this in my post above, but ONE of those two navigation bars (a.k.a. the main one) will need to show 3 levels of pages, sort of like this:

    [SiteMap]
      --Home
         -----Page 1
                
    -----SubPage X
                       -----SubSubPage A
                       -----SubSubPage B
                       -----SubSubPage C
                 -----SubPage Y
                 -----SubPage Z
                       -----SubSubPage A
                       -----SubSubPage B
             -----Page 2
                 -----SubPage X
                 -----SubPage Y
                 -----SubPage Z
             -----Page 3
                 -----SubPage X
                       -----SubSubPage A
                       -----SubSubPage B
                       -----SubSubPage C
                 -----SubPage Y
                 -----SubPage Z
         -----Page 4
         -----Page 5
         -----Page 6
        
    ...etc.

    This I already have working with a SiteMenu (and its settings).  However the only reason that pages 4, 5, and 6 are NOT showing up in that menu is because I have them set to "NO" in "Show in Navigation."  I think I would prefer to stick with SiteMenu, at least for the multi-level navigation bar, instead of having to re-invent something that Telerik did pretty well, already.

    Now, for the OTHER navigation bar, I *could* use your Links control, because I only need to show pages 4, 5, and 6 at THAT level (only siblings, I guess), without caring for how many child nodes are underneath each of those pages.  However, even if I go with the sitemap that you suggested, it wouldn't necessarily help me, because I would still need SiteMenu to display "Group 1", so how would I limit it to display Group 1, and NOT Group 2?

    By the way, you are right that there seems to be some natural separation between the two groups of pages, so dividing them into 2 groups makes sense.  I avoided doing that at first, because my breadcrumbs are starting to get kinda long, so I thought I should just put them at the same level.

    Hmmm....  Thinking... Thinking...
  4. Gabe Sumner
    Gabe Sumner avatar
    440 posts
    Registered:
    09 Sep 2007
    09 Sep 2008
    Link to this post
    Ah, got it.

    So really what you need is something exactly like the "Site Map" control, except with the ability to chose the "starting node".

    Let me play with this for a bit and see what I can do. 

    BTW, I now work for Telerik.  My first day was yesterday so I'm close to useless at this point, but I'm learning as quickly as possible.   :)

    Gabe
    ==============
  5. Marko
    Marko avatar
    148 posts
    Registered:
    30 Jul 2008
    09 Sep 2008
    Link to this post
    Hey, didn't even think about the StartingNode, but you're absolutely right--that's probably the key reason why I'm having trouble with this (the fact that SiteMenu starts from RootNode).

    Granted, I would still have to group the pages like you were suggesting, right? That still makes me somewhat worried about the number of items in breadcrumbs.  I still like the idea of having

     Home >> [whatever] >> [child of whatever]...

    But with the grouping in there, I might end up with

     Home >> [group 1] >> [whatever (child of group 1)] >> [child of whatever]...  which might be too long...
  6. Randel Bjorquist
    Randel Bjorquist avatar
    8 posts
    Registered:
    25 Jan 2008
    09 Sep 2008
    Link to this post
    Hey Gabe,

    If Marko is asking for what you've just said, cann't this be accomplished by setting the "StartingNodeOffset" property, located under "Navigation".  This can be a either a posative or negative number.
  7. Marko
    Marko avatar
    148 posts
    Registered:
    30 Jul 2008
    09 Sep 2008
    Link to this post
    Hi Randel.

    I could be wrong here, but isn't the StartingNodeOffset relative to the SiteMap root?  So, even if you set the offset = 2, for example, it only means that you are starting from 2 levels deeper than the sitemap root, but it will show ALL things at that level.

    In fact, that's how I'm currently controlling my Main Navigation menu.  It's only showing Page 1, 2, and 3 (and their child nodes, and each child's children nodes, in fly-out menus, ).  Because I'm using offset = 2, it means thatthings at the level 1 and [i.e. Home, in my case] and level 0 [SiteMap root] are not shown.  However, I have no way of showing pages that are to be in Navigation Menu #2. 

    --------------------------------------------
    Gabe, btw, congratulations on the new job!!!  It totally makes sense to give you an official Telerik position, after all the work you've done so far!  I'm a new Sitefinity user, only having been at this for few weeks now, but I have already seen your name come accross many threads here, not to mention your blog and custom controls!  Congrats! :-)
  8. Gabe Sumner
    Gabe Sumner avatar
    440 posts
    Registered:
    09 Sep 2007
    09 Sep 2008
    Link to this post

    Randel, great suggestion on the "StartingNodeOffset", although I believe Marko is correct; this setting is relative to the root or relative to the CurrentNode if "StartFromCurrentNode" is true.  I've never thought of putting negative numbers in this property though.  Good to know this works!

    For the existing Sitefinity Treeview control, we only have 2 starting node choices:

    1. Root
    2. Current Page

    In Marko's case, neither of these is a good option.  What we need is a way to pick a custom starting node.  I created a custom User Control that seems to accomplish this.  Here is what I did:

    Create ~/UserControls/CustomTreeView.ascx:

    <%@ Control Language="C#" AutoEventWireup="true" CodeFile="CustomTreeView.ascx.cs" Inherits="UserControls_CustomTreeView" %> 
    <%@ Register assembly="RadTreeView.Net2" namespace="Telerik.WebControls" tagprefix="rad" %> 
    <rad:RadTreeView ID="RadTreeView1" runat="server">  
    </rad:RadTreeView> 

     

    Create ~/UserControls/CustomerTreeView.ascx.cs

    using System;  
    using System.Data;  
    using System.Web;  
    using System.Web.UI;  
    using System.Web.UI.WebControls;  
     
    using Telerik.Cms;  
    using Telerik.Cms.Web;  
    using Telerik.Cms.Web.UI;  
     
    public partial class UserControls_CustomTreeView : System.Web.UI.UserControl  
    {  
        private Guid _startingnode = new Guid("00000000-0000-0000-0000-000000000000");  
     
        /// <summary>  
        /// The node to use as the root of our Site Tree.  
        /// </summary>  
        [WebEditor("Custom.Admin.WebEditors.PageIdWebEditor, App_Code")]  
        public Guid StartingNode  
        {  
            get 
            {  
                return _startingnode;  
            }  
            set 
            {  
                _startingnode = value;  
            }  
        }  
     
        protected void Page_Load(object sender, EventArgs e)  
        {  
            CmsSiteMapProvider ourMapProvider = (CmsSiteMapProvider)SiteMap.Provider;  
            SiteMapNodeCollection childnodes = new SiteMapNodeCollection();  
            string nodetitle;  
     
            // Sitefinity uses a different object type for the Root node.  We  
            // need to figure out whether we're dealing with the root node or not.  
            // Either way we need to get the title for our Parent Node and then a  
            // collection of the Parent Node's Children.  
            Guid RootNodeID = new Guid("00000000-0000-0000-0000-000000000000");  
     
            if (StartingNode == RootNodeID)  
            {  
                CmsRootSiteMapNode rootnode = (CmsRootSiteMapNode)ourMapProvider.RootNode;  
                childnodes = rootnode.ChildNodes;  
                nodetitle = "[Site Map]";  
                Response.Write(childnodes.Count);  
            }  
            else 
            {  
                CmsSiteMapNode node = (CmsSiteMapNode)ourMapProvider.FindSiteMapNodeFromKey(StartingNode.ToString());  
                if (node != null)  
                {  
                    nodetitle = node.CmsPage.Title;  
                    childnodes = node.ChildNodes;  
                }  
            }  
     
            // Bind our Site Map to the RadTreeView.  
            RadTreeView1.DataSource = childnodes;  
            RadTreeView1.DataBind();  
        }  
    }  
     

     

    Create ~/App_Code/Custom/Admin/WebEditors/PageIdEditor.cs

    using System;  
    using System.Collections.Generic;  
    using System.Text;  
    using Telerik.Cms.Web.UI;  
    using Telerik.WebControls;  
    using System.Web.UI;  
    using System.IO;  
    using System.Web.UI.WebControls;  
    using Telerik.Cms;  
    using Telerik.Cms.Web;  
     
    namespace Custom.Admin.WebEditors  
    {  
        /// <summary>  
        /// This is a Sitefinity WebEditor.  It is used while setting properties for  
        /// Sitefinity controls.  This Web Editor allows to browse your Sitefinity  
        /// SiteMap, select a node, and returns its associated Page Guid.  
        ///   
        /// This code was created by Pepi with Telerik.  Minor changes were made  
        /// by Gabe Sumner.  
        /// </summary>  
        public class PageIdWebEditor : WebUITypeEditor<Guid>  
        {  
            protected override HtmlTextWriterTag TagKey  
            {  
                get 
                {  
                    return HtmlTextWriterTag.Div;  
                }  
            }  
     
            public override Guid Value  
            {  
                get 
                {  
                    Guid pageId = Guid.Empty;  
     
                    if (this.container.Tree.SelectedNode != null)  
                        pageId = new Guid(this.container.Tree.SelectedNode.Value);  
     
                    if (pageId != Guid.Empty)  
                        return ((ICmsPage)manager.GetPage(pageId)).ID;  
     
                    return Guid.Empty;  
                }  
                set 
                {  
                }  
            }  
     
            public ITemplate ItemTemplate  
            {  
                get 
                {  
                    return this.itemTemplate;  
                }  
                set 
                {  
                    this.itemTemplate = value;  
                }  
            }  
     
            public string ItemTemplatePath  
            {  
                get 
                {  
                    string value = (string)this.ViewState["ItemTemplatePath"];  
                    return String.IsNullOrEmpty(value) ? "~/Sitefinity/Admin/ControlTemplates/Pages/SiteMapSelector.ascx" : value;  
                }  
                set 
                {  
                    this.ViewState["ItemTemplatePath"] = value;  
                }  
            }  
     
            public SiteMapContainer Container  
            {  
                get 
                {  
                    return this.container;  
                }  
            }  
     
            public RadTreeView TreeView  
            {  
                get 
                {  
                    return this.tree;  
                }  
            }  
     
            protected override void OnInit(EventArgs e)  
            {  
                base.OnInit(e);  
                this.manager = new CmsManager();  
            }  
     
            protected override void CreateChildControls()  
            {  
                this.Controls.Clear();  
     
                this.container = new SiteMapContainer(this);  
     
                if (this.itemTemplate == null)  
                {  
                    if (this.Page != null)  
                    {  
                        string path = this.ItemTemplatePath;  
                        if (File.Exists(this.Page.MapPath(path)))  
                            this.itemTemplate = this.Page.LoadTemplate(path);  
                        else 
                            this.itemTemplate = new DefaultTemplate();  
                    }  
                }  
                this.itemTemplate.InstantiateIn(this.container);  
     
                this.tree = this.container.Tree;  
                if (tree != null)  
                {  
                    tree.NodeExpand += new RadTreeView.RadTreeViewEventHandler(tree_NodeExpand);  
     
                    RadTreeNode root = new RadTreeNode();  
                    root.CssClass = "cmsRoot";  
                    root.CssClassOver = "cmsRootOver";  
                    root.CssClassSelect = "cmsRootSelect";  
                    root.Value = Guid.Empty.ToString();  
                    root.Text = "All Pages";  
                    root.Expanded = true;  
                    root.ToolTip = "";  
                    tree.Nodes.Add(root);  
                    this.LoadNodes(root);  
                }  
                this.Controls.Add(this.container);  
     
            }  
     
            private void LoadNodes(RadTreeNode root)  
            {  
                foreach (ICmsPage page in manager.GetPages(new Guid(root.Value)))  
                {  
                    RadTreeNode node = new RadTreeNode();  
                    node.Value = page.ID.ToString();  
                    node.Text = page.MenuName;  
                    node.ToolTip = page.MenuName;  
     
                    if (page.Pages.Count > 0)  
                    {  
                        node.ExpandMode = ExpandMode.ServerSide;  
                    }  
     
                    if (page.ID == UrlHelper.HomePageID)  
                    {  
                        node.CssClass = "cmsHomePageNode";  
                        node.CssClassOver = "cmsHomePageNodeOver";  
                        node.CssClassSelect = "cmsHomePageNodeSelect";  
                    }  
                    else if (page.PageType == CmsPageType.External)  
                    {  
                        node.CssClass = "cmsExternalPageNode";  
                        node.CssClassOver = "cmsExternalPageNodeOver";  
                        node.CssClassSelect = "cmsExternalPageNodeSelect";  
                    }  
                    else if (page.PageType == CmsPageType.Group)  
                    {  
                        node.CssClass = "cmsPageGroup";  
                        node.CssClassOver = "cmsPageGroupOver";  
                        node.CssClassSelect = "cmsPageGroupSelect";  
                    }  
                    root.Nodes.Add(node);  
                }  
            }  
     
            void tree_NodeExpand(object sender, RadTreeNodeEventArgs e)  
            {  
                this.LoadNodes(e.NodeClicked);  
            }  
     
            private SiteMapContainer container;  
            private ITemplate itemTemplate;  
            private CmsManager manager;  
            private RadTreeView tree;  
     
            private class DefaultTemplate : ITemplate  
            {  
                public void InstantiateIn(Control container)  
                {  
     
                }  
            }  
     
            public class SiteMapContainer : GenericContainer<PageIdWebEditor>  
            {  
                public SiteMapContainer(PageIdWebEditor owner)  
                    : base(owner)  
                {  
                }  
     
                public RadTreeView Tree  
                {  
                    get 
                    {  
                        if (this.tree == null)  
                            this.tree = base.FindRequiredControl<RadTreeView>();  
                        return this.tree;  
                    }  
                }  
     
     
                private RadTreeView tree;  
            }  
        }  
    }  
     

     

    Insert the following code into the <toolboxControls> section in your web.config file:

    <add name="Custom Treeview" section="Navigation" url="~/UserControls/CustomTreeView.ascx" /> 

    This new control can now be found in your Sitefinity "Navigation" tools.  Drag the new control onto your Sitefinity page and select a new "Starting Node".  That's it.

    Let me know if this doesn't work or if you have problems!!! 

    Gabe
    ===============

  9. Marko
    Marko avatar
    148 posts
    Registered:
    30 Jul 2008
    10 Sep 2008
    Link to this post
    Thanks Gabe.  I will try this out as soon as I get a chance.  I'm in the middle of few other things left to be done on our Sitefinity site.

    In the meantime, could you offer some thoughts (if you have any) about the potential breadcrumbs length issue, described in my previous post.

    Thanks,

    Marko
  10. Gabe Sumner
    Gabe Sumner avatar
    440 posts
    Registered:
    09 Sep 2007
    11 Sep 2008
    Link to this post
    Hi Marko,

    I don't have any great ideas for handling looooooong breadcrumbs.

    Brevity is probably going to be your best solution.  :)  The breadcrumbs are based on the "Menu Label" for the page.  Keep it short and then type a longer (more descriptive) title in the "Title" textbox.

    Beyond that, you're looking at chopping out text or using a really small font.  Both of these probably aren't the best solution.

    Let me know if you come up with a solution I've overlooked.  I would love to know it!

    Gabe Sumner
  11. Lyn
    Lyn avatar
    15 posts
    Registered:
    30 Apr 2008
    14 Oct 2008
    Link to this post
    Hi,

    Since upgrade to 3.5 this line in Gabe's PageIdEditor doesn't work:

    if (page.ID == UrlHelper.HomePageID)

    It appears that the property HomePageID seems to have been removed from Telerik.Cms.Web.UrlHelper

    Has anyone got any ideas where it has gone?

    Cheers,

    Seth
  12. Mike
    Mike avatar
    221 posts
    Registered:
    19 Aug 2008
    15 Oct 2008
    Link to this post
    I am having the same issue with this member of URLHelper class... It does not exist in 3.5... No changes have been made to the API reference either...

    Also would like the alternative...

    Thanks,

    Nugs
  13. Pepi
    Pepi avatar
    981 posts
    Registered:
    08 Dec 2016
    15 Oct 2008
    Link to this post
    Hi Marko,

    To achieve the required functionaility you should either use static menus or change the hierarchy of the SiteMap. In case you choose the second option, please refer to the following forum thread that provides a solution for the breadcrumb.

    Do let us know if you need any further assistance.

    Note that
    Sincerely yours,
    Pepi
    the Telerik team

    Check out Telerik Trainer, the state of the art learning tool for Telerik products.
  14. Jeremy Davey
    Jeremy Davey avatar
    1 posts
    Registered:
    06 Jul 2006
    17 Oct 2008
    Link to this post
    Gabe:

    Is something like this also possible with the Rad Site Menu?  We are working on a site that will have 3 different Site Menus - and this functionality is exaclty what's needed in these sorts of cases.

    Any Thoughts?


  15. David
    David avatar
    50 posts
    Registered:
    14 Jan 2009
    28 Jan 2009
    Link to this post
    Hello,

    I'm having the same problem as Marko, but I cannot change the sitemap from it's current orientation.

    For example, I have 7 pages located on the same level, and the client requires they remain that way.

    [SiteMap]
         --Home
         --About
         --Products
         --Services
         --Hours
         --Contact

         --Support

    Is there any way to have two site menus, one which lists Home, About, Products, and Services at the top of the page, while the other lists Hours, Contact, and Support below?


    Thank you in advance for your help.

    David
  16. Georgi
    Georgi avatar
    3583 posts
    Registered:
    28 Oct 2016
    02 Feb 2009
    Link to this post
    Hi David,

    This is possible, but in this case, you should either hardcode the menu links, or implement your logic to separate the items on some criteria. If you decide to implement something, you can use the OnDataBind method, and see what to include in the menu and what to skip.

    Greetings,
    Georgi
    the Telerik team

    Check out Telerik Trainer, the state of the art learning tool for Telerik products.
Register for webinar
16 posts, 0 answered