This hasn't been strenuously tested yet...

What little I've put together so far is here:  http://cosmicforge.com/topics/

This is my first time using jQuery, and so I'm attempting to make a
proper plugin instead of just random functions.

The functionality is very focused as written -- it purposefully only
links the first occurrence found, but I suppose that part could be
made optional -- oh, and it doesn't do any error checking, and it
doesn't work if the JSON files are missing, so there's plenty of work
still to be done.

And for those of you who just want to look at code...


jQuery(function($) {
        $("div.storytext > p").add("div.storytext > ol >
li").add("div.storytext > ul > li").linktopics();
});


A single (object) param to be passed to linktopics:

{
        topicLinkJsonUrl: "URL to JSON file with topic data",
        topicUnlinkJsonUrl: "URL to JSON file with list of topics NOT to
link"
}


JSON for topics to be linked:

{
        "topics": [
                {
                        "topic": "jQuery",
                        "link": "http://jquery.com/";,
                        "strings": [
                                "jQuery",
                                "Javascript framework",
                                "John Resig"
                        ]
                },
...
}


JSON for topics NOT to be linked:

{
        "stoplinks": [
                "Michael Edmondson"
        ]
}


/**
 * jquery.linktopics.js
 */

(function($) {

        $.fn.extend({
                linktopics: function( settings ) {
                        this.settings = $.extend({}, $.linktopics.defaults, 
settings);
                        this.topics = null;
                        var self = this;
                        $.getJSON( self.settings.topicLinkJsonUrl, 
function(json) {
                                if ( typeof json.topics == "object" ) {
                                        self.topics = json.topics;
                                        self.stopLinks = new Array();
                                        $.getJSON( 
self.settings.topicUnlinkJsonUrl, function(json) {
                                                if ( typeof json.stoplinks == 
"object" ) {
                                                        self.stopLinks = 
json.stoplinks;
                                                }
                                                for ( var i = 0; i < 
self.topics.length; i++ ) {
                                                        var allowed = true;
                                                        for ( var j = 0, 
numStopLinks = self.stopLinks.length; j <
numStopLinks; j++ ) {
                                                                if ( 
self.stopLinks[j] == self.topics[i].topic ) {
                                                                        allowed 
= false;
                                                                        break;
                                                                }
                                                        }
                                                        if ( ! allowed ) {
                                                                void( 
self.topics.splice( i, 1 ) );
                                                        }
                                                }
                                                for ( var i = 0, numTopics = 
self.topics.length; i < numTopics; i
++ ) {
                                                        self.topics[i].linked = 
false;
                                                        
self.topics[i].strings.sort(function(a,b) {     // longer strings
come first
                                                                if ( a.length > 
b.length ) {
                                                                        return 
-1;
                                                                } else if ( 
a.length < b.length ) {
                                                                        return 
1;
                                                                } else {
                                                                        return 
0;
                                                                }
                                                        });
                                                        self.topics[i].regexes 
= new
Array(self.topics[i].strings.length);
                                                        for ( var j = 0, 
numStrings = self.topics[i].strings.length; j
< numStrings; j++ ) {
                                                                
self.topics[i].regexes[j] = new RegExp( "(^|\\W)(" +
self.topics[i].strings[j].replace( /([\[\]\(\)\.\*\$\^\?\+\\])/g, '\\
$1' ) + ")((?!\\w)(?![^<]*(?:>|<\\/a)))" );
                                                        }
                                                }
                                                self.each(function() {
                                                        for ( var i = 0, 
numTopics = self.topics.length; i < numTopics;
i++ ) {
                                                                if ( 
self.topics[i].linked == false ) {
                                                                        for ( 
var j = 0, numRegexes = self.topics[i].regexes.length;
j < numRegexes; j++ ) {
                                                                                
if ( $(this).html().search( self.topics[i].regexes[j] ) !=
-1 ) {
                                                                                
        $(this).html( $
(this).html().replace( self.topics[i].regexes[j], '$1<a rel="topic"
title="Topic: ' + self.topics[i].topic + '" href="' +
self.topics[i].link + '">$2<\/a>$3' ) );
                                                                                
        self.topics[i].linked = true;
                                                                                
        break;
                                                                                
}
                                                                        }
                                                                }
                                                        }
                                                });
                                        });
                                }
                        });
                }
        });

        $.linktopics = {};

        // define global defaults, editable by client
        $.linktopics.defaults = {
                topicLinkJsonUrl: "topics_link.json",
                topicUnlinkJsonUrl: "topics_unlink.json"
        };

})(jQuery);



Reply via email to