How to access menu ul

Topics: Customizing Orchard
Feb 11, 2014 at 1:59 AM
[using Orchard v.1.7.2.0]

I am trying to get at the html that wraps my menu items in my main nav, because I want to apply a few classes to it. The rendered HTML looks like this:
<ul class="menu menu-main-menu" shape-id="13">blah</ul>
When I look at the shape tracer...
Zone [Header]
     Header
     User [empty]
​     Zone [Navigation]
          Widget
               Menu
                    MenuItemLink
               Parts_Contents_Publish [empty]
... I cannot find the template where the classes, "menu" and "menu-main-menu" are set.

What am I missing?

All I can find is the MenuItem.cshtml file, which is not mentioned in the shape tracer at all, and which does not set the classes or display the UL that I am looking for.
@{
    // odd formatting in this file is to cause more attractive results in the output.
    var items = Enumerable.Cast<dynamic>((System.Collections.IEnumerable)Model);
}
@{
    if (!HasText(Model.Text)) {
        @DisplayChildren(Model)
    }
    else {
        if ((bool) Model.Selected) {
            Model.Classes.Add("current");
        }

        if (items.Any()) {
            Model.Classes.Add("dropdown");
        }

        @* morphing the shape to keep Model untouched*@
        Model.Metadata.Alternates.Clear();
        Model.Metadata.Type = "MenuItemLink";

        @* render the menu item only if it has some content *@
        var renderedMenuItemLink = Display(Model);
        if (HasText(renderedMenuItemLink)) {
            var tag = Tag(Model, "li");
       
            @tag.StartElement
            @renderedMenuItemLink

            if (items.Any()) {
                <ul>
                    @DisplayChildren(Model)
                </ul>
            }
    
            @tag.EndElement
               
        }
    }
}
Does anyone have any pointers?

Thanks!
Feb 11, 2014 at 12:58 PM
menu and menu-menu-name classes come from CoreShapes.cs Menu shape description. They are rendered by Menu.cshtml with

var tag = Tag(Model, "ul");

@tag.StartElement

here Model has a Classes property populated by CoreShapes with

builder.Describe("Menu")
.OnDisplaying(displaying => {
var menu = displaying.Shape;
string menuName = menu.MenuName;
menu.Classes.Add("menu-" + menuName.HtmlClassify());
menu.Classes.Add("menu");
menu.Metadata.Alternates.Add("Menu__" + EncodeAlternateElement(menuName));
});



Feb 11, 2014 at 6:13 PM
Thanks Kassobasi, I was able to apply the classes that I needed by doing this in CoreShapes.cs:
            builder.Describe("Menu")
                .OnDisplaying(displaying => {
                    var menu = displaying.Shape;
                    string menuName = menu.MenuName;
                    menu.Classes.Add("menu-" + menuName.HtmlClassify());
                    menu.Classes.Add("nav");
                    menu.Classes.Add("navbar-nav");
                    menu.Classes.Add("navbar-right");
                    menu.Metadata.Alternates.Add("Menu__" + EncodeAlternateElement(menuName));
                });
Is this right? This means that all Menus will have these classes applied to them, right? Is there any way to limit the application of these classes to just the main menu?
Feb 12, 2014 at 7:36 AM
You should not change core classes unless you have to, otherwise the change s will be overwritten when you upgrade. You should better add classes to the tag using an alternate in your theme.

In the original shape method, you see there is this line:

menu.Metadata.Alternates.Add("Menu__" + EncodeAlternateElement(menuName));

this means that you can add a template named Menu-MainMenu.cshtml (or Menu-Main Menu.cshtml, I'm not sure) in your theme's Views folder.

In that view, you can include the original code from Menu.cshtml and add your classes before Tag is rendered, using Model.Classes.Add("nav") etc..





Feb 12, 2014 at 7:04 PM
Thanks. Is this a typo or is there supposed to be a space in the name: "(or Menu-Main Menu.cshtml, I'm not sure)"?
Feb 12, 2014 at 9:55 PM
It's not a typo, but as I wrote I'm not sure about the exact name of the alternate, and its matching template file name. It's Menu-<menu name>.cshtml, but EncodeAlternateElement(menuName) might be replacing space with a dot or dash, or removing all space. You can try both with a space and with other possibilities to find out.


Feb 12, 2014 at 10:25 PM
Thanks, it looks like Menu-Main-Menu.cshtml is the name that works.