Posh Mama? The QVC of the Web is here Ext JS: A reminder that you are not alone
Apr 25

Translate: Select any text in the browser and have it convert to English (or your language)

Ajax, Google, JavaScript, Tech with tags: , , Add comments

Translate Bookmarklet

I really liked getting the Ajax Language API out into developers hands as god knows we shouldn’t have to worry about translations. Now we can use the API and have the Google back-end do all of the work.

I have recently had a couple of scenarios where I really wanted a quick translation. I had a few twitter messages pass through my stream in French and Spanish. I had the answer to some technical issues show up on foreign forums.

So, I decided to create a Translate bookmarklet that allows me to select any foreign text, click on the bookmark, and a little window pops up with the English translation if it can work it out. Automatic translation is far from perfect yet, but for many scenarios you can easily get the gist (e.g. you wouldn’t want to automatically convert a book).

This is how I created the bookmarklet:

The source

First, I have the raw JavaScript source that will become the bookmarklet. There are a few sections of the code. First, we setup a method that will go off and call the Ajax Language API, passing in the translation and language that we want. This is where you would change the language code for non-English.

if (!window['apiLoaded']) {
  window.apiLoaded = function() {
    var language = "en";
    var text = window.getSelection().toString();
    if (text) {
      google.load("language", "1", { "callback" : function() {
        google.language.detect(text, function(dresult) {
          if (!dresult.error && dresult.language) {
            google.language.translate(text, dresult.language, language, function(tresult) {
              if (tresult.translation) {
                translationWindow(tresult, dresult);
              } else {
                alert('No translation found for "' + text + '" guessing the language: ' + dresult.language);
              }
            });
          }
        });
      }});
    }
  };
}

Then we setup a method that is able to display a window showing the result. I used the Prototype UI Window object if available, and good old alert() if not:

if (!window['translationWindow']) {
  window.translationWindow = function(tresult, dresult) {
    if (window['UI']) {
      new UI.Window({theme:  "black_hud",
                   shadow: true, 
                   width:  350,
                   height: 100}).setContent("<div style='padding:6px'>" + tresult.translation + "</div>")
                   .setHeader("English Translation")
                   .setFooter("Language detected: " + dresult.language)
                   .center({top: 20}).show();
    } else {
      alert(tresult.translation + " [lang = " + dresult.language + "]");
    }
  }
}

Next, we load the Prototype UI window code, and accompanying CSS resources by dynamically adding the resources to the DOM:

if (!window['UI']) {
  var pw = document.createElement('script');
  pw.src = 'http://almaer.com/downloads/protowindow/protowin.js';
  pw.type = "text/javascript";
  document.getElementsByTagName('body')[0].appendChild(pw);
 
  var pwdefault = document.createElement('link');
  pwdefault.setAttribute('rel', 'stylesheet');
  pwdefault.setAttribute('type', 'text/css');
  pwdefault.setAttribute('href', 'http://almaer.com/downloads/protowindow/themes/window.css');
  document.getElementsByTagName('body')[0].appendChild(pwdefault);
 
  var pwblack = document.createElement('link');
  pwblack.setAttribute('rel', 'stylesheet');
  pwblack.setAttribute('type', 'text/css');
  pwblack.setAttribute('href', 'http://almaer.com/downloads/protowindow/themes/black_hud.css');
  document.getElementsByTagName('body')[0].appendChild(pwblack);
}

Finally, we load the Google API loader, and use the dynamic loading option with the ?callback=apiLoaded. This kicks off the main driver that we saw first, and if it is already loaded we call it directly (for multiple translations on the same page).

if (!window['google']) {
  var s = document.createElement('script');
  s.src = 'http://www.google.com/jsapi?callback=apiLoaded';
  s.type = "text/javascript";
  document.getElementsByTagName('body')[0].appendChild(s);
} else {
  apiLoaded();
};

“Compilation”

This is the raw form, and we need to get the bookmarklet form, which you can just use right away if you are wanting English. For this, I use John Grubber’s makebookmarklet Perl script to do the conversion.

The Server

The Prototype UI code lives on the server, so I put a striped down version over there which just contains a combined Prototype + Window JavaScript file, and just the one theme CSS set.

In Action

Unsure what I am talking about? Just watch it in action:

UPDATE: I also implemented Twitter Translate to automatically convert tweets to your language.

7 Responses to “Translate: Select any text in the browser and have it convert to English (or your language)”

  1. Benjamin Golub Says:

    Nice job! I’m loving using the Google Language API in RSSmeme. I didn’t know Mibbit was using it…I hear about them every once in a while but you’d be hard pressed to pry me away from irssi.

  2. halans Says:

    Crap, you beat me to it by one day. I’m in the middle of doing the same, but using jQuery and a home brewed (but similar) hud. I already had a mapping bookmarklet (www.mapanui.com), and, based on Mapanui, wanted another one for translation. But want to make it a bit more configurable (selecting target language,…).

  3. dion Says:

    Halans,

    Lots of room for more. Please ping me when yours is done so I can check it out!

    Cheers,

    Dion

  4. Patrick Says:

    Hi Dion,

    seems like it’s not working properly in Safari 3.1.1. I made a quick screencast demonstrating what happens:

    http://www.vimeo.com/950810

  5. Brian Says:

    Here’s another one:
    http://balazs.endresz.googlepages.com/translatebookmarklet

  6. Brian Says:

    the free translations of “Happy Birthday” in loads of languages are here if you want it…

    http://www.k-international.com/happy_birthday

  7. informale Says:

    Can get it to work, please help.

    I’m creating a bookmarklet with code copied from your translate-bookmarklet.js, but nothing happens when I click it :( At least in Google Chrome.

    What am I doing wrong? Do I need to enable User Jscript in Chrome and put some js file into user folder?

    Tried replacing %20 %21 and %22 with actual characters. It works either way in Opera, but still no luck in Chrome.

Leave a Reply

Spam is a pain, I am sorry to have to do this to you, but can you answer the question below?

Q: What is the number before 3? (just put in the digit)