Sharing is caring - The 301 Url Tracker

Heads Up!

This article is several years old now, and much has happened since then, so please keep that in mind while reading it.

This post is all about the 301 Url Tracker package, which I've built 3,5 years ago as my graduation project here at InfoCaster, which I passed by the way ;-)

Richard Soeteman came up with the idea for this package (have you checked his excellent SEO Checker package by the way?) and thought it would be nice for me to build it, and so it began!
I'd also like to tell a bit about the open-source philosophy at the company I work for, InfoCaster, and the single assembly practice, which I've used for version 2 of the Url Tracker.

301 Url Tracker

Maybe you've heard about it or even used it, I do hope so! If not, this paragraph is for you! This package helps you with managing URLs in you umbraco website. It's a very nifty tool for redirecting indexed URLs of your old website to your new umbraco website. This way you won't lose the current SEO ranking. In fact, it's possible to create any redirect you want, even if a page already exists for the chosen URL to redirect from (since v2.4.0). If you want to learn more about the package, have a look at the project's page!

The Url Tracker overview UI
The Url Tracker overview UI

Version 2 of the Url Tracker is much better than the first version. It has been rebuilt from the ground up to support multi-domain umbraco websites, logging and other nice features version 1 didn't have. Besides that, the quality of the code is a lot better. I've also started using Github for source control and maintained a detailed changelog for every version 2 release.

I've chosen to use a single-assembly approach for version 2, because it wat such a hassle to do upgrades with v1 (from v1.x to v1.vNext). Also I've tried to change as few files as possible. Version 2 only makes a change to the Dashboard.config file. The HttpModule is configured dynamically by using the DynamicModuleUtility.RegisterModule method.
The huge benefit of this approach is that it's really easy to update the Url Tracker; just replace the assembly or install the newer version via the umbraco back-office.

InfoCaster's open-source philosophy

At InfoCaster we strongly believe in open-source and love Microsoft .Net. This seems to be a contradicting affection, but it's exactly why we've selected Umbraco in the first place. Although we've had some serious issues with Umbraco in the beginning, we have kept using Umbraco and promote it as a platform to our customers.

In the true spirit of open-source, at InfoCaster, we think that using open-source also means contributing to the community. We have actively been part of the community ever since starting and using Umbraco. It was a logical step for us to create an open source package when we ran into 301 redirecting problems for our customers. Having this feature in Umbraco would be beneficial for all Umbraco users, instead of just our clients.

Keeping Umbraco competitive and free is good for the reputation of Umbraco, a good reputation for Umbraco is also good for us.
Even when we have gotten feedback that the improved second version of the Url Tracker should become a commercial package, we never doubted our decision to make it open-source and free for anybody to use.

If we all keep sharing and caring about Umbraco and each others tools, I think we can stay ahead of other open and even closed source CMS vendors.

Discussion on Twitter about commercializing the UrlTracker
Discussion on Twitter about commercializing the UrlTracker

Single assembly packaging

I really wanted to keep version 2 of the UrlTracker as simple as possible, especially when it comes to installing, configuring and upgrading the package! That's why I've decided to make sure the UrlTracker consists of a single assembly, nothing more. This assembly contains all resources used by the UrlTracker, like CSS, javascript, images and SQL files, just like uComponents does. I've also made a built-in installer to install the SQL table, dashboard entry and perform some additional checks.

When I started developing this package, I knew very little about how to build a complete package into a single assembly, so I started off by looking at the uComponents source and searching for information on the web about this topic. Inclusing basic resources like CSS, javascript and images wasn't that big of a deal, as long as you'll set the Build Action to "Embedded Resource" and add an entry in the AssemblyInfo.cs file:

[assembly: WebResource("InfoCaster.Umbraco.UrlTracker.UI.res.css.urltracker.css", "text/css", PerformSubstitution = true)]

An example entry for the AssemblyInfo.cs file

Setting PerformSubstitution to true gives you the ability to reference embedded image files within your stylesheet:

[class^="icon-"],
[class*=" icon-"] {
	background-image: url('<%= WebResource("InfoCaster.Umbraco.UrlTracker.UI.res.img.glyphicons-halflings.png") %>');
}

And here's an example of loading static resources in your mark-up:

<link rel="stylesheet" type="text/css" href="<%= Page.ClientScript.GetWebResourceUrl(typeof(UrlTrackerResources), "InfoCaster.Umbraco.UrlTracker.UI.res.css.urltracker.css") %>" />
<script type="text/javascript" src="<%= Page.ClientScript.GetWebResourceUrl(typeof(UrlTrackerResources), "InfoCaster.Umbraco.UrlTracker.UI.res.js.main.js") %>"></script>

Using embedded static files, like CSS and javascript

I just had to write my own VirtualPathProvider. By using this provider I was able to load usercontrols by using the registered Virtual Path, in this case "/Umbraco/UrlTracker/".
For example, when I need to load a UserControl into the page, I define the UserControl as a protected variable in the page's class and load it like this:

protected CustomView icCustomView;

protected override void OnInit(EventArgs e)
{
	base.OnInit(e);
	
	// Load the UserControl from the assembly
	icCustomView = (CustomView)LoadControl("/Umbraco/UrlTracker/InfoCaster.Umbraco.UrlTracker.UI.UserControls.CustomView.ascx");
	// Add to a Panel or PlaceHolder
	pnlEditValidationGroup.Controls.Add(icCustomView);
}

Loading a UserControl by using the registered VirtualPath

Final words

Building version 2 of the Url Tracker was really awesome and I've learned a lot from it! We hope you'll enjoy using this package as much as we do. Curious to know what is under the hood? Just visit Github and download the source!

I really hope package developers will think about the update process and start using the single assembly technique whenever they can, it's really not that hard.

An updated version compatible with umbraco v7 will be available soon! If you have any further questions, or if you'd like to tell me what you think of this post, please do not hesitate to contact me on Twitter.

Stefan Kip

Stefan is on Twitter as