-
Update to addSizes (v0.3)
I have released version 0.3 of the addSizes script with various fixes and more file types. The code now looks at links to documents of the following types: pdf, doc, zip, mp3, ogg, m4u, jpg, png, swf. If you are using the script and want to add your own, feel free—let me know though, I would be interested to see how people use it.
Thanks to Marko Mrdjenovič for pointing out in a comment on the previous entry that I should in fact be using
encodeURIComponent()instead ofencodeURI()before sending the URL to json-head. It turns out encodeURI() assumes it is given an entire URL and does not escape & and other reserved characters.encodeURIComponent() on the other hand makes no such assumption and will escape all characters in the given string. Since json-head needs to take a fully escaped URI in order to get the head data,encodeURIComponent()should work better.In the original entry I should have stated more explicitly that this script will only work properly with files json-head can see. They need to be publicly visible on the web, ie files behind https may not behave as expected. I am still working on methods of getting around the issue with protected files.
A major fix to this version is that the code now works with relative file paths. Bizarly the issue relates to how I was getting the href of the link. With the previous versions I was using jQuery to get the href,
$(this).attr('href'), for relative file paths this returns the exact value, eg "media/test.doc". Changing this to usethis.href, fixes the issue as it actually interpretes the link to get the absolute URL. Magic.The code is released under the BSD license.
-
addSizes.js: Snazzy automatic link file-size generation
Often in the development of a site I come across the need to display the size of a document next to the link targeting it. I also like to display the type of file the link targets, for example, when linking to pdfs, mp3s or Word documents.
These indications distinguish the 'attachment' link from a normal web link, whilst also giving the user some inkling of the time they will need to wait to view the resulting content.
So I was pretty excited when Simon bounded in from work and enthusiastically demonstrated json-head, a Google App Engine application he built on the train home.
Every file on the web, be it a web page, a text file or whatever has HTTP headers associated with it. This is meta information about the file that is sent before the actual contents of the file itself. Included in this meta information is the size of the document.
You can call json-head with JavaScript (JSONP). It takes the URL of a file on the web and performs a HEAD request against it to return the headers and not the actual content itself. The application then returns this information in JavaScript object notation (JSON) to a callback function you have written.
One of the first things that occurred to me was how this could be used to solve the problem of dynamically adding the file size to links. The resulting script I wrote is being used on this site, so before I explain how it works here's a quick demo of a pdf document and an mp3 file. For a further demo take a look at this basic file.
Using jQuery we first use CSS selectors to find all of the links with the relevant file extensions:
$('a[href$=".pdf"], a[href$=".doc"], a[href$=".mp3"], a[href$=".m4u"]')For each link, we get the type of the target by splitting the href value on '
.' and grabbing the last value. This is the file extension.jQuery neatly abstracts the faff involved in using JSONP. We pass json-head the URL of the file we want to inspect and the name of the callback function we want it to run with the results. The callback function in this case is '
?', which tells jQuery to create a random function name hooked up to the function we pass togetJSON().var url= "http://json-head.appspot.com/?url="+encodeURI(this.href)+"&callback=?"; $.getJSON(url, function(json){ /* ... */ }We can now inspect the information sent to us by json-head. If everything went OK we have the size of the file in bytes in the
Content-Lengthheader.var length = parseInt(json.headers['Content-Length'], 10);
Once we have the exact size we need to do a bit more work to get human readable file sizes. We loop through an array to find the largest unit that fits. Once the right size has been found, the script breaks out of the loop storing the unit name and the length to 1 decimal place, so we end up with something like 1.2GB.
for(var i = 0; i < units.length; i++){ var unitSize = units[i][0]; var unitText = units[i][1]; if (length >= unitSize) { length = length / unitSize; // 1 decimal place length = Math.ceil(length * 10) / 10; var lengthUnits = unitText; break; } }Now the maths is over, all that remains is to insert the results back into the dom. I am using jQuery's
.after()method but if you wanted to insert the size and type directly into the link you could change this to use.append()I also add the type of the document as a class, to allow for additional styling such as adding an icon. A future version of the script will add the content type to the link as well.
link.after(' (' + type + ' ' + length + ' ' + lengthUnits + ')'); link.addClass(type);To use this script in your site, simply include jQuery and then the addSizes script itself will do the rest of the magic.
PLEASE NOTE: this may not be 100% reliable due to App Engine being occasionally and unavoidably flakey.
UPDATE: Please see the update to addSizes.
2 items tagged "code"
Look at "code" on del.icio.us, Flickr or Technorati
