We're using the standard integration between inRiver PIM and EPiServer Commerce 7.5 to create catalog node, category nodes, products and variants in Commerce.
When the category nodes and products are created the name in url is populated with a value that seems to be globally unique within the entire catalog not unique among the siblings within a category. For example if there are many subcategories named dog the name in url will be dog, dog-1, dog-2 and so on even though they are in different categories.
Is there a way to change this behaviour and change the value for name in url so that it is unique only among siblings within a category?
I forgot to mention that the Mediachase.Commerce.Catalog.ImportExport.CatalogImportExport class is used when importing the data and creating the catalog tree in Commerce.
This behaviour apply even without the inRiver integration. It appears that the "Name in URL" must be unique globally - for products. It does not apply to categories.
Given the nature of the catalog, where linking products to multiple categores is normal, having a globally unique url segment makes sense. Though I can see the opposite view too, you want to have full control of the url.
Thanks for your reply, Steve.
I can understand that products must have globally unique "Name in URLs". But I can't see why categories get globally unique name in urls when using the category import api. Something must be wrong with the import functionality, or have I completely misunderstood how name in url works?
Categories do not get globally unique urls out of the box, but I understood the question to be about the products. So what you mean is something like this:
Pet Shop Catalog Food (/food) Dogs (/food/dogs) Cats (/food/cats) Collars (/collars) Dogs (/collars/dogs-1) Cats (/collars/cats-1)
Which I can reproduce from the inRiver Import. However, the import does not provide a value for the url segment, so it is automatically set during import. Not sure exactly where this happens, but it seems to be out of control for the inRiver Connector.
From research I have previously undertaken all catalog content has a default Code value that is constrained to be unique; Entries and Nodes alike. There is also software attached that appears to ensure that any manually entered Code values are unique as well.
This maybe a design decision because the SEO URI value is derived from the Code value and as the SEO URI is the Commerce equivalent of the CMS "Simple Address" then the SEO URI value has to be unique within all of the managed content.
To take over the behaviours associated with generating the Code and the SEO URI values from the Name value the class Mediachase.Commerce.Catalo.Data.UniqueValueGenerator can be replaced by your own implementation. However, I am afraid that I do not know whether your ambition to change the scope of uniqueness for Catalog Nodes from globally to just sibling-wide uniqueness will not have fringe effects.
I have used a derived class of UnqiueValueGenerator to rid myself of the annoying habit the default class has of suffixing all SEO URIs with ".aspx".
That's exactly the behavior I experience. I also believe that this is out of control for the inRiver Connector. Somewhere in the Epi catalog import/export api the "name in url" values are set.
Martin, good input.
When you create the categories manually, it suggests the Code to be "Internal Name" + "_" + counter. The SEO Url is not based on the same counter it seems, cause for code "Nikon_1" I'm at SEO Url "Nikon-5-en.aspx".
The Name in URL is correct, just "nikon", even though I have other categories with the same url segment.
Adding another "Nikon" to the same parent category gives me:
Name in URL: "nikon2"SEO URL: "Nikon-6-en.aspx"Code: "Nikon_2"
So, I'm inclined to categorize this as a bug. Could you please register it Simon?
Whilst I can see where you are coming from, I think you ought to take a quick look at the implementation of UniqueValueGenerator.
I can forsee that the scenario you are experiencing is plausible and explainable from the implementation of this class coupled with whatever other data you already have hanging around in your system. This in turn may transform the assertion of "bug" to a merely a difference of opinion.
We have already registered this as a bug.
Martin, not sure what you mean, there might be something I'm missing in there, but url segment is not generated by using the UniqueValueGenerator.
From what I can see in CatalogNodeAdmin, the GenerateSeoUriSegment tries to do this right, but I'm not able to verify if actually does it.
I think we'll leave that in the capable hands of Developer Support to investigate.
Simon, if you add the ChannelNodeSEOUriSegment field to your model (ChannelNode), you can control the value yourself. The importer will happily use that.
Note! You'll have to make sure you don't have duplicate uri segments yourself, which I guess should not be such a big issue to enforce for nodes. You can even create an inRiver extension to check this.
well I might also be missing something also. It has been known to happen :}
The value you highlight as being equal to "Nikon-6-en.aspx" and being the property not taking on the value you would expect, is not the value I would associate with the SEO URL Segment, but with SEO Uri.
i.e. CatalogNodeDto.CatalogItemSeoRow.Uri, and notCatalogNodeDto.CatalogItemSeoRow.UriSegment
Consequently, that is why I point you towards the unique value generator as a candidate area of interest for you.
The method UniqueValueGenerator.SuggestSeoUri is the method that contains the code that adds the ".aspx" suffix along with the stem prior to the ".aspx".
The method CatalogNodeAdmin.GenerateSeoUriSegment would not appear to create a value that would ever contain ".aspx" and so I don't immediately see why that method would be associated to your question/problem.
But as you say, can't beat the experts
Martin, I see where the confusion comes from, this was never about the SEO Uri, but the "Name in url", which is the SEO Uri Segment, or just "Url Segment". I listed the SEO Uri too, to see if I could see a pattern in how the SEO Uri Segment was generated.
Yep, see that now. Thanks
Steve, we will await the response from EPi regarding our bug report. If this is not recognized as a bug, we will add the ChannelNodeSEOUriSegment field to our PIM model as you suggested.
We are having the samme issue on a customer site. However im not used working with commerce or inriver so im pretty much just guessing.
However i found this link: http://world.episerver.com/blogs/Magnus-Rahl/Dates/2013/12/Replace-SEO-URL-generation-in-EPiServer-Commerce-75/
And i tried it out. the UniqueValueGenerator gets configured but is never used when im debugging.
I tried from the commerce manager inside episerver ui to change the url(en) of a channel node from Loader-cranes-100-en.aspx to Loader-cranes-en.aspx but i get this exception:
[ConstraintException: Column 'LanguageCode, Uri, ApplicationId' is constrained to be unique. Value 'en, Loader-cranes-en.aspx, a49f5036-39d4-4549-828b-9e61768dda3d' is already present.] System.Data.UniqueConstraint.CheckConstraint(DataRow row, DataRowAction action) +2579825 System.Data.DataTable.RaiseRowChanging(DataRowChangeEventArgs args, DataRow eRow, DataRowAction eAction, Boolean fireEvent) +6747476 System.Data.DataTable.SetNewRecordWorker(DataRow row, Int32 proposedRecord, DataRowAction action, Boolean isInMerge, Boolean suppressEnsurePropertyChanged, Int32 position, Boolean fireEvent, Exception& deferredException) +6747215 System.Data.DataRow.EndEdit() +148 System.Data.DataRow.set_Item(DataColumn column, Object value) +502 Mediachase.Commerce.Manager.Catalog.Modules.SeoTab.SaveChanges(IDictionary context) +346 Mediachase.Commerce.Manager.Catalog.Tabs.NodeSeoTab.SaveChanges(IDictionary context) +970 Mediachase.Commerce.Manager.Core.Controls.EditViewControl.SaveChanges(IDictionary context) +280 Mediachase.Commerce.Manager.Catalog.CatalogNodeEdit.EditSaveControl_SaveChanges(Object sender, SaveEventArgs e) +178 Mediachase.Commerce.Manager.Core.SaveControl.OnSaveChanges(Object sender, EventArgs e) +58 System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument) +155 System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +3804
currently i have no idea how to progress or what to try. My college here at work has open support cases with both inriver and episerver and none of them seams to know and blames the other...
Might be worth to mention also is that i think we are running Commerce 8.0
Hi Mattias Jöraas
I'm not sure if there's a support case to your issue at the moment. But for your issue, it's quite clear that Loader-cranes-en.aspx is already existed in the database, while uri per language is supposed to be unique. I expect the control to validate your input uri instead of throwing error - but I can remember it wrong. How exactly can I help you with this?
Currently our customer gets urls like this:/global/products1/loader-cranes-100/hiab-10/products/hiab-008t/selected-brand-hiab/ (this is the global site eg. /en/, there is also a specifik US site eg. /en-us/)
they want to remove all the extra numbers in the url to get it more clean looking eg./global/products/loader-cranes/hiab/products/hiab-008t/selected-brand-hiab/ (hiab-008t is an actual product so this is correct).
I know my college has been in contact with both inriver and episerver about this, if there is an active case or not i really dont know but it sounded like it to me.
I did my own override class for UniqueValueGenerator and configured to service locator but it is never used.
I'm in the process of setting up my commerce catalog using the built in "Commerce Manager - CSV Import Catalog" functionality. I was able to get all my products / variants loaded, but the "Name in Url" is not what I was hoping for. It contains my product name followed by a random eight characters. What I don't understand is that if I manually create a product it doesn't append anything to the "Name in Url". Also, I don't see a way to map the "Name in Url" property through the tool.
The catalog is set up for the following languages:
Example - When uploading through the tool.
Code = p-2859543Name = 2859543Name in Url(en) = 2859543-ae329d3aName in Url(en-CA) = 2859543-b67sea41Name in Url(fr-CA) = 2859543-z8sie3ks
Example - When I create a product manually in "Commerce - Catalog" - "New - Product"
Code = p-123456Name = 123456Name in Url(en) = 123456Name in Url(en-CA) = 123456Name in Url(fr-CA) = 123456
In reading this thread I noticed a comment from Quan Mai that the Uri needs to be unique by locale, but when I look in the database (ecfVersion) the SeoUriSegment is the same for all "versions / locales" when I manually create the product, but when uploading through the tool each locale has a unique eight characters appended to that field.
I would like the "Name in Url" to be just the product name... any idea how I can do this through the tool rather than writing my own solution?
A quick glance at the (decompiled) code indicate that the UriSegment is never set during CSV import.
Is there a possibility that you can use the XML import instead? That can also be called from the Service API. If not, using the regular catalog methods in the Service API is also an option.
Or, writing your own import routine instead, will give you full control. Here is an example using the Content API: https://github.com/BVNetwork/CommerceStarterKit/tree/master/src/CommerceStarterKit.CatalogImporter
Thanks Steve. I'll look into one of the other options. I appreciate the help.