Extend routing in Episerver Commerce to support custom Segments

casper.rasmussen/ May 15, 2016/ Uncategorized/ 0 comments

Recently we had to support custom segments as part of the Hierachical routing mechanism put in place for Commerce. Optimization of the User Experience required us to support a section specific URL on a fairly advanced product presentation page. Essentially, we needed to support that specific sections – e.g. Model Specifications or Accessories – could be shared and directly targeted – i.e. that http://www.commerce.com/cars/vans/model-x/accessories/ were directly leading the user to the Accessories section of the presentation page for Model X.

Episerver Commerce utilizes the concept of Partial Routing for constructing and reacting to its user and SEO friendly URLs. Such Partial Routing is implemented via a EPiServer.Web.Routing.IPartialRouter. It basically acts as a two-way translator by being the main actor in determining:

  1. How a URL is translated to a Product, Node or Catalog.
  2. How an instance of a Product, Node or Catalog, along with additional route values, is translated into an URL.

With that in mind, supporting this simple request seemed pretty straight forward. Let me show you how we managed to achieve it.

Introducing a Section Segment to Product URLs.

First of all, we want to ensure that any URL, belonging to a Product, supports an optional segment – let us call that segment {section} – with only a list allowed values*:

  1. specifications
  2. accessories
  3. quote
  4. technology
  5. design
  6. interior

First step, in order to achieve our goal, is to extend the default (for most Episerver Commerce implementations at least) EPiServer.Commerce.Routing.HierarchicalCatalogPartialRouter with some additional logic. Below is an empty shell, defining the predefined list of segment values we want to support.

Any Episerver PartialRouter consists of two essential methods. GetPartialVirtualPath helps Episerver generate, via the UrlResolver, a URL for a specific piece of Content. On the other hand, RoutePartial ensures that a given piece of Content is located based on a URL beneath a particular page. Be aware that this particular page will be your Commerce Route Starting Point, which by default is ContentReference.StartPage.

As you may have guessed, these two methods will be our playing-field for supporting the need for a custom segment.

GetPartialVirtualPath

We are, by looking at the incoming route values, determining if we need to append our custom {section} segment to the URL already being resolved for the requested piece of Content. Be aware that we are restricting it to be an instance of ProductContent. Above snippet helps Episerver respond to a URL lookup like this:

Returned value will be something similar to /cars/vans/model-x/specifications/

RoutePartial

When resolving the Content for a URL, we need to ensure that Episerver is not left with our Custom {section} Segment (e.g. /specifications/). That is done by simply skipping that segment and excluding it from our RemainingPath. Telling Episerver about the remaining Segment (e.g. /specifications/) would result in a 404 because no content matching that specific part of the URL exists.

There is one essential thing left. The existing EPiServer.Commerce.Routing.HierarchicalCatalogPartialRouter relies on a method called FindNextContentInSegmentPair. Episerver uses it to internally resolve a Content piece for any segment. Reason why it has to be changed, is that our code (object ob = base.RoutePartial(content, segmentContext);) requests Episerver to resolve Content based on a unmodified version of the SegmentContext. What we need to do, is to tell Episerver how to do a lookup based on the LastConsumedFragment in case the next fragment is a part of our allowed values for the {section} Segment.

Minor changes can be included to e.g. ensure that the current {section} segment is being resolved to something the ProductController can react on. We are, for this example, only allowing the {section} segment to be present in the URL in order for our front-end logic to react accordingly. Please, as with many of my other blog posts, be aware that this has been taken out of a greater context.

How to activate my new Router

Please remember to let Episerver know that you want to control routing via your custom implementation. Below snippet should do the trick and will be a direct replacement of e.g. the existing registration of the Hierachical routing mechanism.

* Having a predefined list ensures that our Hierachical routing mechanism still is fully functional when e.g. requested to serve a variant beneath a product.

Leave a Comment

Your email address will not be published. Required fields are marked *

Please type the characters of this captcha image in the input box

Please type the characters of this captcha image in the input box
You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>
*
*