Search code examples
orchardcmsorchardcms-1.8

How do you create a menuItem alternate in orchard for different Zones


I created an alternate for the main menu called MenuItemLink-main-menu-MainNavigation-MenuItem.cshtml because I want to render the menu differently in a Zone called main navigation. vs other places I am using the same menu on the page like the footer. I copied the MenuItem shape and renamed it (MenuItemLink-main-menu-MainNavigation-MenuItem.cshtml) everytime I run it I get an overflow because of the following line.

var renderedMenuItemLink = Display(Model);

can someone please explain to me why this is happening and the best way to create a zone based shapes for the navigation.


Solution

  • You copied markup from one shape (MenuItem) and paste it to another shape (MenuItemLink).

    1. MenuItem calls Display for MenuItemLink
    2. Then you calls Display for MenuItemLink inside MenuItemLink - this is an infinite loop.

    For add alternate inside theme for MenuItemLink:

    First. Create alternate for menu widget (Parts.MenuWidget.cshtml)

    @using Orchard.ContentManagement;
    @using Orchard.Widgets.Models;
    @{
        var widgetPart = ((IContent)Model.ContentItem).As<WidgetPart>();
        Model.Menu.Zone = widgetPart.Zone;
    }
    

    Second. Create alternate for menu item (MenuItem.cshtml) and add one line (after line Model.Metadata.Type = "MenuItemLink";)

    Model.Metadata.Type = "MenuItemLink";
    (Model as Orchard.DisplayManagement.Shapes.Shape).Metadata.OnDisplaying(action => 
        action.ShapeMetadata.Alternates.Add("MenuItemLink__Zone__" + (string)Model.Menu.Zone)
    );
    

    For add alternate inside theme for MenuItem:

    First. Create alternate for menu widget (Parts.MenuWidget.cshtml)

    @using Orchard.ContentManagement;
    @using Orchard.Widgets.Models;
    @using Orchard.DisplayManagement.Shapes;
    @{
        var widgetPart = ((IContent)Model.ContentItem).As<WidgetPart>();
        var items = Model.Menu.Items as List<dynamic>;
        AddMenuItemAlternate(items, widgetPart.Zone);
    }
    @functions{
        public void AddMenuItemAlternate(List<dynamic> items, string zoneName)
        {
            foreach (var item in items)
            {
                item.Metadata.Alternates.Add("MenuItem__Zone__" + zoneName);
                var subitems = (List<dynamic>)Enumerable.Cast<dynamic>(item.Items);
                AddMenuItemAlternate(subitems, zoneName);
            }
        }
    }
    

    Update 2015.08:

    I create module that adds widget name and zone name alternates for menu, menuItem and menu item link shapes. You can download one from orchard gallery https://gallery.orchardproject.net/List/Modules/Orchard.Module.MainBit.Navigation