In this tutorial, you will learn how to implement a partial router within Episerver CMS. If you want to know what a partial router is, first please read Dummy’s Guide To Explaining Partial Routing Within Your Episerver. In today's tutorial, I will show you how to implement a basic blog within your Episerver project.
To make life interesting, in the page tree within the editor, the blog pages will not live directly under the blog's home page. Instead, they will live in a blog section outside of the main web tree. Every blog will be associated with a category. For SEO reasons I want the URL for anyone to access a blog page to be in the following format:
This URL will be converted into segments like this:
When a site visitor, visits the jonsblog
page, I want the blog home page to look like this:
When someone visits the development page, they will see a category page:
Finally, when someone visits the blog item page, they will we will see this:
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 😊. For completeness, the Episerver page tree for the site, will be structured like this:
Not having the blogs items under the blog listing page creates a challenge. How will someone view the blog page as the URL will not work? As the pages sit outside of the homepage, there is no direct way to publically access these pages. Even though the page tree is structured differently, I still want the URLs in the frontend to work as you would expect:
Blog home
âž¡ Category
âž¡ Blog page
We will need a way to route any requests to the blog items and return the CMS content. To do this we need to create a partial router to re-route the routing rules so a controller and subsequently a view can be triggered 💥
The Code
Before getting to the partial routing code, I will walk you through all the page-type code and the HTML within the views required to build this example:
Blog Home: This will be the page-type used to power the main blog landing page:
Blog Page: This will be the page-type for the blog item page:
You may notice I'm using a [SelectOne]
for the blog category picker. I won't cover selection factories in detail here. 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:
This is the page-type code nailed. Let's look at the rest of the code. In the partial router, we will need to get the category and blog pages from within the CMS. For good coding practice, I'm going to extract all this code into utility classes. I will call these CategoryRepository
and BlogRepository
You don't need to follow this pattern, however, it will make your code a bit easier to test.
Category Repository:
Blog Repository:
These two classes are built using pretty straightforward Episerver CMS stuff. Use IContentRepository
to get the CMS data we want to work with 💥
Partial Router
With the set-up code done, we can create the partial router. Create a new class:
To create a partial router, we need to inherit from PartialRouter<T, T>
. The first parameter T
is the page type that triggers the route. In this example, wherever the blog page typed is referenced we want the partial router to trigger. This bypasses Episerver's normal routing by finding the router first instead of palming the request off to the rules in the routeing table. In the constructor notice this code:
I'm passing in the two repositories created above. These will be used to look up the page data based on the requested URL segments. I'm also defining a link to the blog container (this is where all the blog pages will live in the CMS page tree). If you're implementing this, basically in here add all code to find the pages/data you care about. The next bit is where the routing magic happens:
I pass in the page type that will trigger the partial router (blog home page) and the Url segment. You can think of this as an array of the URL segments, so in this example, we have three segments in the array, blog
, 'development' and 'blog-page-1'. Lines 3 and 5 above, check to see what segments are available in the request:
If we have a blog page segment, we need to check our blog data store to see if we have a matching page in the content tree. If a match is found, great. The router sends the matching CMS content for the blog back. The page request will then move onto the normal routing rules. The rules will try to map a request to a controller based on the page type. If no controller for that type exists, we should return null
and a 404 error occurs.
The process is the same for the category page. Try to 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 on the frontend:
The final step is to register the partial router within Episerver using an Initialization Module. If you haven't come across one of these yet, I would recommend reading Initialization Modules Explained:
In here, register BlogPartialRouter
and make sure the constructor items it uses are also registered. We register the router using the Episervers RegisterPartialRouter
call. Note, this is a custom extension method so you need to include the Episerver.Web.Routing
namespace in the code:
Controllers & Views
We have a system that will re-route any matching URL segments to blogs and categories. The final step is to define the associated controllers and views:
Blog Home Page Controller: The controller:
Blog Home Page View: The view:
Blog Page: The controller:
Blog Page View: The view:
Category Page: The controller:
Category Page View: The view:
That's it 🔥🔥🔥
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 the partial routing for two different page types. We have a way to decouple the site URL from the page tree structure. All the above code can be downloaded to a fully working website from my GitHub account here. Happy Coding 🤘