How to setup a Styled Menu widget showing 1 top level menu?

Topics: Administration, Customizing Orchard, General
May 13, 2012 at 10:58 AM

Hi,

I am using Advanced menu 1.4.1 and I have a question.

Here's a sample menu

1 Home (~/)

2 About Us (~/about-us)

3 Articles (~/articles)

   3.1 Testimonials (~/articles/testimonials)

   3.2 News (~/articles/news)

   3.3 Events (~/articles/events)

** News and Events has their own articles

For example I go inside these articles;

   (~/articles/news/a-sample-news-1)

   (~/articles/events/a-sample-events-1)

The sidebar menu will output,

> News

> Events

My question is...

-- How to setup a 'styled menu widget' without using a specific 'root node'?

Thanks!

Developer
May 13, 2012 at 11:09 PM
Edited May 13, 2012 at 11:11 PM

If I understand correctly, you want to display the sub menu items of the current menu item in a widget? Although I'm not sure, I don't think the Advanced Menu module has such a widget. From the top of my head, what you could do is create a template that renders the sub menu for you. Inside this template, you determine the current first level menu item, then query for the sub menu items. If you look at the Advanced Menu module you should find some clues on how to do that. To render this template, just add a shape with the same name as the template (e.g. MySubMenu.cshtml) to the zone where you want to display the sub menu, e.g. "Layout.AsideFirst.Add(New.MySubMenu());".

I did something like this once by overriding Menu.cshtml. You can use the model that has been prepared by the Advanced Menu module and pass it into your custom shape. This shape would then render the children of the current 1st level menu item. 

A sample Menu.cshtml could look something like:

@using Orchard.UI.Navigation
@{
    var requestUrl = Request.Path.Replace(Request.ApplicationPath, string.Empty).TrimEnd('/').ToUpperInvariant();
    dynamic currentItem = null;

    // Find the current first level menu item    
    foreach(var item in Model)
    {
        string itemUrl = item.Href.Replace(Request.ApplicationPath, string.Empty).TrimEnd('/').ToUpperInvariant();
        bool isCurrent = ((!string.IsNullOrEmpty(itemUrl) && requestUrl.StartsWith(itemUrl)) || requestUrl == itemUrl);

        if (isCurrent)
        {
            currentItem = item;
            break;
        }
    }

    // Create a shape called "MySubMenu" and give it a property that references the current 1st level menu item
    Layout.AsideFirst.Add( New.MySubMenu( RootItem: currentItem ));
}

<ul id="main-menu">
    @DisplayChildren(Model)
</ul>

Then your MySubMenu.cshtml file could look something like this:

<ul id="sub-menu">
    @DisplayChildren(Model.RootItem)
</ul>



 

You could also create a widget that renders this shape, so that you can use the admin to configure in which zone the widget should be displayed. But that would require more work which may be unneccesary in your case.