I’ve got a master page which has a function in it called GetSiteMap(), this function is used to custom render a sitemap based on the current location. My problem is that in MVC you don’t have the code behind model thus not exposing that kind of functionality.
What’s the correct way to do it? Should I have a master page controller of some sort with that function defined in it?
Public Function GetSitemap() As String
Dim s As New SiteNavigation
Dim siteMapNodeCollection As SiteMapNodeCollection
If Not SiteMap.CurrentNode.Equals(SiteMap.RootNode) Then
If Not SiteMap.CurrentNode.HasChildNodes Then
' otherwise it'll go to the pseudo-current directory, which is wrong
Dim parentNode As SiteMapNode = SiteMap.CurrentNode.ParentNode.ParentNode
s.AddBackLink(parentNode.Url, parentNode.Title)
Else
Dim parentNode As SiteMapNode = SiteMap.CurrentNode.ParentNode
s.AddBackLink(parentNode.Url, parentNode.Title)
End If
End If
If Not SiteMap.CurrentNode.HasChildNodes Then
siteMapNodeCollection = SiteMap.CurrentNode.ParentNode.ChildNodes
Else
siteMapNodeCollection = SiteMap.CurrentNode.ChildNodes
End If
For Each siteMapNode As SiteMapNode In siteMapNodeCollection
GenerateLinks(siteMapNode, s)
Next
Return s.GetSiteNavigation()
End Function
Private Sub GenerateLinks(ByRef siteMapNode As SiteMapNode, ByRef siteNavigation As SiteNavigation)
If siteMapNode.Url.Length = 0 And siteMapNode.Description = "separator" Then
siteNavigation.AddSeparator()
ElseIf siteMapNode.Url.Length = 0 And siteMapNode.Description = "heading" Then
siteNavigation.AddHeading(siteMapNode.Title)
Else
siteNavigation.AddLink(siteMapNode.Url, siteMapNode.Description, siteMapNode.Title, siteMapNode.HasChildNodes)
End If
End Sub
Sorry, this is what I meant. I wrote this very quickly the other day so it’s not perfect, but for now it does the job. I’m using sitemap and giving certain elements no URL and instead a description such as “separator” to indicate that the <li> element is rendered in a different way (a different class is applied to this HTML element).
Since the site map is customizable based on the user’s location, I’m going to assume that you are talking about generating a user interface element, not a search engine mapping. Generating a sitemap for search engine consumption is probably best done off-line and simply updated periodically.
To generate the user interface I would consider using a ViewUserControl and rendering it as a partial in whatever pages you need. The ViewUserControl will make it much easier to create and maintain the mark up associated with it. It will also be available to any view (and can be included on your MasterPage) that needs it. As @Marc Gravell suggests, the data for it can be generated using an ActionFilter. It would probably be easiest, though, if the control is ubiquitous to create a base controller from which your controllers can derive and override OnActionExecuted in the base controller. You can detect when a ViewResult has been generated, then create and assign to ViewData the data for the sitemap control.
Base Controller:
MasterPage/View
ViewUserControl