Archive for the 'Web Development' Category

Creating your own Digg/Facebook/Tweetmeme button

This quick walkthrough is going to bring you up to speed on how to create your own social bookmarking button. The three prime examples are the famous Digg button, Facebook’s like functionality and the tweetmeme button. For an implementation look slightly above this paragraph or check out mashable’s version on the left of their post.

Our button will be focusing on Fashiolista is a social bookmarking site for fashion, which has seen rapid growth after launching at the next web. This tutorial explains the javascript (client side) aspects of the button. Feedback and improvements on the code would be greatly appreciated. You can find the full 450 lines of js on github.

This is what the end result looks like:

Compact Medium Large

Love it!

Love it!

Love it!

(If you are working on a shop in the fashion industry have a look at our installation instuctions.)

Step 1 – The markup

Its important to get the client side markup of the button right. Since other sites will be implementing this there is no way you can change it later on. The three major players each have their own way.

Facebook XFBML: Async script with XFBML or Iframe
Digg button: Async script with A elements
Tweetmeme: Normal script

<script type="text/javascript">
  //async script, version
  (function() {
   var s = document.createElement('SCRIPT');
   var c = document.getElementsByTagName('script')[0];
   s.type = 'text/javascript';
   s.async = true;
   s.src = '';
   c.parentNode.insertBefore(s, c);
<a class="fashiolista_button fashiolista_compact"
href="">Love it!</a>

For Fashiolista we have chosen an async script approach with A elements. Normally loading a script element is a blocking operation for the browser. Loading the script async ensures faster page load times and a better experience if your site would ever go down. (Note that not all browsers support this option so it is still recommended to include the script tag at the bottom of the page). The function wrapped around the code ensures we don’t pollute the global scope. Furthermore the insertBefore in combination with a script tag technique is used by GA so should work in any scenario.

Step 2 – Creating the buttons, Iframe vs Script

The next step is to convert our A elements into actual buttons. We can choose to replace these A elements by our button’s html (digg, delicious approach) or load an iframe in their place (facebook, tweetmeme). The difference between these two approaches is actually pretty large. For Fashiolista you can see both an iframe and script approach. These are the most important differences I encountered.

Iframe vs Script

  • + Popup communication possible
    The script approach cannot communicate with popups it creates due to the same origin restrictions. The iframe however can be of the same domain as the popup and freely communicate. This gives a better user experience when for instance logging in.
  • + Easier to develop
    The iframe approach is easier to develop and requires less code.
  • + Parallel download in IE
    IE doesn’t download the count scripts in parallel, but it does do so for the IFRAMEs. Making this approach somewhat faster.
  • Independent CSS
    External sites don’t interfere with your button’s css if you use an iframe technique. The disadvantage is that it makes things likes hovers impossible to integrate with the other site. (For example Fashiolista’s compact button).
  • Independent
    The iframe approach makes it very hard for other sites to game the users like/love action. With a script approach a foreign site can simply call your javascript to fake someone loving the product. This freedom can be abused but also allows for mashups.
  • – Slower dom load
    Creating iframes takes a lot more time for the browser.
  • – Slower perceived load
    The script approach allows you to format the buttons before the data is loaded. Vastly increasing the perceived load speed.
  • – No shared functionality
    Buttons can’t share functionality. So when someone logs in for one button its is not possible to update the others.

The best choice differs for each project. For Fashiolista the more open script approach is currently the default.

Step 3 – Cross site scripting using JSONP

Essential to the bookmarking button is requesting the count for the given url. Cross site policies prevent us from using Ajax so we will do so by creating a script element.

_makeRequest: function (url) {
	//Simple create script element functionality
        var s = document.createElement('script');
        var b = document.body;

        s.setAttribute('type', 'text/javascript');
        s.setAttribute('async', 'true');
        s.setAttribute('src', url);


The trouble with the script element is that you lack the nice APIs Ajax offers you. We work around this by using an url with a callback paramater, for example callback=button_loaded_3
The server side code then responds with something like this, executing the callback when the script is loaded.

button_loaded_3({"item_id": 26545, "url": "/item/26545/", "loves": 853})

This technique is often referred to as JSONP. We bind the response function to the global button_loaded_3 using the following code:

loadButtonInformation: function (buttonId) {
		//make a request to the script with the given callback
		var buttonInstance = this.buttonDict[buttonId];
		var buttonUrl = buttonInstance.lookupUrl;
		var path = '&url=' + encodeURIComponent(buttonUrl);
		var callbackFunctionName = 'button_loaded_' + buttonId;
		var scope = this;
		var callbackFunction = function(data) {
			//bind the scope and button id, buttonId, data);
		window[callbackFunctionName] = callbackFunction;
		this.makeRequest(this.countApi + path, callbackFunctionName, true);

Step 4 – Object oriented design

Since we are loading our code into someone else’s website we should be careful not to use similar variable names. We therefore hide as much code as possible in classes.

var fashiolistaClass = function(){ this.initialize.apply(this, arguments); };
fashiolistaClass.prototype = {
	//Base class implementing the fashiolista button
	initialize: function () {
		//load the buttons
		var fashiolistaButtons = this.findButtons();

Note that we are not simulating inheritance for these classes. Using them as simple namespaces is more than sufficient in this case.
The code is organized into 3 classes:

  • fashiolistaClass
  • fashiolistaUtilsClass
  • fashiolistaButtonClass

The first one acts as a manager (finding the buttons, instantiating fashiolistaButtonClasses and retrieving counts). Fashiolista button contains the logic for individual buttons and fashiolista utils contains some string parsing and dom load functionality.

Step 5 – Caching requests in the google app engine

appengineTo prevent our servers from getting flooded we are routing all traffic through google servers using the google app engine. is connected to a google app engine account which forwards and caches requests to This setup enables your button to withstand great amounts of traffic without killing your servers. Furthermore it immediately also acts as a cdn for our web requests, speeding up load times for our international visitors. Setting up caching in the google app engine would require another blog post though. Let us know in the comments if you would like to know more about it.


The full client side code can be found here. This blog post covered the most essential parts. Code review and questions are more than welcome. Be sure to let us know in the comments. Furthermore if you are running a webshop in the fashion industry consider implementing the button.

More information

Improvements/ Request for code review

  • The domload technique is rather verbose, does anyone know a better method?
  • The popup communication or lack thereof is not ideal for users, is there a better method?
  • Script or Iframe what do you prefer?
  • Suggestions to make it faster?

Django &Fashiolista &Google app engine &Javascript &JQuery &Python &Web Development &YouTellMe tschellenbach 03 Aug 2010 11 Comments

Django Facebook – Open graph API implementation

This blog post is outdated, a new and vastly upgraded version of Django Facebook is now available. Read more about it here.

For Fashiolista we needed to integrate with the Facebook Open Graph API. The open graph API is a very exciting facebook project, which you can read about more here and here. The code at allows you to register/login via facebook using the Open Graph API (similar to the old Facebook connect, but registration, instead of only logging in). Before you go try it out, is aimed primarily at females so your girl friends facebook account is probably a better fit.

Im releasing the source code for Django Facebook on github. Its a very early release, but it might help other developers trying to implement a facebook register/loging flow using the new open graph api. See Github for requirements and installation instructions.

Birthday formats are currently giving some troubles for some users.
Fixed and tests added to prevent future problems. (note may still give errors, will be resolved during our next release).

Django &Fashiolista &Javascript &Python &Web Development tschellenbach 17 May 2010 105 Comments – Django at The Next Web – part 1 is launching in 7 days and has already been getting quite some attention. Techcrunch: 25 startups that will be shaping the next web. For Fashiolista we’ve been able to utilize a great deal of best practises learned in previous Django based sites. More on this topic later. For now I’m wondering if there are many other Django fans attending the next web conference.

The conference itself should be very interesting. Definitely looking forward to Werner Vogels and Joe Stump. The later seems to be running Django for SimpleGeo.

Django &Events &Fashiolista &Web Development tschellenbach 22 Apr 2010 13 Comments

Django based startup – is a completely Django based startup located in Amsterdam. We’re probably one of the largest Django projects in terms of codebase. Pretty soon the famous nextweb awards are coming up. (remember those guys which broke into Michael Arrington’s house?). And we need some love from the Django community. Lots of it.

Pretty please nominate for the next web!

Good articles coming soon to offset the bad karma for this shameless plug ;)


A couple of stats about the current codebase.

According to wc (including whitespace and comments) we currently have:

  • Python: 3,363,188 characters, 87926 lines, 655 files
  • Javascript: 940,536 characters, 24229 lines, 77 files

Django &Events &Web Development &YouTellMe tschellenbach 19 Mar 2010 3 Comments

Django query set iterator – for really large, querysets

When you try to iterate over a query set with about 0.5 million items (a few hundred megs of db storage), the memory usage can become somewhat problematic. Adding .iterator to your query set helps somewhat, but still loads the entire query result into memory. Cronjobs at where unfortunately starting to fail. My colleague Rick came up with the following fix.

This solution chunks up the querying in bits of 1000 (by default). While this is somewhat heavier on your database (multiple queries) it seriously reduces the memory usage. Curious to hear how other django developers have worked around this problem.

import gc

def queryset_iterator(queryset, chunksize=1000):
    Iterate over a Django Queryset ordered by the primary key

    This method loads a maximum of chunksize (default: 1000) rows in it's
    memory at the same time while django normally would load all rows in it's
    memory. Using the iterator() method only causes it to not preload all the

    Note that the implementation of the iterator does not support ordered query sets.
    pk = 0
    last_pk = queryset.order_by('-pk')[0].pk
    queryset = queryset.order_by('pk')
    while pk < last_pk:
        for row in queryset.filter(pk__gt=pk)[:chunksize]:
            pk =
            yield row

#Some Examples:


#even better

Django snippet here.

Django &Python &Web Development &YouTellMe tschellenbach 03 Mar 2010 288 Comments

YTM launch!!

No more beta for
The website which is taking over the Dutch product comparison market is officially going out of beta @ 8 o clock.
Party in Amsterdam, Keizersgracht 182 :) Festivities starting right now!


Things are going well, looking very forward to international launch.
We’ve changed a lot since the first reviews!


Beter pictures coming after the event :P

PS. Thanks to Python and Django, for enabling us to beat the competition :)

PSS. Next2News, eduhub, come and join :)

Apache &Business &Css &Django &Dutch &Events &Javascript &PHP &Prototype &Python &Symfony &Web Development &YouTellMe tschellenbach 11 Dec 2009 150 Comments

New YouTellMe release

We have been rolling out some awesome new features at The new version of the comparison system allows for the most flexible product comparison queries. Furthermore we now fully support product variations with easy selectors during price comparison.

Read the full story (in Dutch)

Business &Web Development &YouTellMe tschellenbach 08 Jun 2009 6 Comments

« Previous PageNext Page »