Home  >  

Mimicking Twitterfall's Short URL Replacement

Author photo
AddThis Social Bookmark Button
Since I discovered Twitterfall.com, I've become addicted to the site's constant stream of Twitter updates. The site works on a basic premise. Enter few search terms, and a 'waterfall' of matching tweets will slowly scroll down the screen. It is a great way to discovered relevant content from folks outside your normal audience. I use it to monitor both jQuery and ColdFusion and I was really surprised by what I've seen. Even the dupes are interesting. It's fun to see folks RT the same tweet over and over again like a wave of duplicity.

While using Twitterfall, I noticed something pretty cool. Due to the size limitations of Twitter, most folks will use a "Short URL" service (like tinyurl.com) to post links. The problem with this is that it is impossible to tell where these links will take you. I noticed, though, that when I moused over these links in Twitterfall, they actually changed to their full version.

I opened up Firebug and did some digging and noticed that these replacements were being done serverside. With that in mind I decided to see if i could build my own version of this code with jQuery.

I first took a deeper look at the content loaded into Twitterfall. I noticed that every URL that supported replacements used a particular class. I also noticed that not all of the short urls used this class. I figured then that Twitterfall was only replacing links for short url services that had an API. I think it is fair to assume then that their server side code is simply looking for certain types of URLs and then adding the class on the fly. For my demo I decided to simply do this manually:


<div id="content">
<p>
This is a url: <a href="http://tinyurl.com/c9kzb4" class="surl">http://tinyurl.com/c9kzb4</a> with a 
few tests: <a href="http://tinyurl.com/c9gtw8" class="surl">http://tinyurl.com/c9gtw8</a> Some non <a href="http://www.cnn.com">short</a> urls as <a href="http://www.yahoo.com">well</a>.
</p>

<p>
A second paragraph with <a href="http://snurl.com/dyw9f" class="surl">http://snurl.com/dyw9f</a> tests. 
</p>
</div>

The HTML above contains two paragraphs. The first paragraph has a few links. Two of them use tinyurl.com and have a class of surl. The second paragraph has a link to snurl.com and also uses surl.

My first task is to pick up on the links that have the surl class:


$(document).ready(function() {
 	$(".surl").mouseover(rewriteURL)
});

Nothing too complex here. My selector grabs all the items with the surl class and assigns an event handler for the mouseover event. The rewriteURL function is where the magic happens:

function rewriteURL(e) {
 	var url = e.target.href
 	$.get("getrealurl.cfm",{href:url},function(data) {
  		//change text
  		$(e.target).html(data)
  		$(e.target).unbind("mouseover")
  	});
}

Ok, so line by line, I begin by grabbing the URL of the link the user just moused over. I take that URL and pass it to my server side code. The result will be the full URL, so I can simply change the HTML of the link to the new value. At this point the short url will be rewritten as the full url (details forthcoming in the ColdFusion code in a minute) so there is no point in running the code again. The unbind call will remove the mouseover event from the link so it won't run again.

That's it. Well, on the client. The server is a bit more complex. My example works with tinyurl and snurl, both short url services that have basic APIs. I wrote up simple UDFs to handle the translation, and then used them like so:

<cfsetting enablecfoutputonly="true">

<cfparam name="url.href" default="">

<!---
<cfoutput>i got #url.href#</cfoutput>
--->

<cffunction name="getSnurlOriginal" output="false" returnType="string">
	<cfargument name="snurl" type="string" required="true">
	<cfset var result = "">
	<cfset var resp = "">

	<cfhttp url="http://snipurl.com/site/getsnipdetails" method="post" result="result">
		<cfhttpparam type="formfield" name="snipid" value="#arguments.snurl#">
		<cfhttpparam type="formfield" name="snipuser" value="cfjedimaster">
		<cfhttpparam type="formfield" name="snipapi" value="03fb4bdaebbc55dc5ab2c16dcc46d9e1">
	</cfhttp>
	<cfset resp = xmlParse(result.fileContent)>
	<cfset realUrl = urlDecode(resp.snip.url.xmltext)>

	<cfreturn realUrl>
</cffunction>

<cffunction name="getTinyOriginal" output="false" returnType="string">
	<cfargument name="turl" type="string" required="true">
	<cfset var result = "">
	<cfset var match = "">
	<cfset var mylink = "">

	<cfhttp url="http://preview.tinyurl.com/#listLast(arguments.turl,"/")#" result="result">
	<cfset result = result.fileContent>

	<!--- look for redirecturl --->
	<cfset match = reFindNoCase("redirecturl"" href=""(.*?)""", result,1, 1)>
	<cfset mylink = mid(result, match.pos[2], match.len[2])>
	<cfreturn mylink>
</cffunction>

<cfif findNoCase("snurl.com", url.href)>

	<cfoutput>#getSnurlOriginal(url.href)#</cfoutput>

<cfelseif findNoCase("tinyurl.com", url.href)>

	<cfoutput>#getTinyOriginal(url.href)#</cfoutput>

<cfelse>

	<cfoutput>#url.href#</cfoutput>

</cfif>

The web site address to be modified is sent in via the URL scope as the HREF value. Notice I have some code commented on top: i got #url.href#. This was my original code when I was working on the client side. I used it as a quick way to see if my jQuery code was working correctly. Immediately after this are two UDFs. You don't need to worry about them too much, but they handle the reverse lookup for Snurl and TinyURL. The real logic then is the checks to see which service is being used. If we find snurl.com, then use that UDF to translate the UDF. If we see tinyurl.com, use that UDF. Lastly we simply return the URL unchanged at all if we don't recognize it at all.

You can see this in action here: http://www.coldfusionjedi.com/demos/surlrewrite/test.html

Read more from Raymond Camden. Raymond Camden's Atom feed cfjedimaster on Twitter

Comments

5 Comments

Barney said:

CFHTTP will let you support any service that does a server-side redirect, API or not. Just hit the short URL with redirect="false" and grab the Location header of the response. Works for tinyurl, snurl, and is.gd at least. I didn't try any others.

Obviously an API is a conceptually cleaner solution, but I'm pretty sure HTTP is a sufficiently clean API for this task, and it lets you handle all services in the same way, without having to code against multiple APIs.

Raymond Camden said:

Barney - good point. When I was looking at Twitterfall and noticed that only some of their SURLs did the rewrite, I just assumed that was the logic they used (formal api - do the rewrite).

mbdof said:

Twitterfall is designed, written and maintained by two 2nd year CS students @ York University in the UK, see Daily Telegraph article on Twitter section of the Telegraph website!

Troy said:

Ray, could you make use of http://long.to as a way to resolve the short URLs to their full version?

Raymond Camden said:

Nice, I had no idea about that service Troy. Yes, it COULD be used. Well, I'm assuming it does what it says it does. ;)

Leave a comment


Tag Cloud

iPad

What's your take on the iPad? (Putting aside the Flash/iPad flame war)

Answer

Latest Features

Recommended for You

@InsideRIA on Twitter

Archives

  • Or, visit our complete archive.  

About This Site

Welcome to the premiere community site for all things RIA sponsored by O'Reilly Media and Adobe Systems Incorporated.