Change all website links to affiliate links automatically - javascript

I would like to be able to automatically change links into affiliate links automatically on my MediaWiki installation. This would help to reduce the amount of time managing links in case the code needs to be changed in the future.
This is the setup of my GOG.com affiliate scheme: I need to append this key to the end of every GOG.com link: ?pp=708a77db476d737e54b8bf4663fc79b346d696d2
gog.com/en/gamecard/baldurs_gate_the_original_saga/?pp=708a77db476d737e54b8bf4663fc79b346d696d2
Is it possible for a piece of code, like Javascript, to intercept all links (like http://www.gog.com/en/gamecard/baldurs_gate_the_original_saga/) and append the affiliate code on the end, as in the above example?
I'm aware of this piece of Javascript code called Amazon Associate Link Localiser which does a similar thing. However, it only works for Amazon links, and it also localises links which is a feature I don't want.

Right way is to use LinkerMakeExternalLink mediawiki hook like that ( you can put it at bottom of your LocalSettings.php:
$wgHooks['LinkerMakeExternalLink'][] = 'ExampleExtension::exampleLinkerMakeExternalLink';
class ExampleExtension {
public static function exampleLinkerMakeExternalLink( &$url, &$text, &$link, &$attribs, $linktype ) {
if( strpos( $url, 'gog.com') !== false ) {
$url .= '?pp=708a77db476d737e54b8bf4663fc79b346d696d2';
}
return false;
}
}

Not sure how great it would be performance wise for hundreds of links.
// Plain Javascript
var links = document.getElementsByTagName('a');
for (var i = 0, max = links.length; i < max; i++) {
var _href = links[i].href;
if (_href.indexOf('gog.com') !== -1) {
links[i].href = _href + '?pp=708a77db476d737e54b8bf4663fc79b346d696d2';
}
}
DEMO

So you can also use jquery to bind any link click. This way you can do your link eval on the fly. This jsfiddle is a rough run through of what i think you're trying to accomplish. The alerts are just for your benefit and should be removed.
$("a").click(function() {
addAffiliate(this);
});
myCode = "?pp=708a77db476d737e54b8bf4663fc79b346d696d2";
myAmazonCode = "?tag=shihac-20"
function addAffiliate(link) {
alert("enterting script: " + link.href);
if ((link.href).indexOf("gog.com") > -1 && (link.href).indexOf(myCode) < 0) {
link.href = link.href + myCode;
}else if((link.href).indexOf("amazon.com") > -1 && (link.href).indexOf(myAmazonCode) < 0){
link.href = link.href + myAmazonCode;
}
alert(link.href);
return true;
}​
http://jsfiddle.net/du47b/23/
UPDATE: added code and fully qualified paths
UPDATE: added 'else if' block for other codes. using 'else if' instead of just another if block will hopefully cut back on unnecessary processing.

Related

How do I make external links pass through an affiliate link first using .htaccess or Javascript?

I have a significant amount of external links on my website in this format:
website.com/product/[variable]
I need these links to somehow pass through “myaffiliatelink.com” before being redirected to website.com/product/[variable].
Is this possible using .htaccess or Javascript?
I looked into using .htaccess, but seems I would need to do this individually. Is there a way to set a rule such that any external link using "website.com/product/[variable]" should pass through "myaffiliatelink.com" first?
// catch every click on the page
document.addEventListener("click", e => {
const target = e.target;
if (target.tagName === 'A' && target.href.indexOf("website.com") !== -1) {
// prevent the <a> tag from navigating
e.preventDefault();
const lastSlash = target.href.lastIndexOf('/');
if (lastSlash > 0) {
const variable = target.href.substring(lastSlash + 1);
// use the commented code below, or a window.open
//location.href = "https://myaffiliatelink.com/"+variable;
// for demonstration
console.log("https://myaffiliatelink.com/" + variable);
}
}
})
Product
<p>should pass through "myaffiliatelink.com"</p>

Ideas for a correct function on my webpage?

I am having problems with a javascript function. I want to replace an icon by changing the class.
On my page, I have the following element:
<i class="wait icon" alt="{webui_botstatenotavailable}" title="{webui_botstatenotavailable}" id="{botname}"></i>
The following javascript should change the class, but it does not work:
function incomingBotStatusList(http_request, statusOff, statusOn)
{
if (http_request.readyState == 4)
{
if (http_request.status == 200)
{
if (http_request.responseText.length < 7)
{
// Error
}
else
{
var botStatusList = JSON.parse(http_request.responseText);
for (var key in botStatusList)
{
if (botStatusList.hasOwnProperty(key))
{
var botStatusImage = document.getElementById(key);
if (botStatusImage != null)
{
if (botStatusList[key] == 0)
{
botStatusImage.class.innerHTML = "images/bullet_red.png";
botStatusImage.title = statusOff;
botStatusImage.alt = statusOff;
}
else if (botStatusList[key] == 1)
{
botStatusImage.class.innerHTML = "<i class=\"checkmark green icon\">";
botStatusImage.alt = statusOn;
botStatusImage.title = statusOn;
}
}
}
}
}
}
}
}
Did someone from you know how it will work?
Thanks for your help!
Best Regards
Pierre
I see a couple of problems with your code. First, the <i> element is used to apply italic formatting to text. It is not the HTML code for an icon or an image.
Secondly, you write botStatusImage.class.innerHTML, but the Element.class does not exist, and Element.className is a string. It does not have an innerHTML attribute. So, you could write botStatusImage.className = "new_class_name"; and this would be more correct.
You should then change the image source by calling botStatusImage.setAttribute('src', new_url), where you have set new_url to the new image location.
Check out the javascript reference for the Element class that is returned from document.getElementById: check this link
My recommendation, start simple, then make it complex.
First, try to get the icon to change without the AJAX request. Try writing a function like this:
function changeIcon( imageId, newUrl ){
var element = document.getElementById( imageId );
element.setAttribute( "src", newUrl );
}
Then test this function in the console by passing calling it with the URL's manually.
Once that works, don't change it! Next add the AJAX call, and when you have the Icon url from your server response, all you do is call the function that you already wrote and tested. That way you separate the AJAX code from the image update code and you can test them separately.
The key is smaller functions. Build the easy stuff first, and then call those easy functions from the harder functions. Once you know the easy function works well, it becomes much easier to find problems in the harder functions.

only add script to head if doesn't exist

I want to add additional scripts and styles to my site when a specific div is loaded.
I start out by defining a path to either a script or stylesheet and then create an element. Hereafter I append the element to the head tag in HTML.
But I would like a way to see if the script or stylesheet already has been append before I append it again. It would be stupid to append an already existing script or stylesheet.
Q: How do I use javascript to check wether or not a script already exists in the head tag, and then append the element if not?
EDIT
I have made a function based on the answer from #KernelPanik. It doesn't work yet but hopefully it will. The function is currently in question: my script appending function doesn't work
If you can use jquery, this code is good
function appendScript(filepath) {
if ($('head script[src="' + filepath + '"]').length > 0)
return;
var ele = document.createElement('script');
ele.setAttribute("type", "text/javascript");
ele.setAttribute("src", filepath);
$('head').append(ele);
}
function appendStyle(filepath) {
if ($('head link[href="' + filepath + '"]').length > 0)
return;
var ele = document.createElement('link');
ele.setAttribute("type", "text/css");
ele.setAttribute("rel", "Stylesheet");
ele.setAttribute("href", filepath);
$('head').append(ele);
}
In your code write
appendScript('/Scripts/myScript.js');
appendStyle('/Content/myStyle.css');
var lib = '/public/js/lib.js';
if (!isLoadedScript(lib)) {
loadScript(lib);
}
// Detect if library loaded
function isLoadedScript(lib) {
return document.querySelectorAll('[src="' + lib + '"]').length > 0
}
// Load library
function loadScript(lib) {
var script = document.createElement('script');
script.setAttribute('src', lib);
document.getElementsByTagName('head')[0].appendChild(script);
return script;
}
You can use the DOM getElementsByTagName("script") to get all of the <script> tags in the document. Then you can check the src urls of each script tag returned, for the url of the script(s) that you have added to the head section. Likewise, you can do something similar for the style sheets by replacing the search of "script" with "style".
For example, if the url of the script appended to the <head> section is header_url.html
var x = document.getElementsByTagName("script");
var header_already_added = false;
for (var i=0; i< x.length; i++){
if (x[i].src == "header_url.html"){
// ... do not add header again
header_already_added = true;
}
}
if (header_already_added == false){
// add header if not already added
}
Likewise, if the url of the style appended to the <head> section is header_style.css
var x = document.getElementsByTagName("style");
var header_already_added = false;
for (var i=0; i< x.length; i++){
if (x[i].src == "header_style.css"){
// ... do not add header again
header_already_added = true;
}
}
if (header_already_added == false){
// add header if not already added
}
A similar question was also asked here: Check if Javascript script exists on page
I used Jack Lee's solution. It was easy to implement and quickly versitile with just about any type file.... I didn't expand on anything ...I actually probably stupefied it a bit... just wanted to list what I did in case it helps someone else...
var lib_jq = '//pathtofile/jquery.js';
var lib_bs = '//pathtofile/bootstrap.min.3.5.js';
var lib_cs = '//pathtofile.css';
///checks files with the SRC attribute
function isLoadedScript(lib) {
return document.querySelectorAll('[src="' + lib + '"]').length > 0
}
///checks files with the HREF attribute
function isLoadedCss(lib) {
return document.querySelectorAll('[href="' + lib + '"]').length > 0
}
///loads the script.js files
function loadScript(link) {
document.write('<scr' + 'ipt type="text/javascript" src="'+link+'"></scr' + 'ipt>');
}
///loads the style.css files
function loadCss(link) {
document.write('<link rel="stylesheet" href="'+link+'">');
}
/// run funtion; if no file is listed, then it runs the function to grab the URL listed. ///Run a seperate one for each file you wish to check.
if (!isLoadedScript(lib_jq)) { loadScript(lib_jq); }
if (!isLoadedScript(lib_bs)) { loadScript(lib_bs); }
if (!isLoadedCss(lib_cs)) { loadCss(lib_cs); }
I know there is always a "better" and more "elegant" solution, but for us beginiers, we got to get it working before we can start to understand it...
Another way with a function helper like below
function isScriptAlreadyPresent(url) {
var scripts = Array.prototype.slice.call(document.scripts);
return scripts.some(function(el) {
return el.src && el.src != undefined && el.src == url;
});
}
isScriptAlreadyPresent('http://your_script_url.tld/your_lib.js');
It uses Array.prototype.some function. You may need a es5-shim if your are in browsers not supporting ES5 (IE7 and IE8...)
maybe headjs can help you.
or maybe you can add onload attribute in the script tag.
my english is a little poor,so maybe i'm misunderstand your question.
if(ie){
js.onreadystatechange = function(){
if(js.readyState == 'complete'){
callback(js);
}
}
else{
js.onload = function(){
callback(js);
}
You can try calling some function, object, variable from that js script file, if it finds it then it exists, if not, you need to insert that js script file.

If ? found in redirect url, then change url

Please see this jsfiddle.
I have got it developed for stackflow only..
Now i just have a little problem with it.
If the final url which will be redirected consist of ? or & in it, then instead of addQueryString , addQueryString1 should be used..
Can anyone help please.
Sorry Rohit and Tim. I thought it would be easier if you see the code directly there. But here is my code :
// Plain Javascript
var links = document.getElementsByTagName('a');
for (var i = 0, max = links.length; i < max; i++) {
var _href = links[i].href;
var addQueryString = "?utm_source=tyroo&utm_medium=affiliate&utm_campaign=12june12_20percenteossoffer";
var addQueryString1 = "&utm_source=tyroo&utm_medium=affiliate&utm_campaign=12june12_20percenteossoffer";
if (_href.indexOf('gog.com') !== -1) {
links[i].href = 'http://example.com/lnkurl=' + _href + encodeURIComponent(addQueryString);
}
}
​
It is a code for redirecting affiliate link found in the webpage via a affiliate url so that we earn commission from the links posted by users.
In my code, any link of gog.com will be redirected as http://example.com/lnkurl=http://www.gog.com/%3Futm_source%3Dtyroo%26utm_medium%3Daffiliate%26utm_campaign%3D12june12_20percenteossoffer
Now i am asking you guyz, that if the link is for ex, gog.com/test?price=xyz
Now you see the link itself contain a ? and = in it. So the redirected url as per my script will become : http://example.com/lnkurl=http://www.gog.com/test?price=xyz%3Futm_source%3Dtyroo%26utm_medium%3Daffiliate%26utm_campaign%3D12june12_20percenteossoffer
which won't work.
All i want to do is, if the url contains any ? or & or = in it, then it should use addQueryString1 instead of addQueryString .. and also, if possible, the content in url starting from ? or & should also be encoded..
Please help if you guyz can.. thanks
I think you are looking for a javascript solution. if so you can follow this
if(url.indexOf("?") != -1)
{
//? is present
} else {
//? is not present
}
Same for &

How can I call a function when the mouse is no longer over a nav link?

I have nav code like this in my HTML file:
<div id="center_links">
<ul>
<li>about</li>
<li>blog</li>
...and so on.
My JavaScript looks like this:
function setSideText(setting)
{
if (setting == 0) // Home
{
document.getElementById('center_text').innerHTML = '<p><div class="dropcap">#</div>I am an information technology student interested in free and open source software.</p>';
}
else if (setting == 1) // About
{
document.getElementById('center_text').innerHTML = '<p><div class="dropcap">#</div>My name is David Gay, and this is my website. Welcome.</p>';
}
else if (setting == 2) // Blog
{
document.getElementById('center_text').innerHTML = '<p><div class="dropcap">#</div>My blog runs on the Chyrp blog software.';
}
When I mouseover a link, the side text on my page changes to describe the link. I want the text to change back to the default (setSideText(0)) when I'm not mousing over a nav link. I've been playing around with it for a bit now and I haven't been able to figure it out.
I tried adding this to the JavaScript file, but to no avail:
document.getElementById('center_links').onMouseOut = setSideText(0);
I figured it wouldn't work, anyway.
I'm sure there's a simple solution that I'm not thinking of (I just picked up the language). Any guidance is appreciated!
I'd make two primary suggestions, the first: don't use inline event-handlers (it's more maintainable to have your behaviour in one place) and the second is to use onmouseout on the parent center_links element.
To that end:
function setSideText(setting) {
if (setting == 0) // Home
{
document.getElementById('center_text').innerHTML = '<p><div class="dropcap">#</div>I am an information technology student interested in free and open source software.</p>';
}
else if (setting == 1) // About
{
document.getElementById('center_text').innerHTML = '<p><div class="dropcap">#</div>My name is David Gay, and this is my website. Welcome.</p>';
}
else if (setting == 2) // Blog
{
document.getElementById('center_text').innerHTML = '<p><div class="dropcap">#</div>My blog runs on the Chyrp blog software.';
}
}
var linksElem = document.getElementById('center_links'),
links = linksElem.getElementsByTagName('a');
for (var i = 0, len = links.length; i < len; i++) {
links[i].dataIndex = i+1;
links[i].onmouseover = function() {
setSideText(this.dataIndex);
};
}
linksElem.onmouseout = function(){
setSideText(0);
}
JS Fiddle demo.
Edited to amend the setSideText() function to respond to words rather than an index (because I think it's easier for adding subsequent links at a later date and doesn't rely on being able to add arbitrary attributes to the elements, though it does require that the element have an id attribute...):
function setSideText(setting) {
if (setting == 'home' || setting == 0)
{
document.getElementById('center_text').innerHTML = '<p><div class="dropcap">#</div>I am an information technology student interested in free and open source software.</p>';
}
else if (setting == 'about')
{
document.getElementById('center_text').innerHTML = '<p><div class="dropcap">#</div>My name is David Gay, and this is my website. Welcome.</p>';
}
else if (setting == 'blog')
{
document.getElementById('center_text').innerHTML = '<p><div class="dropcap">#</div>My blog runs on the Chyrp blog software.';
}
}
var linksElem = document.getElementById('center_links'),
links = linksElem.getElementsByTagName('a');
for (var i = 0, len = links.length; i < len; i++) {
links[i].onmouseover = function() {
setSideText(this.id);
};
}
linksElem.onmouseout = function(){
setSideText(0);
}
JS Fiddle demo.
The only reason why that didn't work is because when setting these DOM events in Javascript, there is no capitalization; simply change .onMouseOut to .onmouseout.
I have no idea why they decided to be inconsistent between the HTML and Javascript names of these events. (Another reason why people hate on the DOM, I suppose.)
You need to trigger the function onMouseOut the same way you trigger the function onMouseOver
Your link HTML needs to look like this:
blog
I would recommend looking into jQuery for stuff like this - it makes handling events and DOM manipulation much more straight forward!
There's a great free course here: http://tutsplus.com/course/30-days-to-learn-jquery/

Categories