0

I want to convert certain key words into affiliate links on my website. I do not want to hand-code each one of those links in every page. So I'm looking for a Javascript/Jquery based solution where using a given a list of keywords and corresponding URLs (a two dimensional array), on page load, these keywords are 'URLified' using their corresponding URLS.

I found this comment Find text string using jQuery? which has the code for a case insensitive search, but it URLifies the whole text node instead of just the word.

I could use something like the code below. But the problem is that it will URLify keywords inside <pre> elements too. I want them URLified inside just <p> elements.

<script type="text/javascript">
(function($) {
  var thePage = $("body");
  thePage.html(thePage.html().replace(/testing/ig, '<a href="http://testing.com">testing</a>')); 
})(jQuery)
</script>

For eg:

<p>I'm going to test urlification</p>
<pre>
function test() {
alert(' test ');
}
</pre>

should change to

<p>I'm going to <a href="test123.com">test</a> urlification</p>
<pre>
function test() {
alert(' test ');
}
</pre>
Community
  • 1
  • 1
freethinker
  • 1,286
  • 1
  • 10
  • 17

4 Answers4

3

1. Here is the jQuery plugin which replaces text snippets

/**
* jQuery plugin to replace text strings
*
* Taken from @link http://net.tutsplus.com/tutorials/javascript-ajax/spotlight-jquery-replacetext/
*/

$.fn.replaceText = function( search, replace, text_only ) {
return this.each(function(){
        var node = this.firstChild,
        val, new_val, remove = [];
        if ( node ) {
            do {
              if ( node.nodeType === 3 ) {
                val = node.nodeValue;
                new_val = val.replace( search, replace );
                if ( new_val !== val ) {
                  if ( !text_only && /</.test( new_val ) ) {
                    $(node).before( new_val );
                    remove.push( node );
                  } else {
                    node.nodeValue = new_val;
                  }
                }
              }
            } while ( node = node.nextSibling );
        }
        remove.length && $(remove).remove();
    });
};

2. Here is the code which you can use to achieve the replacements

// the array of affiliate links
var affiliates = [
        ['google', 'http://www.google.com/'],
        ['bing', 'http://www.bing.com/'],
        ['yahoo', 'http://www.yahoo.com/']
    ],
    $p = $('p'), // the selector to search text within
    i = 0, // index declared here to avoid overhead on the loop
    size = affiliates.length, // size of the affiliates array 
                              // again declared here to avoid overhead
    reg; // the regex holder variable

// loop over all the affiliates array
for(i; i < size; i++){
    // create a regex for each affiliate
    reg = new RegExp('('+affiliates[i][0]+')','gi');

    // finally replace the string with the link
    // NOTE: do not forget to include the aforementioned plugin before this code,
    // otherwise this won't work
    $p.replaceText(reg, '<a href="'+affiliates[i][2]+'">$1</a>');
}

Here is a demo

3. You need to make some changes

All you have to do is change the jQuery selector, and the affiliates array. The rest will be taken care of by the plugin. The plugin is smart enough not to replace the element's attributes.

Shef
  • 44,808
  • 15
  • 79
  • 90
  • This looks cool! Do you reckon this is more efficient than @ipr101's solution? – freethinker Aug 06 '11 at 09:31
  • @Fred: [Doesn't look like it does](http://jsfiddle.net/Shef/astHp/). You can always fork and test it. – Shef Aug 06 '11 at 09:33
  • @freethinker: I don't think that version is smart enough to avoid attributes, and for example to avoid replacing text inside an element which is already a link. You can test both and see which one does the job the way you want it. – Shef Aug 06 '11 at 09:37
  • @Shef: Ignore the comment that I just removed, I just realised what you meant :P – Fred Aug 06 '11 at 09:43
  • @Shef: This is actually really good. It even preserves event bindings inside the `

    ` itself. Good work!

    – Fred Aug 06 '11 at 09:46
1

Something like -

var foundin = $('p:contains("I am a simple string")');
foundin.each(function () {
    var linktext = $(this).html().replace('I am a simple string','<a href="">I am a simple string</a>');
    $(this).html(linktext);
});  

Or using your example -

var foundin = $('p:contains("testing")');
foundin.each(function () {
    var linktext = $(this).html().replace(/testing/ig, '<a href="http://testing.com">testing</a>'));
    $(this).html(linktext);
});  

Technique taken from - Find text string using jQuery?

Community
  • 1
  • 1
ipr101
  • 24,096
  • 8
  • 59
  • 61
  • Seems to be copied from here. http://stackoverflow.com/questions/926580/find-text-string-using-jquery/926633#comment-3560223 – GolezTrol Aug 06 '11 at 09:09
  • Copied is a bit harsh, I'd say adapted rather that copied. I've added a credit to the answer text just to make things clearer. – ipr101 Aug 06 '11 at 09:12
  • will `contains` be case insensitive? or should I be using `icontains` (in the link referred to in my post), also is this an efficient method if I have a long list of keywords and their corresponding URLs? – freethinker Aug 06 '11 at 09:13
  • @ipr101 "Copied is a bit harsh" That's true. That's why I've undone my downvote, even before you asked for an explanation. ;) – GolezTrol Aug 06 '11 at 09:18
  • @freethinker - Yes if you wanted a case insensitive search you'd need to use 'icontains'. – ipr101 Aug 06 '11 at 09:19
0

Have you tried this:

Put them in span with class "URLify" and based on what data you get just replace the innerText of the span by creating the URL on the fly with your code

Here is some text with this <span class="URLify">DataItem</span> to be search and replaced with URL or just to be URLified

In your jQuery you can do something like this (not tested)

var URL = "http://www.myapp.com/ListOfItems/"; //the url to use or append item to

$('.URLify').wrapInner('<a href="'+URL+'"></a>');

or if you want to append "DataItem" to ".../ListOfItems/" you can do that too...

PhD
  • 11,202
  • 14
  • 64
  • 112
  • I have now way to wrap the text into span elements, these are pre-generated static html files that I'm dealing with. – freethinker Aug 06 '11 at 09:04
  • Then I suggest using "search and replace" using jQuery and javascript string operations. If there's no structure whatsoever then IMO this is the only fallback... – PhD Aug 06 '11 at 09:06
0

JQuery will not give you text nodes. You will have to check for text nodes explicitly using a JQuery filter, of by just traversing the DOM (which is probably faster in this case). An example is given here on SO.

Community
  • 1
  • 1
GolezTrol
  • 114,394
  • 18
  • 182
  • 210