1

I have been looking around but I didn't find an answer for my problem.

I would like a menu like this :

  1. Home
  2. Admnistration (Not clickable)
    • Personnel
    • Holiday

When I click the Personnel-item I would like to show the following :

  1. Home
  2. Admnistration
    • Personnel
      • Create New

When I click the Home-item, I go back to the index-page showing the first menu. Clicking the Holiday-item would show a menu like this:

  1. Home
  2. Admnistration
    • Holidays
      • Create New

My views are in one project and my controllers are in a different project. I can't seem to get it to work.

This is my sitemap:

<?xml version="1.0" encoding="utf-8" ?><mvcSiteMap xmlns="http://mvcsitemap.codeplex.com/schemas/MvcSiteMap-File-3.0" enableLocalization="true">
<mvcSiteMapNode title="Home" controller="Home" action="Index">
    <mvcSiteMapNode title="Administration" clickable="false">
        <mvcSiteMapNode title="Employee" controller="Personnel" action="Index">
            <mvcSiteMapNode title="New Employee" controller="Personnel" action="Create"/>
        </mvcSiteMapNode>
        <mvcSiteMapNode title="Holiday" controller="Holidays" action="Index">
            <mvcSiteMapNode title="New Holiday" controller="Holidays" action="HolidayNew"/>
        </mvcSiteMapNode>
    </mvcSiteMapNode>
</mvcSiteMapNode>

My web.config:

<siteMap defaultProvider="MvcSiteMapProvider" enabled="true">
      <providers>
        <clear />
        <add name="MvcSiteMapProvider" 
             type="MvcSiteMapProvider.DefaultSiteMapProvider, MvcSiteMapProvider" 
             siteMapFile="~/Mvc.Sitemap" 
             securityTrimmingEnabled="true" cacheDuration="5" enableLocalization="true" 
             scanAssembliesForSiteMapNodes="true" includeAssembliesForScan="" 
             excludeAssembliesForScan="" 
             nodeKeyGenerator="MvcSiteMapProvider.DefaultNodeKeyGenerator, MvcSiteMapProvider" 
             controllerTypeResolver="MvcSiteMapProvider.DefaultControllerTypeResolver, MvcSiteMapProvider" 
             actionMethodParameterResolver="MvcSiteMapProvider.DefaultActionMethodParameterResolver, MvcSiteMapProvider" 
             aclModule="MvcSiteMapProvider.DefaultAclModule, MvcSiteMapProvider" 
             siteMapNodeUrlResolver="MvcSiteMapProvider.DefaultSiteMapNodeUrlResolver, MvcSiteMapProvider" 
             siteMapNodeVisibilityProvider="MvcSiteMapProvider.DefaultSiteMapNodeVisibilityProvider, MvcSiteMapProvider" 
             siteMapProviderEventHandler="MvcSiteMapProvider.DefaultSiteMapProviderEventHandler, MvcSiteMapProvider" />
      </providers>

1 Answers1

3

You will want to modify the MVCSiteMap DisplayTemplates - this gives you fine grained control over how the menu is displayed. This tutorial may help: http://edspencer.me.uk/2011/09/20/mvc-sitemap-provider-tutorial-2-breadcrumbs/

UPDATE

Here is an example to get you started.

Mvc.sitemap

<mvcSiteMapNode title="RootNode" controller="Home" action="Index">
  <mvcSiteMapNode title="Home" controller="Home" action="Index"/>
  <mvcSiteMapNode title="Administration" clickable="false">
    <mvcSiteMapNode title="Personnel" controller="Home" action="Personnel">
      <mvcSiteMapNode title="New Personnel" controller="Home" action="PersonnelNew"/>
    </mvcSiteMapNode>
    <mvcSiteMapNode title="Holiday" controller="Home" action="Holiday">
      <mvcSiteMapNode title="New Holiday" controller="Home" action="HolidayNew"/>
    </mvcSiteMapNode>
  </mvcSiteMapNode>
  <mvcSiteMapNode title="About" controller="Home" action="About"/>
</mvcSiteMapNode>

SiteMapHelperModel.cshtml

<ul class="siteMap">
    @foreach (var node in Model.Nodes) {
        if (node.IsRootNode)
        {
            foreach (var menu in node.Children)
            {
                <li>@Html.DisplayFor(m => menu) 
                    @if (menu.IsInCurrentPath || menu.IsCurrentNode)
                    {
                        if (menu.Children.Any())
                        {
                            @Html.DisplayFor(m => menu.Children)
                        }
                    }
                    else
                    {
                        foreach (var child in menu.Children)
                        {
                            @Html.DisplayFor(m => child)
                        }
                    }
                </li>
            }
        }
    }
</ul>

SiteMapNodeModelList.cshtml

<ul>
    @foreach (var node in Model) {
        if (node.IsCurrentNode)
        {
            <li>@Html.DisplayFor(m => node) 
                @foreach (var child in node.Children)
                {
                    @Html.DisplayFor(m => child);
                }
            </li>
        }
        else if (node.IsInCurrentPath)
        {
            <li>@Html.DisplayFor(m => node) 
                if (node.Children.Any())
                {
                    @Html.DisplayFor(m => node.Children)
                }
            </li>
        }
    }
</ul>

SiteMapNodeModel.cshtml

@if (Model.IsClickable) { 
    <a href="@Model.Url">@Model.Title</a>
} else { 
    <text>@Model.Title</text>
}

Now, when I go home, the menu is rendered as:

<ul class="siteMap">
    <li>
        <a href="/">Home</a>
    </li>
    <li>
        Administration
        <a href="/Home/Personnel">Personnel</a>
        <a href="/Home/Holiday">Holiday</a>
    </li>
    <li>
        <a href="/Home/About">About</a>
    </li>
</ul>

When I click on the Personnel menu item I get:

<ul class="siteMap">
    <li>
        <a href="/">Home</a>
    </li>
    <li>
        Administration
        <ul>
            <li>
                <a href="/Home/Personnel">Personnel</a>
                <a href="/Home/PersonnelNew">New Personnel</a>
            </li>
        </ul>
    </li>
    <li>
        <a href="/Home/About">About</a>
    </li>
</ul>

And when I click on the Holiday menu item I get:

<ul class="siteMap">
    <li>
        <a href="/">Home</a>
    </li>
    <li>
        Administration
        <ul>
            <li>
                <a href="/Home/Holiday">Holiday</a>
                <a href="/Home/HolidayNew">New Holiday</a>
            </li>
        </ul>
    </li>
    <li>
        <a href="/Home/About">About</a>
    </li>
</ul>

This wont be the exact functionality you want, but hopefully its enough to get you started.

UPDATE

Web.config

<siteMap defaultProvider="MvcSiteMapProvider" enabled="true">
  <providers>
    <clear />
    <add name="MvcSiteMapProvider"
         type="MvcSiteMapProvider.DefaultSiteMapProvider, MvcSiteMapProvider"
         siteMapFile="~/Mvc.Sitemap"
         securityTrimmingEnabled="true"
         cacheDuration="5"
         enableLocalization="true"
         scanAssembliesForSiteMapNodes="true"
         includeAssembliesForScan=""
         excludeAssembliesForScan=""
         attributesToIgnore="clickable,visibility"
         nodeKeyGenerator="MvcSiteMapProvider.DefaultNodeKeyGenerator, MvcSiteMapProvider"
         controllerTypeResolver="MvcSiteMapProvider.DefaultControllerTypeResolver, MvcSiteMapProvider"
         actionMethodParameterResolver="MvcSiteMapProvider.DefaultActionMethodParameterResolver, MvcSiteMapProvider"
         aclModule="MvcSiteMapProvider.DefaultAclModule, MvcSiteMapProvider"
         siteMapNodeUrlResolver="MvcSiteMapProvider.DefaultSiteMapNodeUrlResolver, MvcSiteMapProvider"
         siteMapNodeVisibilityProvider="MvcSiteMapProvider.DefaultSiteMapNodeVisibilityProvider, MvcSiteMapProvider"
         siteMapProviderEventHandler="MvcSiteMapProvider.DefaultSiteMapProviderEventHandler, MvcSiteMapProvider" />
  </providers>
</siteMap>
Mightymuke
  • 5,094
  • 2
  • 31
  • 42
  • I've tried it, but it didn't work. So I moved my controllers back to the UI-project. THere I could add the [MvcSiteMapNode(Title = "Create", ParentKey = "Personnel")]. But it still doesn't display the way I would like it. It always displays my "create"-item which I only want to display when I'm viewing the personnel-list. And when I'm on the Personnel-List, I don't want to show the item for "Holidays". – Bart Schelkens Nov 09 '12 at 11:24
  • The partials you should be looking at are `SiteMapHelperModel`, `SiteMapNodeModel` and `SiteMapNodeModelList`. By modifying these you should be able to achieve any style you like. – Mightymuke Nov 09 '12 at 11:31
  • I've been trying to solve my problem, but I haven't succeeded. I don't know what I'm doing wrong. – Bart Schelkens Nov 12 '12 at 11:11
  • Can you update your question with the content of these files so we can take a quick look? – Mightymuke Nov 12 '12 at 17:53
  • I've tried several things. BUt I'm no good at this I'm afraid. So now I'm back to the files as the were when I installed the MvcSiteMap. Thanks already for all the help. – Bart Schelkens Nov 13 '12 at 06:23
  • I've tried it, but i must be doing something wrong. I've added my sitemap to the question. – Bart Schelkens Nov 13 '12 at 12:39
  • What are you seeing? Partial menu / No menu / etc? – Mightymuke Nov 13 '12 at 19:31
  • Also can you please confirm that you're using this helper method to generate the menu `@Html.MvcSiteMap().SiteMap()`, and can you please post the `MvcSiteMapProvider` section from your `web.config`. Thanks. – Mightymuke Nov 14 '12 at 01:22
  • Thanks again for all the help you are giving already. I'm using the MvcSiteMap().SiteMap(). In my config I have the following lines: I think I might be missing something there. – Bart Schelkens Nov 14 '12 at 05:58
  • Is that from your view's web.config? I'm after what's in the main config. I've updated the answer with an example. – Mightymuke Nov 14 '12 at 07:31
  • It is the config of my UI-project. In the config in the "view"-folder there is no mention of MvcSiteMap – Bart Schelkens Nov 14 '12 at 09:12
  • OK - that configuration is usually added to your view, but the default partials are fully qualified so it shouldn't matter. The only difference in the configuration is the attribute `attributesToIgnore="clickable,visibility"` is missing from yours. I don't have my laptop with me so can't test it at the moment. If adding that does not work, can you please let me know what you're seeing (partial menu / no menu / etc). Thanks. – Mightymuke Nov 14 '12 at 09:23
  • I keep seeing the entire menu. Could it be because I have my controllers in a different project ? – Bart Schelkens Nov 14 '12 at 11:48
  • Even when moving my controllers into my UI-project, I still keep seeing the complete menu. – Bart Schelkens Nov 14 '12 at 11:59
  • 1
    Unfortunately I haven't been able to recreate your issue. Therefore I've created a sample application that is similar to your specification above, with a working menu, so that you can compare it with your application and hopefully determine what the issue is. You can find it over at [GitHub](https://github.com/mightymuke/MvcSiteMapProvider). (Note that its MVC3, I cant install MVC4 here). – Mightymuke Nov 15 '12 at 07:37
  • Thanks a lot for all the help. I'll keep you updated on the progress. – Bart Schelkens Nov 15 '12 at 08:03
  • I've restarted the project and now it seems to work. I guess somewhere there something still lingering around. Thanks again for all the help. – Bart Schelkens Nov 16 '12 at 08:48