Johansrk
Johansrk

Reputation: 5250

Umbraco 6 razor menu

Hi I want to add a class of "active" to my li, if it is active or if I am on a page under that. I have the following code

@inherits Umbraco.Web.Mvc.UmbracoTemplatePage
@{
    Layout = null;
}

<nav class="topNav">
    <ul>
        @foreach (var item in Model.Content.AncestorOrSelf(1).Children.Where(x => x.IsVisible() && x.IsDocumentType("Subfrontpage") || x.IsDocumentType("Procesguide")))
        {       
            <li>
                <a href="@item.Url">@item.Name</a>
            </li>
        }
    </ul>
</nav>

I think I can do something with this, but it gives an error

var isSelected = Model.Path.Contains(item.Id.ToString()) ? "active" : "";

            <li class="@Html.Raw(isSelected)">
                <a href="@item.Url">@item.Name</a>
            </li>

This is the error I get. Line 10.

Compilation Error

Description: An error occurred during the compilation of a resource required to service this request. Please review the following specific error details and modify your source code appropriately. 

Compiler Error Message: CS1061: 'Umbraco.Web.Models.RenderModel' does not contain a definition for 'Path' and no extension method 'Path' accepting a first argument of type 'Umbraco.Web.Models.RenderModel' could be found (are you missing a using directive or an assembly reference?)

Source Error:


Line 8:         @foreach (var item in Model.Content.AncestorOrSelf(1).Children.Where(x => x.IsVisible() && x.IsDocumentType("Subfrontpage") || x.IsDocumentType("Procesguide")))
Line 9:         {       
Line 10:            var isSelected = Model.Path.Contains(item.Id.ToString()) ? "active" : "";
Line 11: 
Line 12: <li class="@Html.Raw(isSelected)">

I have now tried with this, but no lunk

<ul>        
        <li>
            <a href="@home.Url">@home.Name</a>
        </li>

        @foreach (var item in Model.Content.AncestorOrSelf(1).Children.Where(x => x.IsVisible() && x.IsDocumentType("Subfrontpage") || x.IsDocumentType("Procesguide")))
        {       


            var isSelected = item.IsDescendant(Model,"active", "");

            <li class="@Html.Raw(isSelected)">
                <a href="@item.Url">@item.Name</a>
            </li>

        }


    </ul>

Upvotes: 4

Views: 6608

Answers (3)

Jan_V
Jan_V

Reputation: 4406

I just created a menu myself and needed the Home page to be active also. Working with just the method IsAncestorOrSelf doesn't work for the homepage.

The piece of code I've created is this:

@{ 
    var root = Model.AncestorOrSelf(1);

    var homeClass = root.Id == Model.Id ? "active" : "";
}

<ul id="nav" class="nav navbar-nav pull-right">
    <li class="@homeClass"><a href="/" >Home</a></li>
        @foreach (var page in root.Children.Where("Visible"))
    {
        <li class="@page.IsAncestorOrSelf(Model, "active", "")">
            <a href="@page.Url">@page.Name</a>
        </li>
    }
</ul>

This iterates through all children of the root node (1). To be able to discover if you are on the Home page, I'm checking the Id's of the page and set the active class accordingly.

Upvotes: 0

Johansrk
Johansrk

Reputation: 5250

ok here is the solution. This is for typed, not dynamic cshtml.

@inherits Umbraco.Web.Mvc.UmbracoTemplatePage
@{
    Layout = null;
    var home = Model.Content.AncestorOrSelf(1);
}

<ul>    
    @*Render Home item*@

    @{ var homeActive = ""; }

    @if( home.Id == Model.Content.Id){
        homeActive = "active";
    }
    <li class="@homeActive">
        <a href="@home.Url">
            @home.Name               
        </a>
    </li>

    @*Render Home children*@    
    @foreach (var item in home.Children.Where(x => x.IsVisible()))
    {                       
        var active = "";

        if(home.Id != Model.Content.Id){ @* if NOT home *@
            if (item.Id == Model.Content.AncestorOrSelf(2).Id){ 
                @* if foreach id and currentpage ancestor id is equal  *@
                active = "active";
            }
        }          
        <li class="@active">                             
            <a href="@item.Url">
                @item.Name                   
            </a>
        </li>
    }
</ul>

Upvotes: 7

lucuma
lucuma

Reputation: 18339

You can try something like this:

var isSelected = item.IsDescendant(Model,"active", "");   

Here is a list of the functions you can use:

@Model.AncestorOrSelf(string nodeTypeAlias)
@Model.AncestorOrSelf(int level)
@Model.AncestorOrSelf(Func<DynamicNode, bool> func)

and those Helper functions:

@Model.IsDescendant(DynamicNode[,valueIfTrue][,valueIfFalse])
@Model.IsDescendantOrSelf(DynamicNode[,valueIfTrue][,valueIfFalse])

Reference: Is the current page a descendant of a specific node id?

The following is the default script for navigation produced by umbraco:

@inherits umbraco.MacroEngines.DynamicNodeContext

@*
    Macro to display child pages below the root page of a standard website.
    Also highlights the current active page/section in the navigation with
    the css class "current". 
*@


@{ 
    @*Get the root of the website *@
    var root = Model.AncestorOrSelf(1);
}

<ul>
    @foreach (var page in root.Children.Where("Visible"))
    { 
        <li class="@page.IsAncestorOrSelf(Model, "current", "")">
            <a href="@page.Url">@page.Name</a>
        </li>
    }
</ul>

Upvotes: 0

Related Questions