(function($){
    // Declare the rootUrl used for filtering internal links.
    var rootUrl = document.location.protocol + '//' + (document.location.hostname || document.location.host) + (document.location.port ? ':' + document.location.port : '') + '/';

    // Helper functions
    var getFragment = function(url, root) { // Grab the fragment and format it how Backbone expects
        var fragment = url;
        if (fragment.indexOf(':') !== -1)
            fragment = fragment.replace(/.*:\/\/[^\/]+/, '');
        if (!fragment.indexOf(root)) fragment = fragment.substr(root.length);
        return fragment.replace(/^[#\/]/, '');
    }

    // jQuery selector for tagging internal links
    $.expr[':'].internal = function(obj, index, meta, stack) {
        var url = $(obj).attr('href') || '';
        return (url.substring(0, rootUrl.length) === rootUrl || url.indexOf(':') === -1); // same domain || relative link
    };

    $.fn.clickify = function(options) {
        options = $.extend({ 'root': '/' }, options); // Set the root option if your single-page app isn't in the site root

        var anchorTags = this.find('a:internal:not(.no-click)');

        anchorTags.click(function (event) {
            var $this = $(this),
                url = $this.attr('href');

            if (event.which == 2 || event.metaKey)
                return true;

            // Make the call to Backbone.History
            // Backbone will call pushState, update the hash or change window.location depending on what our browser supports
            // Regardless, the part you should care about is that your routes are being called.
            Backbone.history.navigate(getFragment(url), { trigger: true });

            event.preventDefault();
            return false;
        });

        anchorTags.addClass('no-click'); // Mark tags we've already added our event handler to

        return this; // chainability
    };
})(jQuery);