I've previously blogged in EPiServer 7 Routing For Dummies which talked a bit about segments in Episerver. Today we're going to go one step further and create our own custom segment.

What is a segment?

In the switch over to .Net and MVC the way Url's are generated are very different.  In the old static html life world, we created folders and html files.  The websites Url structure was made up of this folder and file hierarchy. With MVC we have controllers and actions and Url's are based on the controllers name and the methods declared in them.  In the background these are wired up to views and Url's etc.. are all handled by this thing called routing. When you work with routing in MVC you will have to start playing with custom routes, like this one

The above snippet defines two segments {controller] and {action}. It tells MVC that when it finds a match on these two segments, do something. When we add Episerver into the mix they introduce a few of their own custom segments, the blow code defines a default Episerver route:

In Episerver, as we have page types we don't do any matching on controller directly as pages can live anywhere in a virtual hierarchy in the editor.  Instead we have {node} which will contain an Episerver content reference.  This is the thing that make the current page magic works.  We also defined {language} segment to deal with multi-language if you're using it.

Custom_Segment

In this example then search is the first segment and about is the second segment.

Why would I need to create a custom segment?

The most common scenario of why you will need to create a custom segment is to probably SEO wise to make your url's a bit more user friendly. In the old world let's say you had a search page that you used a query string to pass in the search result

www.website.com/search/?search=searchterm

With MVC we can make the URL look a lot more cooler by using the URL to pass in the search query, like so:

www.website.com/search/Searchterm

There are loads of variations of these types of requirements like tagging, categories, news , pagination etc..

Creating a custom segment

What we're going to do is define our own segment for a search page and then populate a search term parameter so the search term is automatically passed into a controller.

So, to create a custom segment, we need to either inherit from SegmentBase or ParameterSegment.  When you inherit from SegmentBase you have to implement GetVirtualPathSegment and RouteDataMatch.  Instead of implement from ParameterSegment, we only have to implement GetVirtualPathSegment

In GetVirtualPathSegment, what we're going to do is check that the current page request is of type search page.  If it is populate a segment called "searchterm".  This means if we have an input string called search term in our search controller it will automatically be populated.  The text it will be populated by will be the next segment, e.g. searchterm

www.website.com/search/searchterm

In our code the first thing we do is get the actual segment value itelf

This should return us the text 'searchterm' in our example. The next bit will assign the segment value into a custom segment.

In this method, we're using the Episerver API to check if the current page is the search page.  If it is, then we set the current segment into RouteData and assign it to [Name]. If the page isn't a search page we carry on and process the page as normal.

Registering The Segment

The last part of the puzzle is actually registering our customer segment.  This is done in the global.ascx file.  If we don't set the pages up correctly, we'll get a 404-page error as the MVC handler won't know how to translate the Url into the correct Episerver age to use. I should warn you it can be a bit of a pain to debug this when you set it up wrong. 

Whenever you get a 404, what we need to do is whenever a match is made on an action, call our custom segment handler so we can tell MVC that we have a correct page match and then populate our custom search term route data.

I'll hold my hands up that this bit was copied off another blog.

Conclusion

Today we've gone over what a segment is.  When we use MVC routing we need a way to map the url to a controller, action method or anything we want.  This is really useful for SEO friendly Url's.  Instead of using query string values we can add the old query string values directly into the Url if we want to. To add this type of feature we need to create a custom segment.

We can do this by either inheriting from SegmentBase or ParameterSegment. In this example, we add the code to only add data into the routing data for search pages only.  If we wanted to populate search terms on any page, then we could simply remove the page type check. The last bit is registering the segment in the global.ascx. We use the action segment to perform the match and then register a custom route for it.

All the above code can be downloaded in a fully working website from my GitHub account here. JonDJones.com.EpiSiteSearchSampleSite