Portland & Courant News: Short URLs

This past Saturday I joined Daniel Bachhuber and David Estes in Portland to talk journo dev projects. We talked about workflow engines, news wikis, virtual assignment desks, and other miscellaneous topics, but eventually Daniel and I got to work on building a simple short URL app for Django/Courant News.

There is certainly no shortage of short URL services in existence, with bit.ly currently being the most popular. However, as the recent existential crisis at tr.im has shown, trusting these services is sometimes not the best idea. In addition, there are numerous advantages (enumerated elsewhere) to hosting your short URLs on your own domain name.

Referral Tracking

As news orgs strive to find ways of attracting traffic to their websites, evaluating the effectiveness of distribution through different mediums is critical. How much traffic comes from email newsletters? Twitter? Facebook? the print edition?

Some or all of such mediums will not pass HTTP referrer headings, which means it is difficult or impossible to track using normal methodology. If you are using Google Analytics or similar service, the best you can likely do is add an HTTP GET parameter to the end of the link and convert that on the server side. However, it is easy for users to strip this off and is far from foolproof.

Alternatively, we can generate a different short URL for each of the target mediums and then track hits before/during the redirection step. That’s the route we chose for our app.

Short URL Types

There are a few strategies to generating actual short URL strings. Most of the popular services just use incremental keys that are encoded in base-32 or similar (converts a number to a string consisting of A-Z, a-z, 0-9 and perhaps some punctuation characters).

That works well with huge volume, as a single individual is unlikely to generate consecutive URL tokens. However, when you host your own URL shortener, all URLs generated on a given day will look very similar using this approach, which may or may not be problematic.

I, personally, prefer more diverse URLs for tokens created in a sequence. Since the point of per-medium URLs is to reliably track referrers, we don’t want users to easily guess what the URL for another medium is and thus spoof our service (or just accidentally mistype them).

Therefore, our short URL app supports both generation types: consecutive sequence (GHn8n, GHn8o, GHn8p) or a pseudo-random generator (GHn8n, SfMgo, ednto).

If you want a custom URL for a special case, you can manually create a new short URL through the admin interface and manually specify whatever URL value you desire.

Primary vs. Secondary Domain

The YDN has a very long domain name, so we want to use a shorter domain name (goydn.com) for our short URLs. However, some orgs, such as David’s DailyUW.com may want to just use their normal domain. Thus our app supports both scenarios.

If you want to use your primary domain, we recommend you put it under some prefix, such as /go/ or /g/, to avoid collisions with other valid URLs (e.g., /news/). However, if you want to play with fire, you can configure your short URLs to work at the top level of your primary domain without problems.

Do note that short URLs will only get checked if the page requested would have otherwise returned a 404 error.

App Models

The first model in our app is ShorturlMedium, which is simply a named object representing a given medium like “Print”, “Twitter” or whatever your org needs.

The core of our app is the Shorturl model, which maps a ShorturlMedium to a content object (using Django’s content type app) and stores the actual short URL.

Finally, we have the ShorturlHit model, which tracks hits for a given per-medium short URL. I have not yet generated any report generation tools, but that should be an easy work item in the future and will surely be a part of Nando.

Template Tags

To put short URL links on your pages, we have a simple template tag to get (and generate, if necessary) one for a given content object (article, page, event, etc.).

{% load shorturls %}
{% shorturl obj Twitter %}

That’s it. The first parameter is the content object variable, and the second is the medium you want it to run in.


Our short URL app is pretty simple, but is configurable to meet the needs of most college news deployment scenarios. Because it ties into your content behind the scenes, it won’t break when you change your normal URL structures and supports any new models you add to the system. In a few months, after we use the system in production, I’ll post a followup analyzing the analytics data we gather from it.

Code can be found in the Courant News code repo. Parts were based on django-ittybitty, but we strayed far enough away in purpose and implementation that it didn’t make sense to just treat our code as a patch. Let me know if you have any questions.

3 Responses to Portland & Courant News: Short URLs
  1. [...] In the past week, Twitter as all about Facebook, FriendFeed, and tr.im. Jeffery Zeldman, a notable desig... copress.org/2009/08/14/preparation-for-the-fall
  2. [...] Courant News included new email and analytics tracking systems, which allowed us to push breaking news u... copress.org/2009/09/24/keeping-courant-with-annie-le-coverage

Leave a Reply