Brian McKeiver's Blog

Custom Document Aliases in Kentico CMS


(Note: this post assumes that you read the primer post on URL Rewriting & Aliasing in Kentico CMS)

 

In my last post I described what it takes to use the URL Rewriting and Document Aliasing capabilities of Kentico. I also promised a twist to those who made it through the entire blog post, and here it is. So without further ado, I now present my solution for creating a Custom Document Alias in Kentico that is QueryString aware.

Let’s get started. Now that you understand more about URL Rewriting say you had a URL like this:

 

http://mcbeev.com/products/item.aspx?type=Chips&name=Baked Lays

 

Pretend for a minute that your store also sold candy bars, and we decided to reuse the same old page to display both types of products. We would still have a URL like:

 

http://mcbeev.com/products/item.aspx?type=Candy Bars&name=Snickers

 

Our example translated into a standard Kentico setup:

 

Kentico CMS Content Tree

 

And here ladies and gentlemen we hit our first snag with the Kentico CMS out of the box and aliasing. You can URL Rewrite and even Document Alias any node in the content tree. However, the one small gotcha is that you can not create an Alias that looks at QueryString values, or anything after the question mark.

The default Kentico engine will just replace any special character with a dash in the in the URL Path or URL extension field of the Document Alias, therefore wiping out the important part of the QueryString that our example URL above is relying on.

I have actually run into this in my real world projects where I am upgrading a pre existing site that has lots of old links from it’s website as well as other websites that match the URL format in our above example.

Bummer.

To fix this we have to get a little creative and write some code. This is a two part solution. First, we need to make a generic redirector page with a Document Alias of the first part of the URL above.

I created a new page called RedirectItems at the root of my Kentico site and then added a Document Alias like so:

 

Kentico URLs tab

 

The purpose of this page will be catch all the incoming requests regardless of QueryString value, and hand it off to the right place after running a bit of code on that page, or Web part.

The next step we need to do is create a new custom Web part. The purpose of this new Web part will be to to grab the information out of the the request that we need. To do so I used these instructions from Kentico on how to create a new custom Web part.

 

Kentico CMS WebPart Redirector

 

The key here is that we create the new Web part called Redirector (or whatever you like) and then give it one Property called RedirectToPaths. This is where you will set your URL templates for how we can handle the QueryString redirects.

 

Kentico CMS WebPart Redirector 2

 

At this point you are safe to click save on the Create Web part Screen. Next we need to add in some code to our Web Part.

Once the new Web Part is added in the CMSSiteManager and the file is in ~/CMSWebParts/Your Category Name/ you can open up the source code of Redirector.ascx.cs with your favorite Text Editor or Visual Studio.  And add the following OnPreRender method.

 

protected override void OnPreRender(EventArgs e)
{
 base.OnPreRender(e);

 if (this.StopProcessing)
 {
  // Do nothing
 }
 else
 {
  //Collect the URL information from the current Request
  string currURL = HttpContext.Current.Request.RawUrl;
  string queryString = string.Empty;
  string newURL = string.Empty;

  //Check to make sure some query string variables exist
  int iqs = currURL.IndexOf('?');

  //QueryString variables exist, put them in a string.
  if (iqs >= 0)
  {
   queryString = (iqs < currURL.Length - 1) ? currURL.Substring(iqs + 1) : string.Empty;
  }

  if(queryString.Length > 0)
  {
   //Parse the querystring  
   NameValueCollection qsKeys = HttpUtility.ParseQueryString(queryString);

   //Pull in the Path Expressions from the Web Part property called RedirectToPaths
   string redirectToPaths = (string) this.GetValue("RedirectToPaths");

   //If the property is empty do nothing
   if(redirectToPaths.Length > 0)
   {

    //Split out the property value by a comma in case there are multiple
    foreach(string p in redirectToPaths.Split(','))
    {
     string path = p;
     bool allKeysInPath = true;

     //Iterate through the keys and replace the key with the value
     foreach (string key in qsKeys.AllKeys)
     {

      if(path.Contains("{"+ key + "}"))
      {
       path = path.Replace("{"+ key + "}", qsKeys[key]); 
      }
      else
      {
       allKeysInPath = false;
      }
     }

     //Handle whitespace
     path = path.Replace(" ", "-");

     //Make sure we got a redirectToPath that handles all the keys
     if(allKeysInPath)
     {
      newURL = path;
      break;
     }

    }

    //Check if we generated a new URL
    if(newURL.Length > 0)
    {
     //Redirect to our new path
     Response.Redirect(newURL);
    }

   }

  }
 }
}

 

 

 

That’s all the code we need to touch, so close and save the file. Now let’s add our new Redirector Web Part to our site. Open up the CMSDesk again and go to where you created the page called RedirectItems from above. Click on the Design tab of the page and add in new Redirector Web Part that we just created. Then click configure. You should be at a modal window that looks like this:

 

Kentico CMS WebPart Redirector 3

 

Notice our RedirectToPath property shows up and I have typed in two URL templates. Go ahead and copy the second string /Products/{type}/{name} into your Web part. Then click OK. I think you can probably guess how that maps to our original problematic URL of:

 

http://mcbeev.com/products/item.aspx?type=chips&name=Baked Lays

 

Basically the code will replace anything inside the curly brackets that matches the name of the parameter with the value of the parameter. So for the preceding example, we will end up being redirected to the correct location of:

 

http://mcbeev.com/Products/Chips/Baked-Lays

 

So there you have it, this custom Web part will now give us a small enhancement to the built in ability of Document Aliasing for Kentico CMS. The code for the Web part can be found at the link below.

I hope this idea helps you maintain working links when upgrading a pre existing site the way it did for me. As always please feel free to leave feedback for me in the comments.

 

Web part code download