I’ve had a good look through a load of MS documentation only to find a tree view like structure to the use of sitemaps. I don’t suppose anyone’s aware of how it’s possible to have a folder-like structure for sitemap navigation? Take for example a structure as follows
Home About Me.aspx MyFamily.aspx MyPets.aspx Contact Telephone.aspx Email.aspx Disclaimer.aspx
The ‘About’ and ‘Contact’ would be folders, but the sitemap is never hierarchical on a single page. So, I would have my root page with two menu items, one would be ‘Home’ which acts like a folder to drill down into the about and contact menus, and the other is a link to the page for the disclaimer. I want to be able to click on Home which will reload the menu with the links for ‘About’ and ‘Contact’ and hide ‘Home’ and ‘Disclaimer’ altogether.
Home > Disclaimer
Then click on home and you would get
About > Contact >
Then when clicking on about you’d get
Me My Family My Pets
Every menu would have an ‘up’ menu to come back out a folder.
I can’t see there being an easy solution, but at the moment we use static html pages that are in different folders all over our web application. This is something that needs changing as you can well imagine.
Any ideas?
EDIT
I’ve had to come up with a VB.NET solution
<script runat='server'> Private Function GetSecondaryNavItems() As String Dim sRet As String = '' Dim oCurrNode As System.Web.SiteMapNode = Nothing Dim oCurrParentNode As System.Web.SiteMapNode = Nothing 'Dim sCurrPage As String = GetURL(Request.ServerVariables('SCRIPT_NAME').ToLower()) Dim sCurrPage As String = GetURL(HttpContext.Current.Request.ServerVariables('SCRIPT_NAME').ToLower()) oCurrNode = GetCurrentNode(sCurrPage, SiteMap.RootNode) If Not oCurrNode Is Nothing Then oCurrParentNode = oCurrNode.ParentNode End If If Not oCurrParentNode Is Nothing Then If Not oCurrParentNode Is SiteMap.RootNode Then sRet += 'Parent Folder Link' If Not oCurrNode Is Nothing Then For Each oChild As SiteMapNode In oCurrParentNode.ChildNodes sRet += 'Link for child' Next End If End If End If Return sRet End Function Private Function GetURL(ByVal fullURL As String) As String Return fullURL.Substring(fullURL.LastIndexOf('/')) End Function Private Function GetCurrentNode(ByVal _sCurrentPageURL As String, ByVal _oNode As SiteMapNode) As SiteMapNode Dim oNodeRet As SiteMapNode = Nothing For Each oNodeCheck As SiteMapNode In _oNode.ChildNodes If oNodeCheck.HasChildNodes = True Then oNodeRet = GetCurrentNode(_sCurrentPageURL, oNodeCheck) End If If oNodeRet Is Nothing Then Exit For End If Dim sURL As String = oNodeCheck.Url.ToLower() Dim iPos As Integer = sURL.IndexOf('?') If iPos > 0 Then sURL = sURL.Substring(0, iPos) End If iPos = sURL.LastIndexOf('/') If iPos > 0 Then sURL = sURL.Substring(iPos) End If If sURL = _sCurrentPageURL Then oNodeRet = oNodeCheck Exit For End If Next Return oNodeRet End Function </script>
This is in the master page file directly (temporary, I’ll place it in the code behind model later).
I’ve then got this in the body
<div id='sidebar'> <%= GetSecondaryNavItems() %> </div>
Again, temporarily just to test. It doesn’t actually output anything but then I’m thinking my GetURL definition is incorrect. I was assuming it was just getting the actual file? I could be very wrong though 🙂
EDIT EDIT: For some reason I’m not getting any output, so I thought it was my sitemap. I’ll need to debug it but I’m remoting in at the moment so it’s quite slow 😉
<?xml version='1.0' encoding='utf-8' ?> <siteMap xmlns='http://schemas.microsoft.com/AspNet/SiteMap-File-1.0' > <siteMapNode url='Accounts/Default.aspx' title='Accounts' description='Accounts'> <siteMapNode url='Accounts/Test.aspx' title='Client Balances' description='Client Balances'> <siteMapNode url='Hello.aspx' title='Hello' description='rarar' /> <siteMapNode url='Hiya.aspx' title='Hiya' description='rarar' /> </siteMapNode> <siteMapNode url='Test.aspx' title='Test' description='rarar' /> </siteMapNode> </siteMap>
Here’s the example sitemap.
You could still use the Sitemap.sitemap file to control your navigation, but you wouldn’t use any of the built-in controls in asp.net to achieve this. I just did almost this very thing on a site I just finished.
Make all of your pages inherit from a base page class (or use master pages, either way you’ll only have 1 copy of your code.)
Create a div or span on each page, named something appropriate (divNav or spnNav or whatever).
In your base page, on page load, loop through all the sitemap nodes to find the current page’s node. This needs to be a recursive call.
Once you have the current node, get its parent.
Add a link (the ‘up menu to come back out a folder’ as you called it).
Then do a foreach(SiteMapNode in parent.ChildNodes)
Add a link for each of the children.
So, our main call, that we called on every page load, was like this:
I have to tell you that the code above is part copied and part freehanded by me. But this should give you a good start, I would think.
EDIT: So sorry! Here is the GetURL proc…