Adding Menu Items using INavigationFilter

Topics: Writing modules
Jan 10, 2013 at 7:35 AM
Edited Jan 10, 2013 at 7:52 AM

Good Morning,

I am just getting up to speed with orchard. After creating a HelloWorld Module I wanted to add a link to the menu pointing to my page.

However, all the examples I have found are not using  INavigationFilter but the INavaigationProvider . I understand that from 1.6 INavigationFilter is to be used for front end navigation menus.

Does anybody have a few lines of code demonstrating this?





Jan 10, 2013 at 8:59 AM

Have a look at NavigationQueryProvider in Orchard.Projections.Navigation. It shows off how one may dynamically generate menu items, in this case, from a Query.

Jan 10, 2013 at 9:43 AM

I have looked over the code , but It seems a little complex. I am afraid that I am very new to Orchard .

I was hoping for a AddMenuItem("Hello World" , "/HelloWorld") kinda solution. Does one exist ?

Jan 10, 2013 at 11:02 AM

If you implemented your own controller and action to which you want to point from a menu item, you may be interested in the Contrib.Navigation module:

It adds a new menu item type, allowing the user to specify an action, controller and (tokenized) routevalues.
The best way to learn how the navigation API works is by keep looking at existing code, implementing your own classes (perhaps copied from other modules) and poke around and see what happens.

Essentially, all you have to do to see something work is implement INavigationFilter and return an IEnumerable of MenuItems. In your case, you could simply yield return a new MenuItem instance from the Filter method along with the rest of the items, something like this:

using System.Collections.Generic;
using Orchard;
using Orchard.UI.Navigation;

namespace HelloWorld.Navigation {
    public class NavigationProvider : Component, INavigationFilter {
        public IEnumerable<MenuItem> Filter(IEnumerable<MenuItem> items) {

            // Yield the current menu items
            foreach (var item in items) {
                yield return item;

            // Yield your own menu item as well
            yield return new MenuItem {
                Href = "~/HelloWorld/Home/Index",
                Text = T("Hello World")

That being said, you don't actually have to write code in order to create a menu item that points to your custom controller actions. There are several menu item types, where the Custom Link allows you to enter any url you want, e.g. ~/HelloWorld.

Jan 10, 2013 at 11:49 AM

sfmskywalker , Thanks for all your help so far. I am begining to undertsand what is going on , which is always useful.

However, I still cannot get the above code to work. The yielding of the existing items works , but the adding of a new item fails to show. Does Orchard do any checks on the MenuItem?

I have debugged through and the content item for the new MenuItem is null , does this stop it from rendering? 

I will start looking at the Contrib.Navigation module.

Jan 11, 2013 at 7:59 PM

Although I did not verify, that may very well be the cause of it. You could try by setting it to a content item (perhaps set it to the CurrentSite content item, which you can get by injecting a IWorkContextAccessor or IOrchardServices (which as a WorkContext property which in turn has a CurrentSite property). Not sure what the side effects of that are, if any.

Jan 14, 2013 at 3:10 PM


I have tried the above techniques but still no Joy.

I have found that setting the Position value allows the previous entries to show. Otherwise something falls over and stops the menu from displaying.

 I have also tried setting the Content to Null  , but with no effect.

Jan 14, 2013 at 3:14 PM

Found This in the logs from my earlier attempts to set content to CurrentSite:

Orchard.ContentManagement.Drivers.Coordinators.ContentPartDriverCoordinator - NullReferenceException thrown from IContentPartDriver by Orchard.Core.Navigation.Drivers.MenuWidgetPartDriver
System.NullReferenceException: Object reference not set to an instance of an object.
   at Orchard.Core.Navigation.Services.NavigationManager.Arrange(IEnumerable`1 items) in C:\DevOrchard\src\Orchard.Web\Core\Navigation\Services\NavigationManager.cs:line 216
   at Orchard.Core.Navigation.Services.NavigationManager.BuildMenu(IContent menu) in C:\DevOrchard\src\Orchard.Web\Core\Navigation\Services\NavigationManager.cs:line 48
   at Orchard.Core.Navigation.Drivers.MenuWidgetPartDriver.<>c__DisplayClass9.<Display>b__7() in C:\DevOrchard\src\Orchard.Web\Core\Navigation\Drivers\MenuWidgetPartDriver.cs:line 60
   at Orchard.ContentManagement.Drivers.ContentPartDriver`1.<>c__DisplayClassf.<ContentShape>b__e(BuildShapeContext ctx) in C:\DevOrchard\src\Orchard\ContentManagement\Drivers\ContentPartDriver.cs:line 130
   at Orchard.ContentManagement.Drivers.ContentPartDriver`1.<>c__DisplayClass15.<ContentShapeImplementation>b__14(BuildShapeContext ctx) in C:\DevOrchard\src\Orchard\ContentManagement\Drivers\ContentPartDriver.cs:line 139
   at Orchard.ContentManagement.Drivers.ContentShapeResult.ApplyImplementation(BuildShapeContext context, String displayType) in C:\DevOrchard\src\Orchard\ContentManagement\Drivers\ContentShapeResult.cs:line 39
   at Orchard.ContentManagement.Drivers.ContentShapeResult.Apply(BuildDisplayContext context) in C:\DevOrchard\src\Orchard\ContentManagement\Drivers\ContentShapeResult.cs:line 21
   at Orchard.ContentManagement.Drivers.Coordinators.ContentPartDriverCoordinator.<>c__DisplayClassa.<BuildDisplay>b__9(IContentPartDriver driver) in C:\DevOrchard\src\Orchard\ContentManagement\Drivers\Coordinators\ContentPartDriverCoordinator.cs:line 49
   at Orchard.InvokeExtensions.Invoke[TEvents](IEnumerable`1 events, Action`1 dispatch, ILogger logger) in C:\DevOrchard\src\Orchard\InvokeExtensions.cs:line 17

Jan 14, 2013 at 3:52 PM
Edited Jan 14, 2013 at 3:53 PM

I created an example module that injects tags as menu items when I was playing with the feature for the first time.

Here is the Blog Post with links to the source on GitHub as well as the module in the Orchard Gallery:


Maybe it will help.



Jan 15, 2013 at 8:26 AM


I have modified the code to look like the following based on you code , but I still cannot get it to work:

namespace HelloWorld.Navigation
    public class NavigationProvider : Component, INavigationFilter

        public IEnumerable<MenuItem> Filter(IEnumerable<MenuItem> items)

            // Yield the current menu items
            foreach (var item in items)
                yield return item;

            // Yield your own menu item as well
            yield return new MenuItem
                Text = new LocalizedString("Hello World"),
                Url = string.Format("~/HelloWorld/Home/Index"),
                Items = new MenuItem[0],
                Position = "1"
I must be missing something obvious...
Jan 15, 2013 at 8:58 AM

Did you attach the debugger to see if an exception occurs someplace? If so, it might give you a clue what is missing.

Jan 15, 2013 at 9:38 AM


The code steps through fine, nothing in the output window or the logs. No exceptions raised. The existing menu items display but the new one does not.

I have also tried just displaying the new menuItem by removing the first yield, at which point no menu items are displayed.

Jan 15, 2013 at 10:08 AM

Solved: ish.

It is a permissions problem. The Tabs only appear on the front page when I have logged in  (as admin).

What do I need to do to make the appear on the front page to anonymous users?

Jan 17, 2013 at 9:10 PM
Edited Jan 17, 2013 at 9:11 PM

This thread has been a great help to me! I too would like to know how to create MenuItems on the anonymous layer. I have created my custom menu items but they only appear once I've logged in. Any help would be appreciated!

Jan 21, 2013 at 7:25 AM

Any body have any Ideas?

Jan 21, 2013 at 7:53 AM

I don't know from the top of my head what this could be, but you could set a breakpoint in your code and step through back up the stack and find out what the calling code is doing with the yielded results. There's probably some permission checking going on somewhere.

Jan 28, 2013 at 8:10 PM

Has anyone made headway on this? I've tried to look at the call stack and associated code but cannot figure out how to create MenuItems that appear on the anonymous layer. ANY help would be much appreciated!

Jan 29, 2013 at 10:05 AM

This fix : seems to resolve this issue for me.

Jan 29, 2013 at 3:48 PM

So did you modify the Orchard source or did you override the Reduce function somewhere? if you overrode the Reduce function where did you do it?

Jan 29, 2013 at 6:39 PM

I was sloppy and modified the source.