Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Jamie Howarth 306 posts 773 karma points c-trib
    Feb 17, 2012 @ 17:06
    Jamie Howarth
    5

    Razor version of Flexible nav

    Hi guys,

    Given the advent of v5, I've found this menu package to be infinitely useful in various different projects.
    So, I've ported it to Razor syntax.

    @using umbraco.MacroEngines;
    @inherits umbraco.MacroEngines.DynamicNodeContext
    @{
        int startDepth = String.IsNullOrEmpty(Parameter.StartingLevel) ? -1 : int.Parse(Parameter.StartingLevel); 
        int startLevel = (startDepth >= 0) ? startDepth : int.Parse(Model.Level);
        int? forceNode = null;
        if (!String.IsNullOrEmpty(Parameter.ForceNode)) { forceNode = int.Parse(Parameter.ForceNode); }
        var ulClass = String.IsNullOrEmpty(Parameter.UlClass) ? "" : String.Format(" class=\"{0}\"", Parameter.UlClass);
        DynamicNode currentNode = (forceNode.HasValue) ? Library.NodeById(forceNode.Value) : Model;
        @nodeIterator(currentNode, currentNode.AncestorOrSelf());
    }
    
    @functions{
        public int startLevel { get { return @Parameter.StartingLevel; } }
        public bool selectBranches { get { return (@Parameter.SelectBranches == 1); } }
        public bool recurse { get { return (@Parameter.Recurse == 1); } }
        public int maxMenuDepth { get { return @Parameter.MaxMenuDepth; } }
        public int forceNode { get { return @Parameter.ForceNode; } }
        public bool walkChildren { get { return (Convert.ToInt32(@Parameter.ExpandChildren) == 1); } }
        public bool securityTrimming { get { return (@Parameter.SecurityTrimming == 1); } }
    
        public string ulBaseClass { get { return @Parameter.UlBaseClass; } }
        public string branchClass { get { return @Parameter.BranchClass; } }
        public string selectedClass { get { return @Parameter.SelectedClass; } }
    }
    
    @helper nodeIterator(DynamicNode parentNode, DynamicNode pseudoCurrentPage) {
         var calculatedMenuDepth = (parentNode.Level - Convert.ToInt32(@Parameter.StartingLevel));
         if ((parentNode.ChildrenAsList.Count > 0) || (calculatedMenuDepth == 1 && @Parameter.ForceHome)) {
             <ul class="@MenuClass(calculatedMenuDepth, ulBaseClass)">
                @if (calculatedMenuDepth == 1 && @Parameter.ForceHome) {
                    bool isHomeSelected = (Model.AncestorsOrSelf(1).ID == Model.ID);
                    <li class="@cssClassConstructor(isHomeSelected, false, true, selectedClass, branchClass)">
                        <a href="@library.NiceUrl(Model.AncestorOrSelf(1).ID)">@Model.AncestorsOrSelf(1).Name</a>
                    </li>
                }
                @foreach (DynamicNode node in parentNode.GetChildrenAsList.Where<DynamicNode>("umbracoNaviHide=false")) {
                    int currentNodeId = node.Id;
                    bool isBranch = (Model.AncestorOrSelf().Id == currentNodeId);
                    bool isSelected = ((Model.Id == node.Id) || (Model.Id == pseudoCurrentPage.Id));
                    bool isSelectedBranch = (isBranch && isSelected);
                    bool hasChildren = (node.ChildrenAsList.Count > 0);
                    <li class="@cssClassConstructor(isSelected, isSelectedBranch, hasChildren, selectedClass, branchClass)">
                        <a href="@library.NiceUrl(node.Id)">@node.Name</a>
                        @if ((isBranch && recurse) || ((walkChildren) && (maxMenuDepth > calculatedMenuDepth))) {
                            @nodeIterator(node, node)
                        }
                    </li>
                }
            </ul>
         }
    }
    
    @helper cssClassConstructor(bool isSelected, bool isSelectedBranch, bool hasChildren, string selectedClass, string branchClass) {
        string cssClass = String.Empty;
        if (isSelected) { cssClass += selectedClass + " "; }
        if (isSelectedBranch) { cssClass += branchClass + " "; }
        if (hasChildren) { cssClass += "hasChildren "; }
        @cssClass;
    }
    
    @helper MenuClass(int calculatedMenuDepth, string ulBaseClass) {
        string cssClass = String.Empty;
        if (calculatedMenuDepth == 1) { cssClass += ulBaseClass + " "; }
        cssClass += "lv" + calculatedMenuDepth;
        @cssClass
    }
    
    Let me know if it's buggy, but so far it seems to work AOK for me. If you install the normal CogNav macro, then create a new CSHTML, and swap it over in the macro settings, then it should still work just fine.
    Any bugs, let me know.
    Benjamin
  • Jeroen Breuer 4908 posts 12265 karma points MVP 4x admin c-trib
    Feb 18, 2012 @ 17:46
    Jeroen Breuer
    0

    How is the performance of your navigation? I've had some problems. You can see the solution here: http://our.umbraco.org/forum/developers/razor/28479-Razor-menu-performance-(v4)?p=3#comment108221

    Jeroen

  • Tim 225 posts 690 karma points
    Feb 29, 2012 @ 12:29
    Tim
    0

    Hiya,

    This looks great. Thanks for the contribution. A razor version was on my never shortening list of things to do.

    When I get 5mins I'll pull this into the package and take a look at Jeroen's performance concerns.

    Tim

  • Anthony Candaele 1197 posts 2049 karma points
    Oct 09, 2012 @ 13:42
    Anthony Candaele
    0

    Hi Tim,

    Are there still plans to have a Razor version of COG Flexible Navigation?

    greetings,

    Anthony

  • Jamie Howarth 306 posts 773 karma points c-trib
    Oct 09, 2012 @ 14:32
    Jamie Howarth
    0

    Hi Anthony,

    You're looking at it :-) install the Cogworks nav package, then copy the above code into a new CSHTML file (Developer > Scripting files), then change the macro settings (under Macros > [COG]Navigation) to use the new file you created.

    Re making this the standard for the package instead of the XSLT, that's down to Tim and Adam.

    HTH,

    Benjamin

  • Anthony Candaele 1197 posts 2049 karma points
    Oct 09, 2012 @ 14:50
    Anthony Candaele
    0

    Hi Benjamin,

    I did what you described above, but I'm getting an error:

    Error loading MacroEngine script (file: [COG]Navigation.cshtml)

    When I open the script in Visual Studio, Intellisense gives red squigly on this line of code:

    (line 34) @library.NiceUrl(Model.AncestorOrSelf(1).ID)... (@library is underlined with a red squigly)

    and

    (line 44) [email protected](node.Id)...(@library is underlined with a red squigly)

    I guess it's a namespace thing.

    I'm using Umbraco version 4.9.0

    greetings,
    Anthony

  • Jamie Howarth 306 posts 773 karma points c-trib
    Oct 09, 2012 @ 17:54
    Jamie Howarth
    0

    HI Anthony,

    Add the following to the top of the file:

    @using umbraco;

    HTH,

    Benjamin

  • bob baty-barr 1180 posts 1294 karma points MVP
    Jan 31, 2013 @ 17:50
    bob baty-barr
    0

    i am getting this error... 
    Operator '>' cannot be applied to operands of type 'method group' and 'int'

    on this line...
     if ((parentNode.ChildrenAsList.Count > 0) || (calculatedMenuDepth == 1 && @Parameter.ForceHome)) {

    using version 4.11.3

    any thoughts? 

  • bob baty-barr 1180 posts 1294 karma points MVP
    Jan 31, 2013 @ 18:17
    bob baty-barr
    0

    okay, so updating to Count() gets rid of errors on save...however, not getting any nodes to render... hmmm

  • Jan Brinker 77 posts 103 karma points
    Apr 16, 2013 @ 11:48
    Jan Brinker
    0

    Hiho,

    I'm getting some unexpected behaviour (and crashes) when running the code on v6.03. I had a website on 4.11 that used the original XSLT version of your navigation and just switched over to the Razor code. The parameters in my templates are still the same but I'm getting some unexpected behaviour (and crashes). Sadly I have no clue where the crashes occur, since Umbraco does not give any information about that.

    However here some info what happens and how my site is built:

    My tree looks like this:

    Home
    -News
    --2013
    ---04
    ----News Item
    -Events
    --2013
    ---04
    ----Event Item
    -Galler

    Now I call the macro for the main navigation bar like this:

    @Umbraco.RenderMacro("[COG]Navigation", new {startingLevel="1" , 
    recurse="0" , selectBranches="1" , maxMenuDepth="1" , 
    ulBaseClass="horizontal" , branchClass="branch" , 
    selectedClass="selected" , forceNode="" , expandChildren="0" , 
    forceHome="0" , securityTrimming="1" })

    Upon visiting the landing page (Home), the navigation does show only the direct children of Home, but all of them carry the "selected" class.

    When I now decide to go into the News section the main navigation does not render anymore. (Error loading MacroEngine script (file: [COG]Navigation.cshtml) )

    The second-level navigation (code below) still does render everything correctly and only gives me one entry in the sidebar-navigation: "2013", correctly NOT marked as selected yet.

    @Umbraco.RenderMacro("[COG]Navigation", new {startingLevel="2" , recurse="1" , selectBranches="1" , maxMenuDepth="999" , ulBaseClass="vertical" , branchClass="branch" , selectedClass="selected" , forceNode="" , expandChildren="0" , forceHome="0" , securityTrimming="1" })

    However if I now go into the 2013-folder of my news-section something very interesting happens. The second-level navigation throws an error, not being able to load, BUT the folder "04" (as in the tree the subfolder of 2013) appears now in my MAIN navigation. Also if I now click on it, my News Items show up in the main menu and the sidebar-navigation still shows the error. My main navi should only and always show the direct children of my "Home" node, the second-level navigation everything below these children.

     

    edit:

    A little cosmetic idea for the implementation:

    change

    @foreach(DynamicNode node in parentNode.GetChildrenAsList.Where<DynamicNode>("umbracoNaviHide=false"))

    to

    @foreach (DynamicNode node in parentNode.GetChildrenAsList.Where<DynamicNode>("Visible")) {

     

    Jan

  • Jan Brinker 77 posts 103 karma points
    Apr 16, 2013 @ 18:21
    Jan Brinker
    0

    Ok, I sat down today and tried to fix the code ad much as I could.. and I have to say (without wanting to sound rude) that the code was pretty much a-NO-k. In the beginning I wanted to post the lines that I had to change, I redecided to do the more practical solution and post the whole code. A lot had to be cleaned up and smoothed out.

    Still I can't guarantee bug-freeness, I'm just happy that I got this far with the given code.

    Also I added a functionality which adds a css-class to every link containing the node-id.

    Here you go:

    @using umbraco;
    @using umbraco.MacroEngines;
    @inherits umbraco.MacroEngines.DynamicNodeContext
    @{
    var ulClass = String.IsNullOrEmpty(ulBaseClass) ? "" : String.Format(" class=\"{0}\"", ulBaseClass);
    DynamicNode currentNode = (forceNode != -1) ? Library.NodeById(forceNode) : Model;
    @nodeIterator(currentNode.AncestorOrSelf(startLevel), currentNode);
    }

    @functions{
    public int startLevel {
    get {
    int level = Convert.ToInt32(String.IsNullOrEmpty(Parameter.StartingLevel) ? "-1" : Parameter.StartingLevel);
    return (level <= 0 ? Model.Level : level);
    }
    }
    public bool selectBranches { get { return (Parameter.SelectBranches == "1"); } }
    public bool recurse { get { return (Parameter.Recurse == "1"); } }
    public int maxMenuDepth { get { return Convert.ToInt32(Parameter.MaxMenuDepth); } }
    public int forceNode { get { return Convert.ToInt32(String.IsNullOrEmpty(Parameter.ForceNode) ? "-1" : Parameter.ForceNode); } }
    public bool walkChildren { get { return (Parameter.ExpandChildren == "1"); } }
    public bool forceHome { get { return (Parameter.ForceHome == "1"); } }
    public bool securityTrimming{ get { return (Parameter.SecurityTrimming == "1"); } }

    public string ulBaseClass { get { return Parameter.UlBaseClass; } }
    public string branchClass { get { return Parameter.BranchClass; } }
    public string selectedClass { get { return Parameter.SelectedClass; } }
    }

    @helper nodeIterator(DynamicNode parentNode, DynamicNode pseudoCurrentPage) {
    int calculatedMenuDepth = parentNode.Level - startLevel + 1;
    if ((parentNode.ChildrenAsList.Count() > 0) || (calculatedMenuDepth == 1 && forceHome)) {
    <ul class="@MenuClass(calculatedMenuDepth, ulBaseClass)">
    @if (calculatedMenuDepth == 1 && forceHome) {
    bool isHomeSelected = (Model.AncestorsOrSelf(1).ID == Model.ID);
    <li class="@cssClassConstructor(isHomeSelected, false, true, selectedClass, branchClass)">
    <a class="@linkCssClassConstructor(Model.AncestorOrSelf(1).ID)" href="@library.NiceUrl(Model.AncestorOrSelf(1).ID)">@Model.AncestorsOrSelf(1).Name</a>
    </li>
    }
    @foreach (DynamicNode node in parentNode.GetChildrenAsList.Where<DynamicNode>("Visible")) {
    bool isBranch = Model.IsDescendantOrSelf(node);
    bool isSelected = ((Model.Id == node.Id) || (pseudoCurrentPage.Id == node.Id));
    bool isSelectedBranch = (isBranch && selectBranches);
    bool hasChildren = (node.ChildrenAsList.Count() > 0);
    <li class="@cssClassConstructor(isSelected, isSelectedBranch, hasChildren, selectedClass, branchClass)">
    <a class="@linkCssClassConstructor(node.Id)" href="@library.NiceUrl(node.Id)">@node.Name</a>
    @if ((isBranch && recurse) || ((walkChildren) && (maxMenuDepth > calculatedMenuDepth))) {
    @nodeIterator(node, node)
    }
    </li>
    }
    </ul>
    }
    }

    @helper cssClassConstructor(bool isSelected, bool isSelectedBranch, bool hasChildren, string selectedClass, string branchClass) {
    string cssClass = String.Empty;
    if (isSelected) { cssClass += selectedClass + " "; }
    if (isSelectedBranch) { cssClass += branchClass + " "; }
    if (hasChildren) { cssClass += "hasChildren "; }
    @cssClass;
    }

    @helper linkCssClassConstructor(int nodeId) {
    string cssClass = "link"+nodeId;
    @cssClass;
    }

    @helper MenuClass(int calculatedMenuDepth, string ulBaseClass) {
    string cssClass = String.Empty;
    if (calculatedMenuDepth == 1) { cssClass += ulBaseClass + " "; }
    cssClass += "lv" + calculatedMenuDepth;
    @cssClass
    }

    Jan

  • Bjarni 7 posts 28 karma points
    Jun 03, 2013 @ 17:14
    Bjarni
    0

    Force Home was buggy, there was an extra "s" in the middle of AncestorOrSelf.  :)

    @if(calculatedMenuDepth ==1&&@Parameter.ForceHome){
                   
    bool isHomeSelected =(Model.AncestorOrSelf(1).ID ==Model.ID);
                   
    <li class="@cssClassConstructor(isHomeSelected, false, true, selectedClass, branchClass)">
                       
    <a href="@library.NiceUrl(Model.AncestorOrSelf(1).ID)">@Model.AncestorOrSelf(1).Name</a>
                    </
    li>
               
    }

    Bjarni

Please Sign in or register to post replies

Write your reply to:

Draft