Add custom classes to menu items in Orchard 1.5

Topics: General, Installing Orchard
Jul 31, 2012 at 4:01 PM

I'm in the process of setting up my menu items in Orchard 1.5 after upgrading from 1.4.2 previously using the advanced menu module.

One thing that I'm having trouble replicating is adding custom classes to specific menu items.

In this case, the top-level menu items had a unique class for each item (on each li tag).

With advanced menu this was fairly straight forward as it allowed additional classes to be specified against individual menu items. 

I've tried enabling the Vandelary.Classy module and adding the CustomCSS part to the Content Menu Item content type. This allowed me to define the class in the menu item definition, but it wasn't rendered to the view.

I suspect this is due to content template issue discussed in the following article

Can you point me in the direction of the template that outputs the <li> tags that I would need to override in my theme to allow classy to work?

Alternatively is there a better approach to add custom class to the li tags of the menu items in navigation in 1.5?

Any suggestions much appreciated :)

Jul 31, 2012 at 4:21 PM

MenuItem.cshtml? There are several of this, but the one you're looking for is probably the one in Orchard.Core/Shapes/Views.

Aug 1, 2012 at 7:32 AM
Edited Aug 1, 2012 at 7:43 AM

Thanks. Found that and from looking at the shape tracing it seems that's the one I'm interested in. 

That said, it already renders the li tags using the Tags(Model, "li") approach you have suggested in the above referenced discussion. So I'm not sure what else I need to be doing to ensure the custom css tags are rendered from the classy module.

Do I need to access the CustomCss.CssClass property directly in the template and manually add it to the tags class list?

If this is the case, it would seem that I need to add a reference in my theme to the Classy module to achieve this, so I can do something like...




In the MenuItem.cshtml file (CustomCss is the content part defined in the classy module).

Aug 2, 2012 at 2:55 PM

No, it should work. I don't know why it doesn't. You did add the part to menuitem, not to menu, right? Next step would probably be to debug into that template.

Aug 3, 2012 at 12:01 AM

Yeah I added the CustomCss part to the "Custom Link", "Content Menu Item" and "Html Menu Item" content types. In all three cases, I can then specify a class against the menu item in admin, but it's never rendered to the <li> tag in the display output.

I ran the debugger over the CustomCssHandler.cs class in the Vandelay.Industries module and noticed that the BuildDisplayShape override method is never called (for menu items). It is however called if I attached the CustomCss part to a widget content type and define a custom class against the widget.

Aug 3, 2012 at 4:40 PM

Here is how I did it for the harvest conference:

- Add a CssClass text field to MenuPart, this will then be rendered for each menu item
- Copy/Paste the \Core\Shapes\Views\MenuItem.cshtml template to your theme and insert those lines where necessary:

    dynamic contentItem = Model.Content.ContentItem;


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

I find it quite useful and maybe we could have it by default.

Aug 3, 2012 at 4:41 PM

Yes, that makes sense. Well, I suppose I would have to dig into this and debug it. Can you please file a bug on the Vandelay.Industries bug database? I'm not sure when I'll be able to look at it in more details though.

Aug 3, 2012 at 4:42 PM

Sébastien's solution will work too, of course, but I'd still like to have a bug filed as this should work with Classy, in an ideal world.

Aug 4, 2012 at 8:51 AM
Edited Aug 4, 2012 at 8:51 AM

I've raised the following issue.

Aug 4, 2012 at 9:00 AM

BTW, Thanks Sébastien for your alternate solution. This works a treat!

Aug 4, 2012 at 8:16 PM


Aug 4, 2012 at 8:53 PM

Recently I had pretty much the same problem. This isn't generic, but maybe could solve your issue too: just write css selectors for the links directly (filtering on the content of the href attribute). I made a menu with custom images this way.

May 3, 2013 at 5:46 PM
Sorry to resurrect this thread. I'm trying to implement Sebastien's solution.
I've added the CssClass text field to MenuPart, copied \Core\Shapes\Views\MenuItem.cshtml to my theme's Views folder and altered the code per Sebastien's post. Here is my MenuItem.schtml code:
    // odd formatting in this file is to cause more attractive results in the output.
    var items = Enumerable.Cast<dynamic>((System.Collections.IEnumerable)Model);

    dynamic contentItem = Model.Content.ContentItem;

if (!HasText(Model.Text)) {
} else {
    string requestUrl = Request.Path.Replace(Request.ApplicationPath, string.Empty).TrimEnd('/').ToUpperInvariant();
    string modelUrl = Model.Href.Replace(Request.ApplicationPath, string.Empty).TrimEnd('/').ToUpperInvariant();
    if (requestUrl == modelUrl || (!string.IsNullOrEmpty(modelUrl) && requestUrl.StartsWith(modelUrl + "/"))) { 
    if(items.Any()) {

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

    @* morphing the shape to keep Model untouched*@
    Model.Metadata.Type = "MenuItemLink";
    if (items.Any()) {
I'm getting the following error:
'Orchard.Core.Navigation.Models.MenuPart' does not contain a definition for 'CssClass'

What am I missing?
May 4, 2013 at 12:21 AM
Can you confirm that you added the "CssClass" field to the "Menu" Content Part (Content Parts tab in admin) and not the "Menu" Content Type (Content Types tab in admin)?
May 4, 2013 at 4:39 PM
Yes, CssClass field was added the the "Menu" Content Part.