Search code examples
c#asp.net-mvctwitter-bootstrapasp.net-mvc-5mvcsitemapprovider

MVC5 using MvcSiteMapProvider to build twitter bootstrap menu


Default menu section in MVC5 template looking like that:

     <div class="navbar-collapse collapse">
            <ul class="nav navbar-nav">
                <li>@Html.ActionLink("Home", "Index", "Home")</li>
                <li>@Html.ActionLink("About", "About", "Home")</li>
                <li>@Html.ActionLink("Contact", "Contact", "Home")</li>
            </ul>
            @Html.Partial("_LoginPartial")
        </div>

_LoginPartial looking like that:

@using Microsoft.AspNet.Identity
@if (Request.IsAuthenticated)
{
    using (Html.BeginForm("LogOff", "Account", FormMethod.Post, new { id = "logoutForm", @class = "navbar-right" }))
    {
    @Html.AntiForgeryToken()

    <ul class="nav navbar-nav navbar-right">
        <li>
            @Html.ActionLink("Hello " + User.Identity.GetUserName() + "!", "Manage", "Account", routeValues: null, htmlAttributes: new { title = "Manage" })
        </li>
        <li><a href="javascript:document.getElementById('logoutForm').submit()">Log off</a></li>
    </ul>
    }
}
else
{
    <ul class="nav navbar-nav navbar-right">
        <li>@Html.ActionLink("Register", "Register", "Account", routeValues: null, htmlAttributes: new { id = "registerLink" })</li>
        <li>@Html.ActionLink("Log in", "Login", "Account", routeValues: null, htmlAttributes: new { id = "loginLink" })</li>
    </ul>
}

So i can replace the code

        <div class="navbar-collapse collapse">
            <ul class="nav navbar-nav">
                <li>@Html.ActionLink("Home", "Index", "Home")</li>
                <li>@Html.ActionLink("About", "About", "Home")</li>
                <li>@Html.ActionLink("Contact", "Contact", "Home")</li>
            </ul>
        </div>

with just one line:

@Html.MvcSiteMap().Menu(false)

That line will produce this:

        <div class="navbar-collapse collapse">
            <ul class="nav navbar-nav">
                <li>@Html.ActionLink("Home", "Index", "Home")</li>
                <li>@Html.ActionLink("About", "About", "Home")</li>
                <li>@Html.ActionLink("Contact", "Contact", "Home")</li>
            </ul>
           //how to put _LoginPartial here!
        </div>

So the question is how can i render @Html.Partial("_LoginPartial") inside menu created by MvcSiteMapProvider ?


Solution

  • Rowan's answer is pretty close to what you need to do, and should have led you down the correct path. The template MyMenu.cshtml can contain any logic you need to output the desired HTML. You simply need to modify the template to meet your requirement. Note that you can also modify the default templates if desired, but you will have to be careful to select "no" when asked to replace them during an upgrade of MvcSiteMapProvider, or your customizations will be overwritten.

    @model MvcSiteMapProvider.Web.Html.Models.MenuHelperModel
    @using MvcSiteMapProvider.Web.Html.Models
    
    <div class="navbar-collapse collapse">
        <ul class="nav navbar-nav">
            @foreach (var node in Model.Nodes) { 
                <li>@Html.DisplayFor(m => node)</li>
            }
        </ul>
        @Html.Partial("_LoginPartial")
    </div>
    

    And then this line will produce the desired output:

    @Html.MvcSiteMap().Menu("MyMenu")