URL Shortening in SharePoint with bit.ly
In my two previous posts about customizing the Edit Control Block (or ECB for short) with Javascript, I showed some basic examples of what can be accomplished with this technique. Now it’s time to build a real life example instead of menu items which show Hello World dialog boxes.
I’m pretty sure everybody who is using SharePoint has sent a link to a document in a Document Library to somebody else (in an email message for example). So you probably know that links to documents (or list items) can become pretty long if the document is located in a Document Library on a site deeply buried in a hierarchy. Already some time ago the internet community has solved the issue of long URL’s (which were a pain in newsgroups for example, or too long for Twitter messages): URL shortening. The idea is pretty basic: you can request a short URL (typically containing a generated code) for a long URL. When somebody uses the short URL, the long URL is retrieved and the user is redirected. There are many sites on the internet that provide this service for free, in this article I will be using bit.ly because they have a pretty nice API you can work with as a developer. For example this link http://bit.ly/1btOBN will navigate to http://weblogs.asp.net/jan/archive/2009/09/04/customizing-the-sharepoint-ecb-with-javascript-part-2.aspx.
So what’s the idea? Instead of having to copy the link of a SharePoint document or list item to the clipboard, navigate to bit.ly and request a short URL over there; we’ll build this functionality directly into the SharePoint web user interface. The screenshot below shows the ECB of a normal Document Library, as you can see there is an extra menu item Shorten Link with bit.ly that has three child menu items.
Once again, in my previous post I go into the details about how you can build a nested ECB menu item by just using Javascript. So let’s quickly discuss the code to build the menu items:
function Custom_AddDocLibMenuItems(m, ctx) {
var itemLink = window.location.protocol + "//" + window.location.host +
GetAttributeFromItemTable(itemTable, "Url", "ServerUrl");
return addBitlyMenuItems(m, ctx, itemLink);
}
function Custom_AddListMenuItems(m, ctx) {
var itemLink = window.location.protocol + "//" + window.location.host +
ctx.displayFormUrl + "?ID=" + currentItemID;
return addBitlyMenuItems(m, ctx, itemLink);
}
function addBitlyMenuItems(m, ctx, url) {
var shortenMenu = CASubM(m,"Shorten Link with bit.ly", "/_layouts/images/RAT16.GIF");
CAMOpt(shortenMenu, "Shorten and Display", "getShortUrl('" +
url + "', shortenAndDisplay)", "");
CAMOpt(shortenMenu, "Shorten and Copy to Clipboard",
"getShortUrl('" + url + "', shortenAndCopy)");
CAMSep(shortenMenu); // separator
CAMOpt(shortenMenu, "Show Statistics for Short Link",
"getShortUrl('" + url + "', shortenAndShowStats)", "/_layouts/images/GRA16.GIF");
CAMSep(m); // separator
return false;
}
Because I want to show the ECB menu item both in Lists and Document Libraries, I’ve implemented both the Custom_AddDocLibMenuItems and Custom_AddListMenuItems Javascript functions. In those functions a string is constructed that contains a link to either the list item or to the document. Once we’ve got that URL, the addBitlyMenuItems function is called. This function will build the parent menu item in the ECB and the three child menu items which will actually do the actions. Every action menu item calls a custom Javascript function called getShortUrl which has a parameter for the long URL and a callback function. The getShortUrl function builds an URL to call the bit.ly REST API. This URL is called with the help of the jQuery getJSON function. Note that to make use of the bit.ly API you need to have a free account and a corresponding key.
function getShortUrl(url, callback) {
var bitlyURL = "http://api.bit.ly/shorten?"
+ "version=2.0.1"
+ "&longUrl=" + escape(url)
+ "&login=YOUR_LOGIN" +
+ "&apiKey=YOUR_KEY" +
+ "&history=1" +
+ "&format=json&callback=?";
$.getJSON(bitlyURL, function(data){
callback(data.results[url].shortUrl);
});
}
Once the getJSON function receives the data from bit.ly, the callback function (which was passed as a parameter) is called, passing along the shortened URL.
The three callback functions used in the addBitlyMenuItems function, will each do a specific action: show the shortened link, copy the link to the clipboard or navigate to the bit.ly statistics page. The shortenAndDisplay is the most complex of those three; this function will display the shortened URL in a DIV centered on top of the page. Once again jQuery is used for manipulating the HTML DOM to dynamically render the DIV.
function shortenAndDisplay(url) {
$("body").append("<div id='shortUrlDiv' class='ms-vb' style='position:absolute; \
background-color:White; padding:10px; border-width:1px; border-style:solid; \
border-color:Black;display:none; position:absolute;'>URL shortened to:<h2>" +
url + "</h2><a href='#' id='shortUrlDivClose'>Close</a></div>");
var $shortUrlDiv = $("#shortUrlDiv");
var topPos = (document.body.clientHeight - $shortUrlDiv.height()) / 2;
var leftPos = (document.body.clientWidth - $shortUrlDiv.width()) / 2;
$("#shortUrlDivClose", $shortUrlDiv).click(function() {
$(this).parent().hide("fast", function() { $(this).remove(); });
});
$("#shortUrlDiv").css("top", topPos).css("left", leftPos).show("fast");
}
The result of this function looks like this:
The other two callback functions are very easy to implement. Notice that to show the bit.ly statistics page for a shortened link, you just need to add a + sign to that link.
function shortenAndCopy(url) {
clipboardData.setData("Text", url);
}
function shortenAndShowStats(url) {
window.location = url + "+";
}
The complete source code can be downloaded from here. You will notice that I’ve made the code somewhat easier to configure by adding a configuration variable at the top:
var shortenConfig = {
debug: 0, // set this value to 1 to see debug information
bitlyLogin: "spdemo", // bit.ly account, below API key
bitlyAPIKey:"R_877718dd86f418d0ee840c08af717a68",
bitlyHistory: 1 // set this value to 1 to add to bit.ly history
};
When you set the debug variable to 1, another DIV is dynamically added to the page and will show some log messages. When the bitlyHistory variable is set to 1, bit.ly will add the shortened link to the bit.ly account (so you can track it). Once again, if you plan to use this, go to bit.ly and sign up to get your own login and API key. On top of my code there is a reference to the jQuery library hosted by Google. If you have deployed jQuery locally, feel free to change the script reference. To use the code, just navigate to a Document Library or List, and add a new Content Editor web part to that page. As the HTML source of the web part, copy and paste the entire code that you've downloaded. (For a detailed description how to add the Content Editor web part, check an earlier article)