Menu Import bug

Topics: Core, General, Troubleshooting
Aug 2, 2013 at 4:46 AM
Edited Aug 2, 2013 at 4:48 AM
Running a recipe or import/export multiple times will import the Menu's many times causing multiple menus with the same name.

I've investigated this further and the issue lies with a missing IIdentityResolverSelector for "name"
<Menu Id="/name=Main" Status="Published">
      <CommonPart />
      <TitlePart Title="Main" />
    </Menu>
The simple fix would be to create a Menu IIdentityResolverSelector there is one small issue though. The MenuHandler defines the identity of a menu as "name" this is a bit generic and may cause issues in the future it should really be changed to "menu" although this may cause backwards compatibility issues.
protected override void GetItemMetadata(GetContentItemMetadataContext context) {
            if(context.ContentItem.ContentType != "Menu") {
                return;
            }

            context.Metadata.Identity.Add("name", context.ContentItem.As<TitlePart>().Title);
        }
Another fix would be to attach an IdentityPart to the ContentType Menu, although this is probably not the correct fix.

I've raised the following work item https://orchard.codeplex.com/workitem/19967
Aug 5, 2013 at 12:11 AM
Anyone have any comments on how this would be best fixed? I'm happy to take the bug and submit a fix.
Developer
Aug 5, 2013 at 12:55 AM
I think it makes sense to attach the IdentityPart to the Menu type, because otherwise we would have to implement something similar as part of MenuPart (e.g. store a GUID to uniquely identify it).
Aug 5, 2013 at 3:15 AM
The disadvantage with attaching an IdentityPart is that it will not work for updates across different sites, unless it was imported with the same GUID as the existing menu.

i.e. You could end up with multiple menus named "Main" if they contain a different identity/GUID... When you would expect this to update the existing "Main" menu.
Developer
Aug 5, 2013 at 5:48 AM
Sure, but I thought that was the point: to uniquely identify a content item.
If you have two content items with the same name but with different GUIDs, they are different things.
But I suppose that if you do want to identify menu items by name, then your code snippet of the content handler makes sense, but then there's the danger of other types of content using the same approach, using the same title, creating conflicts.

Perhaps something in between will work: adding not only the title, but a hardcoded value of "menu" to signify a category.
E.g.:
context.Metadata.Identity.Add("type", "menu");
context.Metadata.Identity.Add("name", context.ContentManager.GetContentItemMetadata(Item.ContentItem).DisplayText);
Aug 14, 2013 at 4:50 AM
The option you have proposed I think is the correct one. Essentially your saying if importing content of type => menu, and with the same name. Then treat this as the same content Item. This is what I want to do and how i would expect it to work.

To implement this it will require the creation of 2 new IIdentityResolverSelector one for "name" and one for "type"

This also has the advantage of being able to be used to any content items you want to treat as the same if they have the same name and type.

I'll create the revolvers in the same namespace as the Identifier resolver: Orchard.Core.Common.Services.IdentifierResolverSelector

Are you happy with this solution for a pull request?
Developer
Aug 16, 2013 at 7:55 AM
Personally I would prefer adding the IdentityPart, but perhaps others have different opinions. Please create an issue with a reference to this discussion, so we can discuss this during triage. Thanks.