Quality Reads

Wednesday, December 27, 2006

Add A Translation Tool To Your Blog

I added Google Analytics to my blog a couple weeks ago because I was interested to see where my web traffic was coming from. I was surprised at the percentage of views coming from non-English speaking countries (~33%). I started wondering if all these individuals were adept at reading English or were just muddling through my posts to get to the code (most of the views were for my code-related entries). After a minute or two of contemplation, it dawned on me I could make their life a whole lot easier by providing a translation tool. So, I jumped onto Google Translation and took a quick look at how they structure their URL variables. Here's the HTML/Javascript widget I came up with:

<form action="http://www.google.com/translate" onsubmit="this.u.value=window.location.href" method="GET">
<input value="en" name="hl" type="hidden"/>
<input value="UTF8" name="ie" type="hidden"/>
<input value="" name="u" type="hidden"/>
Select Language: <select name="langpair">
<option value="en|fr"/>French
<option value="en|de"/>German
<option value="en|it"/>Italian
<option value="en|pt"/>Portuguese
<option value="en|es"/>Spanish
<option value="en|ar"/>Arabic BETA
<option value="en|zh-CN"/>Chinese (Simplified) BETA
<option value="en|ja"/>Japanese BETA
<option value="en|ko"/>Korean BETA
<option value="en|ru"/>Russian BETA
</select><br/>
<input value="Translate" type="submit"/>
</form>

The form posts to Google's Translation Service and seems to do a good job of converting the page to the selected language. Please be aware of two things:

  1. The languages listed in Beta can mess with the page layout a little bit. Remove those from the select box option list if thats a major concern for you.

  2. The WHOLE page will be translated. If some of your posts deal with code examples, they will be turned into some bizarre/humorous pseudo-code.


To use the widget, just copy and paste the above code into the proper section of your blog Template. If you are using Blogger, paste the code into a "Third Party HTML/Javascript" module.
The widget works great and provides a nice way for people to read your posts in their native tongue. Please let me know if you run into any problems. I'll be more than happy to troubleshoot issues as they arise.

Enjoy!

Tuesday, December 26, 2006

Saturday, December 23, 2006

watch() :: One of Many Missing JS Functions in IE

I've been playing around with Adobe's Flex for a couple months now and one feature that keeps impressing me is the ease with which you can bind Actionscript variables to UI Elements. I started wondering if there was any way to attach an onchange event to a JavaScript variable so I could replicate the effect with HTML controls. After a little searching on Mozilla.org, I found the watch() function. You can check out the documentation here. Essentially, it will run a function that you define every time a JS variable is changed. Something very useful if you use data access objects to pass information back and forth in your AJAX applications. The problem is that IE doesn't support the method (surprise, surprise). So I set out to create a work around. Here's the resulting function:
 /* Cross Browser Watch Function */
Object.prototype.xwatch = function (prop,func){
if(!Object.watch){
new IEwatch(this,prop,func);
}
else{
this.watch(prop,func);
}
}
var IEwatch = Class.create();
IEwatch.prototype = {
initialize: function(obj,prop,func){
this.obj = obj;
this.prop = prop;
this.func = func;
this.oldvalue = this.obj[this.prop];
setInterval(this.check.bind(this),50);
},
check : function(){
if(this.obj[this.prop] != null && this.obj[this.prop] != this.oldvalue){
this.oldvalue=this.func(this.prop,this.oldvalue,this.obj[this.prop]);
}
}
}


First, I start off by extending the Object Class by adding a new method called xwatch (cross-browser watch). If the browser supports watch() then the native function is used otherwise my IEwatch method is used. IEwatch polls the variable specified looking for a change in the variable's value. Kinda crude but it works. I haven't run into any problems with race situations yet.

I also created the function below to bind a JS variable to another Object. You could use it to bind a variable to a text input or the innerHTML property of a div etc etc.

/* Data Bind Functions */
var dataBinding = Class.create();
dataBinding.prototype = {
initialize: function(sourceObj, sourceProp, destinationObj, destinationProp){
this.srcObj=sourceObj;
this.srcProp=sourceProp;
this.destObj=destinationObj;
this.destProp=destinationProp;
var temp = this.update(this.sourceProp, this.srcObj[this.srcProp],this.srcObj[this.srcProp]);
this.create();
},
create: function(){
this.srcObj.xwatch(this.srcProp,this.update.bind(this));
},
update: function(id, oldvalue, newvalue){
this.destObj[this.destProp] = newvalue;
return newvalue;
}
}

Note, these Classes required prototype.js to function.