Hi!
From your route mapping, it looks like you should get a match on /products/bikes/consumer and /products/bikes/business. The {node} part here is actually /products/bikes. I'm no expert on this topic but I tested to intercept the default IUrlSegmentRouter and successfully managed to route to the correct page using a similar scenario. See below for example:
public class CustomerTypeUrlSegmentRouter : IUrlSegmentRouter
{
private readonly IUrlSegmentRouter _defaultUrlSegmentRouter;
public CustomerTypeUrlSegmentRouter(IUrlSegmentRouter defaultUrlSegmentRouter)
{
_defaultUrlSegmentRouter = defaultUrlSegmentRouter;
}
public Func<SiteDefinition, ContentReference> RootResolver
{
get => _defaultUrlSegmentRouter.RootResolver;
set => _defaultUrlSegmentRouter.RootResolver = value;
}
public ContentReference ResolveContentForIncoming(ContentReference contentReference, string urlSegment,
SegmentContext segmentContext)
{
var contentLink = _defaultUrlSegmentRouter.ResolveContentForIncoming(contentReference, urlSegment, segmentContext);
// If we have hit an unknown segment and it qualifies as a customer type segment.
if (contentLink == null && IsCustomerTypeSegmentMatch(urlSegment))
{
// TODO: Maybe validate if incoming content link is actually the products root page.
// Return the incoming content link, in your case "Products".
return contentReference;
}
return contentLink;
}
public ContentReference ResolveContentForOutgoing(ContentReference contentLink)
{
return _defaultUrlSegmentRouter.ResolveContentForOutgoing(contentLink);
}
public IRoutable GetRoutingSegment(ContentReference contentLink, string preferredLanguageBranch)
{
return _defaultUrlSegmentRouter.GetRoutingSegment(contentLink, preferredLanguageBranch);
}
public bool IsContentUnderRoot(ContentReference contentLink)
{
return _defaultUrlSegmentRouter.IsContentUnderRoot(contentLink);
}
private bool IsCustomerTypeSegmentMatch(string urlSegment)
{
// This logic should probably be a bit more advanced. :)
return urlSegment == "consumer" || urlSegment == "business";
}
}
You need to intercept the default segment router. This can be done in an initialization module (you probably already have a dependency injection module):
[ModuleDependency(typeof(ServiceContainerInitialization))]
[InitializableModule]
public class DependencyResolverInitialization : IConfigurableModule
{
public void ConfigureContainer(ServiceConfigurationContext context)
{
context.Services.Intercept<IUrlSegmentRouter>((locator, defaultUrlSegmentRouter) =>
new CustomerTypeUrlSegmentRouter(defaultUrlSegmentRouter));
}
public void Initialize(InitializationEngine context)
{
}
public void Uninitialize(InitializationEngine context)
{
}
}
Hi Mattias and thank you for your detailed answer!
You are correct in pointing out the {node} in this scenario ends up being "/products/bikes/consumer", while I really need "/products/consumer/bikes" instead. I naively tried using a url of "{language}/{node}/{customertype}/{node}/{partial}/{action}" to support this but naturally this didn't work. It appears that segments in-between a node-"path" make things a bit more complicated. Instead of going the segmentbase route I have instead re-implemented the default episerver partial router, looking for customer-type segments in the url and manually stripping it out, and from there looking up the content in the CMS page hierarchy. I had to do this for the commerce router as well. This feels quite intrusive so a simpler method would be awesome.
Hi,
I'm attemping to add a custom segment in the middle of an url. Consider the two urls:
/products/consumer/bikes
and/products/business/bikes
I would like both urls to route to the same page in Episerver CMS.
The cms page structure is:
The consumer and business part of the url is added to the RouteData object in the request context. I believe I have the correct logic for this implemented in a custom segment class that extends the SegmentBase class.
However, what URL should I use when registering this custom segment to the route table? I have tried {language}/{node}/{customertype}/{partial}/{action} but it does not seem to match the mentioned urls to the Bikes-page.
The normal behaviour of the Episerver pages route will render the bike-page when hitting
/products/bikes
, however I am looking for the same behaviour using/products/consumer/bikes
or/products/business/bikes
. Is this even possible to do using only url segments? Or do I need to implement a custom PartialRouter?