Featuring Orchard Advanced Menu

Tags: orchard, module, menu

New Hierarchical Menu module release is finally here. As you probably noticed, the module name has changed to Advanced Menu, as I guess it’s more appropriate now. Why? This is basically what I’m about to write about, as there’s been a lot of changes since the last releaseUśmiech.

First and foremost – the module is prepared to work with the upcoming Orchard 1.1 release! The bad news about it is that it probably won’t work with the Orchard 1.0, because the new release introduces some breaking changes (e.g. different LocalizationString handling). Would there be a demand for backward compatibility, I’ll do my best to try adding that (I have to make some research if it’s possible at all first).

As the module takes part in the Orchard Module Challenge, I created a simple demo site, which shows it’s most powerful featuresUśmiech Check it out!

New features

Version 1.2 introduces many features not available in previous versions (in addition to changes to existing ones, which are described later in this article):

  • Custom menus– ability to create your own menus.
    • Easily create different menus for different purposes, e.g. separate the menus used for display and breadcrumb rendering
    • You can auto-fill the created menu with existing content items (Pages, Blogs, Lists etc.) with just a click of a button. There is also an option to include contained items (e.g. Blog posts, List items and such)
  • Styled menu widget – styled and scripted with Superfish jQuery library menu widget with color customization options. Works with all major browsers and degrades gracefully when JS is disabled
  • Templated menu items – you can put your own Html markup inside menu items
  • Visit counters – attach a visit counter to any displayable content type (attached to Page type by default)
    • Scoped – you can choose from three predefined counter scopes: PerSite, PerUser and PerSession
    • This is the flag use of the counting framework I created while rewriting the included RecentlySeenWidget (which now utilizes this). There’s way more than this, but this is clearly a topic for a different article.

When the Advanced Menu module is enabled, the default menu gets automatically replaced with StyledMenuWidget. So you don't have to create the first widget by hand, as it's already there! You can change it or replace from the Dashboard if you need to.

Changes

  • More menu and menu item rendering options
    • Optional wrapping of sub-items in additional <div> tags
    • Add optional subtitle to menu items
    • Hide/show menu item’s text
    • Render menu item as link (default) or just as a plain text
    • Limit the number of menu levels displayed with an option to cut or flatten to a single list the items below threshold
    • Specify which menu item children to use as a top level of a displayed menu. By default none, which means that the whole menu is rendered
  • Tweaks for easy styling/scripting
    • Unique Id attribute for each menu widget – each menu widget has a unique menu-<item_id>  HTML Id attribute to allow targeting specific menu with jQuery/CSS selectors. The item_id is menu widget’s content item Id.
    • Unique Id attribute for each counter – counter-<item_id>, analogous to the former
    • Additional CSS classes for counterscounter-<counter_scope>, where counter_scope is the scope used (“PerSite”, “PerUser” or “PerSession”).
  • Additional shape alternates for customization
    • Menu__[item_id], where item_id stands for MenuWidget/StyledMenuWidget content item Id. Example: Menu-33.cshtml
    • Breadcrumbs__[item_id] – where item_id is BreadcrumbsWidget content item Id. Example: Breadcrumbs-22.cshtml
    • Breadcrumbs__[menu_name] – where menu_name is the name of menu used to render BreadcrumbsWidget. Example: Breadcrumbs-main.cshtml
    • Counter__[counter_scope] – where counter_scope is counter scope used (“PerSite”, “PerUser” or “PerSession”). Example: Counter-PerSite.cshtml
    • Counter__[item_type] – where item_type is the name of content type the counter is attached to. Example: Counter-BlogPost.cshtml
    • Counter__[item_id] – where item_id stands for the Id of an item the counter is attached to. Example: Counter-11.cshtml
  • Lot of code refactoring

 

Plans for the next release (around mid/end-April 2011)

  • Editing content item menu associations on item edit/creation screen
  • Multi-column sub-items layout – dividing children into multiple lists
  • Menu item position auto-creation based on existing items
  • Menu item listing UI improvement and tweaks
  • Performance improvements by utilizing caching engine where possible
  • More styling options for StyledMenuWidget – borders, padding, margins, custom CSS, top menu level alignment (left/right/center)
  • Refactoring – group and divide the features into separate features - I just didn't have time to do this, as OMC deadline was nearby (and being left with the totally broken build few hours before wasn't the thing I dreamt ofUśmiech)

 

I hope you’ll find it useful in your Orchard projects! I’m going to update my blog to Orchard 1.1 as soon as it arrives to utilize this nice new feature. I’d be very glad for any feedback so I could make this module better and betterUśmiech

Cheers!

53 Comments

  • Olin said

    Hello !

    great job for your module.

    I'm testing and looking for all the new features ! it seem really amazing :)

    I've been confronted to a first problem : When i try to delete a menu i have the following error :A required anti-forgery token was not supplied or was invalid.

    Thanks for your really helpful job again ! :)

  • pszmyd said

    @Olin: Nice to hear that:) This is surely a bug - I'll post an update tomorrow. Thanks for pointing that out.

    @mataswork: There is a module by Renaud Paquay - Package Manager. You can download it here: http://www.orchardproject.net/gallery/List/Modules/Orchard.Module.Iroo.PackageManager. It allows to upgrade/downgrade any installed module.

    Sorry for making trouble those who use Orchard 1.0. I could've specified the 1.1 version in module manifest (which I'll surely do after official release) so to prevent instalation on older versions, but... It'd prevent the installation on any Orchard instance as the version hasn't been incremented in dev source yet (so even if you use the latest bits the version is still 1.0.20).

  • pszmyd said

    @springy: Ahhh, stupid error:) Copy-pasted that and forgot to change the namespace. I'll fix that asap.

  • Olin said

    Hi again !

    I've been testing from this morning your module and it work very great!

    but perhaps i'm missing something but are the item localized ? because i've made a page translated and even if i switch language , my menu do not change and still be in the same culture.

  • Alex said

    Hello! The type or namespace name 'Work' could not be found Line 18: private readonly Work _menuService; NavigationProviderFactory.cs Line: 18

    I've got this error. What's my problem?

  • springy said

    It's always fun digging into the sources to find out how you did that :)

    I'm glad to see that OrchardSuppressDependencyAttribute replaced the low-level AutoFac-Module-"Hack" (which always was active no matter whether the Orchard-Module was disabled).

    I wonder would could be done to reduce conflicts with modules like "CulturePicker" which provides a localized menu.

    IMHO the entire multi-menu / hierarchical-menu / multi-language featureset should be put into the core modules -- interestingly the admin menu is hierarchical since ages.

  • springy said

    @Alex: Work was introduced lately and is part of the integration branch (1.0 => 1.1)

  • Olin said

    I've been looking the code of the navigation provider and sadly there is no localization ^^

    will it be in the next coming update with the bug corrections ?

    :)

    Another time : Great job ! it work very fine :) !

    PS: in next release will you make some stuff to update position between pages because it's not very easy ^^ importing all the pages and reorganizing the position is the better way i found, but not so fast :p

  • pszmyd said

    Wow, just gone for a moment:) @Alex: Work is a new addition in Orchard 1.1 which allows injecting objects of "unit of work" (request) lifetime into those of a "singleton lifetime, which wasn't possible earlier.

    @springy: Yes, this is a nice addition Sebastien Ros told me about:)

    I agree that those should be in the core, and I guess in 1.2 they will be (I will contribute my module to the core for sure).

    Admin menu isn't stored anywhere, but it's being built by gathering and merging outputs of INavigationProviders from every enabled feature. So dynamic hierarchy building doesn't happen here - it's hardcoded. Orchard supports hierarchical menus from the very beginning, but just didn't have a feature for creating those from GUI-defined items. I guess the reason why GUI-based hierarchical menu building wasn't added to the core yet is pretty simple - 2 months ago we just had the first release and there are lots of issues of higher priority that Team has to deal with atm (like problems with running Orchard on shared hosting, performance, layout building and theming etc.). It is important thing though and that's why I tried to add the missing part:)

    @Olin: Yes, I'll surely focus on usability-related stuff in next version. I just didn't have enough time for that before OMC deadline... My goal for this release was to refactor the source and setup the module structure and db schema for easy updating and extensibility. GUI was thought to be just good enough to use the module features. I have to admit that it's nowhere near I would like it to look finally;)

  • Alex said

    I see. Thank you for answer. I would like to get Orchard 1.1. but i dont know where it is.

  • Olin said

    You wan get the last source here : http://orchard.codeplex.com/SourceControl/list/changesets or getting the source directly from the repository using Hg repository with this source https://hg01.codeplex.com/orchard

    have fun ^^

    Pszmyd, will you had localizable menu in the next mid/end april release ?

  • springy said

    Hmm.. There is no strong coupling of content items and menu structure any more? Everything is being bound by full paths which you have to remember and which break if someone renames a slug?

  • springy said

    Maybe it's a sideeffect of some other module: Have you tried using Shape Tracing? I get JavaScript-Timeout errors and the hierarchical menu is flooded with debug text.

  • pszmyd said

    @springy: No it's not bound by full paths - the coupling is here, but it surely lacks an UI atm.

    Menu items which get created via filling a menu are coupled to the content items (Url field is there though when you edit one, but it's overridden by a generated path - have to gray out that for bound items).

    This is the GUI thing I'm working on now - to distinguish bound/unbound items and link between menu item(s) and a corresponding content item (and vice versa).

    Also there's also gonna be a part similar to the exisiting one, though not used by me - MenuPart. This is the one that generates the checkbox "Show on main menu" for Pages. I'm currently rewriting this to show many checkboxes (for every defined menu), so you could choose which menus to add the corresponding menu item to at creation time. Much like the UserRolesPart does with user roles.

  • pszmyd said

    @springy: Havent used that yet, but will surely check it out. Didn't have a clue why that happens...

  • mataswork said

    Hello it's me again

    Error 17 The command "xcopy C:\inetpub\wwwroot\inspra\src\Orchard.Web\Modules\Szmyd.Orchard.Modules.Menu* C:\inetpub\wwwroot\inspra\src\Orchard.Web\Modules\Szmyd.Orchard.Modules.Menu* /H /E /Y" exited with code 4. Szmyd.Orchard.Modules.Menu

    then I try to build menu project.

  • springy said

    @mataswork: You can remove the after-build target when the module resides in the modules folder

  • Doga Oztuzun said

    I have got the latest version of the Orchard from the Source code.

    But I got the following error in the NavigationProviderFactory class.

    The type or namespace name 'Work' could not be found (are you missing a using directive or an assembly reference?)

    It is asked before but I don't know how do you fix it.

  • pszmyd said

    @mataswork: Exactly like @springy said - please remove the post-build event in module project properties. I forgot to remove this (I'm using that because I store the module projects aside from the Orchard source) - will remove in the bugfix release today.

    @Doga Oztuzun: Are you sure you have the latest source from 1.x/integration branch? TortoiseHg by default downloads the "default" one (Orchard 1.0.20)...

  • springy said

    Found a small bug: Creating a menu having a camelcased name all the action links get a non-working space in the path.

  • pszmyd said

    @springy: Thanks, I'll take a look. I've used one of Orchard built-in string extensions - maybe I've missed something.

  • springy said

    What would be the correct migration path against an old 1.0 database (which already has been upgraded to 1.1 for all other parts)?

    Having enabled the module/feature it brings down everything including the admin menu because there are missing fields and tables -- the pure activation of the module fails too at MenuFeatureEvents.Enabled() in Events.cs:line 50.

  • cj said

    I appreciate the good work as always. Quick question for you. I'm trying to upgrade from the previous version and I'm getting "Invalid object name 'SzmydOrchardModulesMenuAdvancedMenuPartRecord'." What is the intended upgrade process? Installing from the gallery seems to throw errors as well. I'm running the latest integration branch. Thanks again!

  • Philip Senechal said

    Love the menu so far! I have a suggestion and a question.

    Suggestion: there is no way to turn off the sub-menu arrows from the admin GUI...only way I found to turn them off is in the Menu.Styling Part in the Module folder. Would be nice if this was an option you could enable/disable per menu instance.

    Question: I cannot seem to get my menu to display for anonymous users even though it's on the Default layer. Is there some sort of setting I'm missing?

    Thanks!

  • pszmyd said

    Hi!

    Thanks for lot of feedback!:) I'm in the process of updating module for recently released 1.1 version. There were a couple of issues beacuse I was trying to have backward compat with 1.0 release which was a mistake, I have to admit.

    I'll post an update to the Gallery tomorrow.

    @springy: Upgrading from 1.0 will be tough, as I did lot of refactoring in the meantime. I'd suggest a fresh install, removing the previously installed instances...

    @Philip: Yes, the arrows are hardcoded as part of the Superfish styling I used in Styled Menu Widget. I'll try to add arrow enable/disable in future release. Weird thing with display - are you sure the zone you placed the menu widget in is being rendered at all in Layout.cshtml?

    @Arra: Could you provide the error info you get? Post me please directly on piotr.szmyd at ieee.org - I'll try to figure it out.

  • Philip Senechal said

    Well...it defaulted the menu to the Navigation zone, so I left it there. I removed the widget and added it to the Header zone and it was then visible when accessing the site as anonymous. So my Navigation zone must not be visible to anonymous users. I'll have to figure out how to change that or add it to a different zone.

    Thanks for the tip!

  • Philip Senechal said

    I figured out the problem with the menu disappearing. I defined the CSS for the menu placement while logged in as admin which adds a div for the widget-control to edit the widget. My placement of the menu was taking this into account...so when the widget-control div isn't present, my menu placement ends up so high it's off the screen.

  • Philip Senechal said

    One more question for you if you don't mind.

    I have a breadcrumb widget based off my main menu. The main menu has 3 items 0 - Home / 1 - Link 1 /link1 1.1 - Sublink 1 /sublink1

    When I'm on the Home page, the breadcrumb is correct and displays Home. When I'm on Sublink 1, the breadcrumb is correct and displays Home > Link 1 > Sublink 1. But when I'm on Link 1, the breadcrumb only displays Link 1 instead of Home > Link 1.

    Any ideas on how I can get that output without having to put Link 1 underneath Home? Is there an option for 1st level menu items to always display the Home link?

    Thanks for the assistance!

  • Olin said

    Hello pszmyd !

    Using your module, i've found a bug:

    in the website, my item url is : http://localhost/Help/fr/extra/creation

    in the recently seen widget : http://localhost/fr/extra/creation

    how can i correct it fastly ? because i need to fix it for my next release of the website. Thanks !

    Moreover, is that possible to display the parent name in this widget by patching your module ? and if its possible , where ?

    thanks a lot !

  • Bogdan T said

    First of all, congratulations on winning the contest with this great module. Second, I have a few observations :

    • If you add a list to the site, add select to appear on the main menu, it does not synchronize with the "main menu" edit from the dashboard. If you change something to the list name or path after you add it to the menu, editing it in the menu has no effect, it will show the old data.

    • The menu seems to break sometimes, I haven't managed to isolate the exact cause/moment. What happens is each menu item shows, next to the menu item text, the path to the view. Any ideas? I haven't been able to fix the menu when this happens, and I had to start from a "fresh" source four times already.

      I had spotted a couple more, but they were on another source, I will post them another time. Cheers.

  • Bogdan T said

    I found the answer to the second one. It breaks when you enable Shape Tracing, you have to disable it to come back to normal.

  • Bogdan T said

    When I try to delete a menu, this appears :

    A required anti-forgery token was not supplied or was invalid.

  • mataswork said

    Hello it's me again. I get error Invalid object name 'SzmydOrchardModulesMenuAdvancedMenuPartRecord' I think its the same cj is getting. This happened after upgrading Orchard from 1.0.20 to 1.1 with old version of menu. After upgrading to 1.1 old menu would not load so I deleted module and tried to get new version (1.2.1) from gallery, I got this error. Tried removing everything and even deleting 4 tables in DB then downloading the new one (1.2.1). Same error. It looks like for some reason new tables are not created in DB. When I set breakpoint in Migrations -> public int Create() it's not being hit, someone must have solved this on by now. Please share.

  • eyal berman said

    i get an error after installing the menu on orchard 1.1.30

    Request for the permission of type 'System.Security.Permissions.FileIOPermission, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed.

  • FacuD said

    To solve this error "A required anti-forgery token was not supplied or was invalid." . Go to Views -> MenuAdmin -> Index.cshtml and replace

    @Html.ActionLink(T("Delete menu").Text, "Delete", "MenuAdmin", new { Area = "Szmyd.Orchard.Modules.Menu" }, new { @class = "button primaryAction" })

    with this

    @T("Delete menu")

    That's solved for me. Cheers.

    This solution doesn't work if your menu-name contains "main".

  • Sławek said

    Hi Szymon, When I create a menu with name like already deleted menu I have the following exception:

    "Nie można wstawić dwóch wartości pod unikatowy indeks. [ Table name = SzmydOrchardModulesMenuAdvancedMenuPartRecord,Constraint name = UQSzmydOrchardModulesMenuAdvancedMenuPartRecord00000000000002B5 ]"

  • Nasenbaer said

    Hi. After hours of trying I could not delete items. I always receive following error (German): Die gesuchte Ressource wurde möglicherweise entfernt oder umbenannt, oder sie steht vorübergehend nicht zur Verfügung.

    Menu still is available. I think I updated from 1.1 to V 1.2.1 but still could not delete menu item.

  • marktap said

    FacuD said on kwi 28 2011 at 8:06 To solve this error "A required anti-forgery token was not supplied or was invalid." . Go to Views -> MenuAdmin -> Index.cshtml and replace

    Thanks, that worked for me too!

  • marktap said

    I added a new menu, then click on "Add templated item". I wanted to compare to "Add simple item" so I hit back in my browser instead of saving the new menu item. Now I can't do anything with the menu..can't add new items, can't delete it, etc. I get:

    HTTP Error 404.0 - Not Found The resource you are looking for has been removed, had its name changed, or is temporarily unavailable.

    thanks!

  • pszmyd said

    Hi, it's been quite a long time since I replied as I was away and pretty busy recently. Sorry for that. I'll update the menu module with all bugfixes to issues you reported next week. Great thanks for lot of feedback, though!

    @marktap, @FacuD: There is a bug with generated link, as controller needs anti-forgery token, which I forgot to put in the action link.

    @marktap: Weird, I'll check this out.

    @Sławek: It looks like the old menu record still exists in the db (or is being cached somehow) - the menu name column is unique.

    @eyal berman: Are you running your app in Full or Medium trust? I must say I haven't noticed that error before on either mode. The module doesn't read/write any files so the FileIOPermission isn't being requested by the module itself. It looks like an issue with your Orchard instance. Have you set the read/write permissions to the folder where Orchard is located to the user account under which the application runs in IIS (IUSR_ by default)?

    There is also a bug (which some of you already noticed) when Shape Tracing module is enabled. Shape Tracing adds some data to every generated shape to provide more detailed info. Basically, it sets the "Template" property on every shape with the link to the .cshtml template file related to that shape. Unfortunately, the MenuItem shape contains Template property, which is used for something completely different and it gets filled/overwritten... That is why you get the link displayed.

    I guess Shape Tracing creators assumed that no shape would contain property with the name "Template" (ooops!). I'll change the property name and it should help.

    Cheers!

  • david said

    Sounds like you're in the process of some bugs--I might have another. I recently added the Advanced Menu module and, out of the box, the two navigation tabs already in place display incorrectly. Each tab is rendered with a div tag following the link. They have attributes shape-id="14" and shape-id="15" and both contain the inner text "~/Modules/Szmyd.Orchard.Modules.Menu/Views/MenuItem.cshtml"

    Also, if I add subtitles, they are rendered offset and to the right of the Displayed Text for the menu item. The CSS for the Displayed Text is relative, so the subtitle div appears to overlap. Chrome 11, FireFox 4, and IE9 produce the same effect? Do I need to do some initial configuration?

  • david said

    Looks like Bogdan T actually had my issue above. I disabled shape tracing and the menu's seem to be corrected.

    I am still experiencing the problem with "A required anti-forgery token was not supplied" and the suggested solution above didn't work because, I assume, because my menus have the word "main" in them

  • pszmyd said

    @david: Yes, there is an issue with Advanced Menu and Shape Tracing modules being enabled at the same time. I'll fix that (and other known bugs) around the middle of next week.

  • springy said

    I wonder no one reported that "Flatten lower levels?" exactly works the opposite way as the doc says "Leave unchecked if you want to just remove lower levels." -- I have to check it in order to remove limited levels.

    The "Limit levels" value also is very weird -- I have to use "3" to show 2 levels (main + 1 sub). Using "2" I get main + empty-sub.

    There is also a problem with the breadcrumb: It only shows the "home" link at level 2 but not on level 1 -- at least I found no switch to change that.

  • springy said

    The last 2 issues ("Limit levels" and breadcrumb) are related to the same strange thing: The menu structure is polluted with unnamed-nodes-with-single-subitem at each real node. Looks very strange to me.

  • Stuart Moran said

    There are currently issues with server farm use of the module, in that the CounterRecord class isn't serializable and therefore won't work with SQL server session state set up.

  • pszmyd said

    @springy: Thanks, I'll look into both of these issues. @Stuart: I guess it's a deeper problem. CounterRecord is a default Orchard record entity (bound to underlying NHibernate stuff). Entities shouldn't be directly serialized at all (like eg. file handles), because they are bound to database session. I'll try adding a serializable POCO on top on that, so that serializing CounterRecord directly wouldn't happen.

  • pszmyd said

    @Stuart: I managed to fix that - it'll be ok in the upcoming release, which I will publish today.