In today's tutorial, I will show you how to implement a partial router within Episerver. If you want to know what a partial router is, then first please read Dummy’s Guide To Explaining Partial Routing Within Your EPiServer. We will do this by implementing a basic blog. The blog will be populated by a blog home page.
To make life interesting, in the editor's page tree, the blog pages will not live directly on the blog's home page but will live on a blog section outside of the main web tree. Every blog will be associated with a category. For SEO reasons we want the URL for anyone to access a blog page to be in the following format:
When we visit the 'jonsblog' page, we will see the blog home page view:
When we visit the 'development' page, we will see the category pageview:
When we visit the 'blog-page-1' we will see the blog page view:
I know what you're thinking... wowed by the graphics of my blog. If you need me for design work, use the contact form on the side :) It also means I can spin out another blog post from this :) Finally, we'll look at the Episerver page tree for the site, which will be structured like this:
As we want the final URL to a page to be 'blog home -> category -> blog page' we will need a way to route any requests to the blog home, grab anything in the URL to the right of it, like 'category' or 'blog page' and then re-route MVC to a different controller and subsequently a different view.
The first thing we need to do is define our page types:
You may notice I'm using a [SelectOne] for the blog category. I won't cover the code here (it's in the associated project download) but if you want to learn more about selection factories, I recommend reading How to Create a Selection Factory From a Page Type in Episerver The selection factory will be used to select a category page type which is defined below:
In the partial router, we will need to do things like getting the category and blog pages themselves. For good coding practice, I'm going to extract all this code into their own classes, called CategoryRepository and BlogRepository. You don't need to do this but it will make your code a bit easier to test.
These two classes are pretty straightforward and don't have anything to do with the routing magic. When we get a URL segment like 'development' or 'blog-page-1' then we need a way get the data we care about.
Now we can finally define the partial router:
To create a partial router, we need to implement it from IPartialRouter
I'm passing in the two repositories we created. These will be used to look up the page data in the URL segments. I'm also defining the blog page which is a link to the blog container where all the blog page will live. If you're implementing this, then basically pass in anything that you need to find the pages/data you care about. The next bit is where the magic happens:
We pass in the page type that will trigger the partial router (blog home page) and a Url segment. You can think of this like an array of the URL segments, so 'on blog' will be one element, 'development' will be another and 'blog-page-1' will be the last one. The first two lines are making checks to see what segments are available in the request
If we have a blog page segment then we need to check our blog data store to see if we have a matching page type, so we call the blog repository to check. If we find a match great, we send matching the blog page back. MVC will h=then look for a matching controller. If we don't, we should return null so a 404 error occurs. If no blog page segment exists and a category page exists we pretty much follow the same process, or, using the category repository to try and find a matching category page that has the URL segment as the name. If it exists, pass it back else return null and a 404 will occur.
Registering The Partial Router
To trigger the partial router we need to create an Initialization Module. If you haven't come across one of these yet, I would recommend reading Initialization Modules Explained.
This code is pretty simple we new up our custom BlogPartialRouter passing in the constructor items we defined. We then register it using Episervers RegisterPartialRouter. Note this is a custom extension method so you need to include using EPiServer.Web.Routing; namespace
Controllers & Views
Now we have a system that will re-route any matching URL segments. We need to define the controllers and views to trigger them:
Blog Home Page
The the view
The the view
Welcome to the category page @Model.CategoryName
Well, it takes a shit load of code but we finally got there! If you have followed the steps (use the working project sample from my GitHub if you're having issues) you should have a basic blog working that does partial routing for two different page types. We basically defined three-page types, one to trigger off our customer routing and that defined the pages.
Any of the Url Segments to the right of the blog home page bit in the Url ,we try to match up to pages that exist within Episerver. If we have a match, we pass that page type back and MVC then triggers a matching controller and renders what we need. If we don't get a match a 404 page is displayed.
All the above code can be downloaded in a fully working website from my GitHub account here. JonDJones Base Build