A long time ago I read Ian G's blog post about URI design and his approach immediately appealed to me. His ideas on this subject continue to withstand the test of time, so I recently decided to implement this design for Community Server. Next I may attempt to do the same thing with Subtext, which runs this blog.
Ian's stated goals for his URL design were:
- No extensions (e.g. .aspx) or other implementation artifacts. The fact that I’m using .aspx pages internally is of no real relevance to anything, so it has no business appearing in a web browser’s address bar – I want the name of the page to be the name of the page, no more, no less. I also want the name to be durable, so that whenever I switch over from .aspx pages to whatever technology comes next, I don’t break any links.
- ‘Hackability,’ as Jakob Nielsen calls it. In other words, the user should be able to munge the URL by hand in the address bar and have it behave like it looks like it should behave.
These goals are in tune with another good article on URI design by Mike Amundsen: see what makes a good URL.
I believe I have now accomplished the implementation of these URI design goals for Community Server and I'll show you how in this post.
Below is an example of what my URIs look like now. From the blog post URL shown below, each URL segment can be hacked off and the resulting URL is valid and works as one would expect.
http://mydomain.com/blogs/myblog/2006/11/12/my-blog-post-name
http://mydomain.com/blogs/myblog/2006/11/12
http://mydomain.com/blogs/myblog/2006/11
http://mydomain.com/blogs/myblog/2006 (this one probably isn't ideal. Currently, for CS, I just show January for the year instead of showing the whole year)
http://mydomain.com/blogs/myblog
http://mydomain.com/blogs
http://mydomain.com
I was able to accomplish this implementation with two fairly simple changes to Community Server. The change that took the most work to get right was my revised SiteUrls.config. (Clicking that link will download a zip archive containing the actual SiteUrls.config file I'm using on a production web site.) If you drop this config file into your Community Server installation, your blog URLs will look and act just like the example shown above -- as soon as you take care of the second step of my solution.
The second step was much easier for me to implement, but it does involve modifying code. I posted about this code change on the CS forums. In ReWrittenUrl.cs, the Convert method had to be refactored as shown here:
public virtual string Convert(string url, string qs)
{
string newUrl = _regex.Replace(url, _path);
if(qs != null && newUrl.Contains("?"))
{
qs = qs.Replace("?","&");
}
return string.Format("{0}{1}", newUrl, qs);
}
As I said, it ended up being a really simple change and it doesn't alter any of Community Server's standard behavior.
I believe the easiest way to deal with this is to build a new CommunityServer.Components.dll using the code shown above and then drop this assembly into your \Web\bin folder. In fact, I'll provide such a dll for CS 2.1 SP2 here if enough people request it.
The installation steps are:
- Enable wildcard mapping in IIS.
- Back up your old SiteUrls.config and replace it with my SiteUrls.config.
- Drop the modified CommunityServer.Components.dll into \Web\bin.
Please share your feedback with me. Let me know if you have problems with any of my modifications. And if you extend this implementation with success, please contact me and let me know, in keeping with the open source spirit.