Help removing the catalog name from our URL

Vote:
 

Hello all,

I was hoping you could help me resolve what I think should be a simple task that I'm coming up short on.  I'm using Episerver version 9.  Basically, we just want to remove the catalog node name from the URL of our product catalog.  

So in other words, we'd like our product url to change from: http://domainname.com/catalogname/productcategory/productsubcategory/product/ to just: http://domainname.com/productcategory/productsubcategory/product/

After some google research I came up with the following code in my CommerceInitialization class:

using EPiServer.ServiceLocation;
using CMS.Business;
using EPiServer;
using System.Linq;
using EPiServer.Web.Routing;
using EPiServer.Commerce.Catalog.ContentTypes;
using EPiServer.Web;

namespace CodeSamples.EPiServer.Commerce.Catalog
{
    [ModuleDependency(typeof(global::EPiServer.Commerce.Initialization.InitializationModule))]
    public class CommerceInitialization : IInitializableModule
    {
        public void Initialize(InitializationEngine context)
        {

            var referenceConverter = context.Locate.Advanced.GetInstance();

            var repository = ServiceLocator.Current.GetInstance();
            var rootLink = referenceConverter.GetRootLink();
            var catalogRef = repository.GetChildren(rootLink)
                            .FirstOrDefault(x => x.Name == "catalogname");

            var hierarchicalCatalogPartialRouter = new HierarchicalCatalogPartialRouter(() => SiteDefinition.Current.StartPage, catalogRef, false);

            RouteTable.Routes.RegisterPartialRouter(hierarchicalCatalogPartialRouter);

        }

        private static void MapRoutes(RouteCollection routes)
        {
            CatalogRouteHelper.MapDefaultHierarchialRouter(routes, false);
        }

        public void Uninitialize(InitializationEngine context) { /*uninitialize*/}

        public void Preload(string[] parameters) { }
    }
}

(Note: I changed our catalog name in the code above to a generic name for privacy purposes).

Unfortunately this doesn't seem to work.  Or at least I think the product category is working, for example: http://domainname/productcategory/ seems to work but http://domainname/productcategory/productsubcategory/ returns a 404 error.

Am I missing something or am I barking up the wrong tree entirely?  Any help is greatly appreciated, thanks!

John

#163449
Edited, Oct 20, 2016 16:02
Vote:
 

UPDATE:

I figured it out and wanted to share the answer for anyone else doing their homework like I had to do, hehe.

using System.Web.Routing;
using EPiServer.Framework;
using EPiServer.Commerce.Routing;
using EPiServer.Framework.Initialization;
using System.Web.Mvc;
using EPiServer.ServiceLocation;
using CMS.Business;
using EPiServer;
using System.Linq;
using EPiServer.Web.Routing;
using EPiServer.Commerce.Catalog.ContentTypes;
using EPiServer.Web;
using Mediachase.Commerce.Catalog;
using EPiServer.Core;
using EPiServer.Web.Routing.Segments;

namespace CodeSamples.EPiServer.Commerce.Catalog
{
    [ModuleDependency(typeof(global::EPiServer.Commerce.Initialization.InitializationModule))]
    public class CommerceInitialization : IInitializableModule
    {
        public void Initialize(InitializationEngine context)
        {

            MapCatalogRoute(RouteTable.Routes);

        }

        private static void MapRoutes(RouteCollection routes)
        {
            CatalogRouteHelper.MapDefaultHierarchialRouter(routes, false);
        }

        private void MapCatalogRoute(RouteCollection routes)
        {
            // This will pick the first catalog, and strip it from all urls (in and out)
            var contentLoader = ServiceLocator.Current.GetInstance<IContentLoader>();
            var referenceConverter = ServiceLocator.Current.GetInstance<ReferenceConverter>();
            var languageSelectionFactory = ServiceLocator.Current.GetInstance<LanguageSelectorFactory>();
            var routingSegmentLoader = ServiceLocator.Current.GetInstance<IRoutingSegmentLoader>();
            var contentVersionRepo = ServiceLocator.Current.GetInstance<IContentVersionRepository>();
            var urlSegmentRouter = ServiceLocator.Current.GetInstance<IUrlSegmentRouter>();
            var contentLanguageSettingsHandler = ServiceLocator.Current.GetInstance<IContentLanguageSettingsHandler>();

            var firstCatalog =
                contentLoader.GetChildren<CatalogContent>(referenceConverter.GetRootLink()).FirstOrDefault();

            var partialRouter = new HierarchicalCatalogPartialRouter(
                () => SiteDefinition.Current.StartPage,
                commerceRoot: firstCatalog,
                supportSeoUri: false,
                contentLoader: contentLoader,
                languageSelectorFactory: languageSelectionFactory,
                routingSegmentLoader: routingSegmentLoader,
                contentVersionRepository: contentVersionRepo,
                urlSegmentRouter: urlSegmentRouter,
                contentLanguageSettingsHandler: contentLanguageSettingsHandler);

            var partialRouter2 = new HierarchicalCatalogPartialRouter(
                () => SiteDefinition.Current.StartPage, firstCatalog, false);

            if (firstCatalog != null)
            {

                routes.RegisterPartialRouter(partialRouter2);
            }
        }

        public void Uninitialize(InitializationEngine context) { /*uninitialize*/}

        public void Preload(string[] parameters) { }
    }
}
#163454
Oct 20, 2016 17:39
Vote:
 

Is your partialRouter variable really in use? 

#171543
Nov 10, 2016 7:54
Vote:
 

Hi John,

Please note  if your site is powered by EPi find then the above piece code will not allow the products to index in Epi Find... :(

Regards

Venkata Phani Kumar R

#172034
Nov 24, 2016 2:45
Vote:
 

Same to your solution but shorter:

        private static void MapRoutes(RouteCollection routes)
        {
            var contentLoader = ServiceLocator.Current.GetInstance<IContentLoader>();
            var referenceConverter = ServiceLocator.Current.GetInstance<ReferenceConverter>();

            var firstCatalog = contentLoader.GetChildren<CatalogContent>(referenceConverter.GetRootLink()).First();
            routes.RegisterPartialRouter(new HierarchicalCatalogPartialRouter(() => EPiServer.Web.SiteDefinition.Current.StartPage, firstCatalog, false));
        }
#172219
Edited, Nov 28, 2016 5:15
Vote:
 

John, In your answer you are intializing "var partialRouter = " but not using it otherwise its same as @Son Do have answered.

/K

#172228
Nov 28, 2016 13:19
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.