Sunday, February 10, 2008

Make Your Blog Speak More Languages

I speak and write English (Americanised English, for you Brits). Until this weekend, my blogs were all published in English, and in English only. Thanks to the Kaspersky fiasco of Friday (Kaspersky is a Russian product), however, I was motivated to correct that shortcoming.

This was, surprisingly, an easier task than I had anticipated. If you will examine the sidebar, you will observe my multi-lingual translator, courtesy of Google Translator. It provides on the fly translation of the currently displayed web page, and whatever web pages that are subsequently loaded from following any links. It provides translation from English, to any of (currently, as of 10/22/2008) 34 different languages. You can see the enumeration of the available languages below, in the code, or you can move the mouse over each flag, and check out the popup tags.

The translator applet code is surprisingly compact, and expandable with additional languages. It's well defined too - "<form ... > ... </form>" is the entire package. Stretch the browser window widely enough, so you can see all of the text, please. And be very careful of any gratuitous line breaks.

(Update 2008/12/18):There was a small coding error which I have removed from the code below, which you may wish to remove from your copy (if you have installed this on your blog) when convenient.


<form action="http://www.google.com/translate">

<script language="javascript" type="text/javascript">

<!--

document.write ("<input name=u value="+location.href+" type=hidden>")

// -->

</script>

<noscript><input value="http://blogging.nitecruzr.net/" name="u" type="hidden"/></noscript>

<input value="en" name="hl" type="hidden"/>

<input value="UTF8" name="ie" type="hidden"/>

<input value="" name="langpair" type="hidden"/>

<input onclick="this.form.langpair.value=this.value" title="Andorran / Catalan" value="en|ca" type="image" height="20" src="http://1.bp.blogspot.com/__v4nth5_ki0/SP-fM7vwhSI/AAAAAAAAHl0/ZoZkfhEb01M/s320/Andorra+-+Catalan+-+ad_flag.png" width="30" name="langpair"/>

<input onclick="this.form.langpair.value=this.value" title="العربية / Arabic" value="en|ar" type="image" height="20" src="http://photos1.blogger.com/x/blogger2/6075/564571464515337/1600/z/358406/gse_multipart12399.png" width="30" name="langpair"/>

<input onclick="this.form.langpair.value=this.value" title=" България / Bulgaria" value="en|bg" type="image" height="20" src="http://2.bp.blogspot.com/__v4nth5_ki0/SMiXtQx-uLI/AAAAAAAAG6I/RuLPDhnFMXY/s320/Bulgaria+-+bg_flag.png" width="30" name="langpair"/>

<input onclick="this.form.langpair.value=this.value" title="中文(简体) / Chinese (Simplified)" value="en|zh-CN" type="image" height="20" src="http://photos1.blogger.com/x/blogger2/6075/564571464515337/1600/z/546049/gse_multipart12397.png" width="30" name="langpair"/>

<input onclick="this.form.langpair.value=this.value" title="中文(繁体) / Chinese (Traditional)" value="en|zh-TW" type="image" height="20" src="http://photos1.blogger.com/x/blogger2/6075/564571464515337/1600/z/208681/gse_multipart12398.png" width="30" name="langpair"/>

<input onclick="this.form.langpair.value=this.value" title="Hrvatska / Croatian" value="en|hr" type="image" height="20" src="http://1.bp.blogspot.com/__v4nth5_ki0/SMhVoigYF0I/AAAAAAAAG5s/naE3NObTVZs/s400/Croatia+-+hr_flag.png" width="30" name="langpair"/>

<input onclick="this.form.langpair.value=this.value" title="Česká Republika / Czech Republic " value="en|cs" type="image" height="20" src="http://4.bp.blogspot.com/__v4nth5_ki0/SMiX9aMIL3I/AAAAAAAAG6o/4-RYadolKWQ/s320/Czech+Republic+-+cs_flag.png" width="30" name="langpair"/>

<input onclick="this.form.langpair.value=this.value" title="Danmark / Denmark" value="en|da" type="image" height="20" src="http://2.bp.blogspot.com/__v4nth5_ki0/SMiX9nD1NZI/AAAAAAAAG6w/ZnIBEtLIHEw/s320/Denmark+-+da_flag.png" width="30" name="langpair"/>

<input onclick="this.form.langpair.value=this.value" title="Suomi / Finnish" value="en|fi" type="image" height="20" src="http://2.bp.blogspot.com/__v4nth5_ki0/SMiZwsOFndI/AAAAAAAAG8w/VlBr_zN32q8/s320/Finland+-+fi_flag.png" width="30" name="langpair"/>

<input onclick="this.form.langpair.value=this.value" title="Français / French" value="en|fr" type="image" height="20" src="http://photos1.blogger.com/x/blogger2/6075/564571464515337/1600/z/327620/gse_multipart12413.png" width="30" name="langpair"/>

<input onclick="this.form.langpair.value=this.value" title="Deutsch / German" value="en|de" type="image" height="20" src="http://photos1.blogger.com/x/blogger2/6075/564571464515337/1600/z/734899/gse_multipart12400.png" width="30" name="langpair"/>

<input onclick="this.form.langpair.value=this.value" title="Ελλάς / Greek" value="en|el" type="image" height="20" src="http://bp3.blogger.com/_pzC_7PLtN-0/R7CKOqA_bjI/AAAAAAAAA8A/7bmPVwaFDcQ/s320/Greek+Flag+36x24.png" width="30" name="langpair"/>

<input onclick="this.form.langpair.value=this.value" title="ישראל / Hebrew" value="en|iw" type="image" height="20" src="http://4.bp.blogspot.com/__v4nth5_ki0/SP-fNBP-7LI/AAAAAAAAHmE/fJeA_Sbl9w4/s320/Israel+-+il_flag.png" width="30" name="langpair"/>

<input onclick="this.form.langpair.value=this.value" title="Hindi / India" value="en|hi" type="image" height="20" src="http://4.bp.blogspot.com/__v4nth5_ki0/SMiYu9muwaI/AAAAAAAAG7Y/lO6YgNdyHM4/s320/India+-+hi_flag.png" width="30" name="langpair"/>

<input onclick="this.form.langpair.value=this.value" title="Bahasa / Indonesian" value="en|id" type="image" height="20" src="http://4.bp.blogspot.com/__v4nth5_ki0/SP-fNKvGgZI/AAAAAAAAHl8/UESh2PimM5U/s320/Indonesia+-+id_flag.png" width="30" name="langpair"/>

<input onclick="this.form.langpair.value=this.value" title="Italiano / Italian" value="en|it" type="image" height="20" src="http://photos1.blogger.com/x/blogger2/6075/564571464515337/1600/z/306145/gse_multipart12401.png" width="30" name="langpair"/>

<input onclick="this.form.langpair.value=this.value" title="日本語 / Japanese" value="en|ja" type="image" height="20" src="http://photos1.blogger.com/x/blogger2/6075/564571464515337/1600/z/443122/gse_multipart12402.png" width="30" name="langpair"/>

<input onclick="this.form.langpair.value=this.value" title="한국어 / Korean" value="en|ko" type="image" height="20" src="http://photos1.blogger.com/x/blogger2/6075/564571464515337/1600/z/581031/gse_multipart12403.png" width="30" name="langpair"/>

<input onclick="this.form.langpair.value=this.value" title="Latvija / Latvian" value="en|lv" type="image" height="20" src="http://2.bp.blogspot.com/__v4nth5_ki0/SP-fNX2rCXI/AAAAAAAAHmM/1LRWqh7YQBA/s320/Latvia+-+lv_flag.png" width="30" name="langpair"/>

<input onclick="this.form.langpair.value=this.value" title="Lietuvos / Lithuania" value="en|lt" type="image" height="20" src="http://2.bp.blogspot.com/__v4nth5_ki0/SP-fNrJizVI/AAAAAAAAHmU/kdaran4uffk/s320/Lithuania+-+lt_flag.png" width="30" name="langpair"/>

<input onclick="this.form.langpair.value=this.value" title="Nederland / Dutch" value="en|nl" type="image" height="20" src="http://1.bp.blogspot.com/__v4nth5_ki0/SMiZWUAFSOI/AAAAAAAAG74/lsNT2NI_oFI/s320/Netherlands+-+nl_flag.png" width="30" name="langpair"/>

<input onclick="this.form.langpair.value=this.value" title="Norge / Norwegian" value="en|no" type="image" height="20" src="http://2.bp.blogspot.com/__v4nth5_ki0/SMiZWYWSvEI/AAAAAAAAG8A/7sOoou7far0/s320/Norway+-+no_flag.png" width="30" name="langpair"/>

<input onclick="this.form.langpair.value=this.value" title="Pilipinas / Philipines" value="en|tl" type="image" height="20" src="http://1.bp.blogspot.com/__v4nth5_ki0/SP-f7gyN2aI/AAAAAAAAHmc/x_LSaXlHtCs/s320/Pilipnas+-+ph_flag.png" width="30" name="langpair"/>

<input onclick="this.form.langpair.value=this.value" title="Polska / Polish" value="en|pl" type="image" height="20" src="http://bp1.blogger.com/_pzC_7PLtN-0/R7CAvKA_bgI/AAAAAAAAA7o/pKLqrW8EpD4/s320/Polish+Flag+36x24.png" width="30" name="langpair"/>

<input onclick="this.form.langpair.value=this.value" title="Português / Portuguese" value="en|pt" type="image" height="20" src="http://photos1.blogger.com/x/blogger2/6075/564571464515337/1600/z/670301/gse_multipart12404.png" width="30" name="langpair"/>

<input onclick="this.form.langpair.value=this.value" title="România / Romanian" value="en|ro" type="image" height="20" src="http://bp2.blogger.com/_pzC_7PLtN-0/R7CAvaA_bhI/AAAAAAAAA7w/HTWQoR8M6lQ/s320/Romainian+Flag+36x24.png" width="30" name="langpair"/>

<input onclick="this.form.langpair.value=this.value" title="Русский / Russian" value="en|ru" type="image" height="20" src="http://photos1.blogger.com/x/blogger2/6075/564571464515337/1600/z/111692/gse_multipart12405.png" width="30" name="langpair"/>

<input onclick="this.form.langpair.value=this.value" title="Србија / Serbia" value="en|sr" type="image" height="20" src="http://3.bp.blogspot.com/__v4nth5_ki0/SP-f7_imioI/AAAAAAAAHmk/ytbpoyJHbmo/s320/Serbia+-+si_flag.png" width="30" name="langpair"/>

<input onclick="this.form.langpair.value=this.value" title="Slovenčina / Slovak" value="en|sk" type="image" height="20" src="http://4.bp.blogspot.com/__v4nth5_ki0/SP-f79KzfyI/AAAAAAAAHms/-I315jcpHN0/s320/Slovak+-+sk_flag.png" width="30" name="langpair"/>

<input onclick="this.form.langpair.value=this.value" title="Slovenija / Slovenia" value="en|sl" type="image" height="20" src="http://1.bp.blogspot.com/__v4nth5_ki0/SP-f8P0fwiI/AAAAAAAAHm0/Lzeh8mXiWvE/s320/Slovenia+-+si_flag.png" width="30" name="langpair"/>

<input onclick="this.form.langpair.value=this.value" title="Español / Spanish" value="en|es" type="image" height="20" src="http://photos1.blogger.com/x/blogger2/6075/564571464515337/1600/z/998398/gse_multipart12407.png" width="30" name="langpair"/>

<input onclick="this.form.langpair.value=this.value" title="Sverige / Swedish" value="en|sv" type="image" height="20" src="http://1.bp.blogspot.com/__v4nth5_ki0/SMiZwrYspyI/AAAAAAAAG8o/uVUWBAyZkVc/s320/Sweden+-+se_flag.png" width="30" name="langpair"/>

<input onclick="this.form.langpair.value=this.value" title="Україна / Ukraine" value="en|uk" type="image" height="20" src="http://3.bp.blogspot.com/__v4nth5_ki0/SP-f8Bg1AMI/AAAAAAAAHm8/b4jhQQPSvj4/s320/Ukraine+-+ua_flag.png" width="30" name="langpair"/>

<input onclick="this.form.langpair.value=this.value" title="tiếng Việt / Vietnam" value="en|vi" type="image" height="20" src="http://2.bp.blogspot.com/__v4nth5_ki0/SP-gZakjpuI/AAAAAAAAHnE/fwfNZkisDOA/s320/Vietnam+-+vn_flag.png" width="30" name="langpair"/>

</form>

<a href="http://blogging.nitecruzr.net/2008/02/make-your-blog-speak-more-languages.html"><span style="font-weight:bold;">What Are These?</span></a>


Each entry of the above appears modular. My hope is that, as Google continues developing its linguistic resources, additional languages will become available. Here, for instance, is the Arabic entry. Note that Arabic, being a language written right to left, requires a template that supports bi-directional text justification.

<input onclick="this.form.langpair.value=this.value" title="العربية / Arabic" value="en|ar"
src="http://photos1.blogger.com/x/blogger2/6075/564571464515337/1600/z/358406/gse_multipart12399.png"
name="langpair" height="20" type="image" width="30">

This entry requires just 3 unique elements.
  • When you hover the mouse over the flag, you see
    العربية / Arabic
  • The definition of English to Arabic translation is
    en|ar
  • The picture of the Arabic flag, resized to 30px x 20px, in 1600 pixels resolution, is
    http://photos1.blogger.com/x/blogger2/
    6075/564571464515337/1600/z/358406/gse_multipart12399.png

Each of the other language entries, similarly, require another corresponding 3 unique elements. The array of flags are universal language symbols, that are obvious to the inhabitants of the various countries, so they need no captions.

If you want your blog to reach the world, I can't think of an easier way to encourage that to happen.
  • Add a new HTML / JavaScript gadget.
  • Highlight, Copy, then Paste the code ("<form ... > ... </form>"), exactly as presented above, directly into the Content window in the new HTML / JavaScript gadget. Do not copy anything into Notepad, or any other word processor that might have trouble with the UTF-8 character set. The code above includes UTF-8 characters, in the Asian language labels - if you try to save anything as ANSI, you will get a warning, and possible code corruption.
  • Make one simple change - correct the blog URL, to identify your blog (in this example, "myblog.blogspot.com").
    <noscript><input value="http://blogging.nitecruzr.net/" name="u" type="hidden"/></noscript>
    change to
    <noscript><input value="http://myblog.blogspot.com/" name="u" type="hidden"/></noscript>
  • Save.
  • Test, and admire, your new world ability.

It took me several hours to write (and rewrite) this. It took me 10 minutes to set up the gadget on this blog, and 5 minutes to add this to PChuck's Network.

Having said all of that, I will note that je parle un peu de francais, and yo hablo un poco de espanol. And briefly examining (5 minutes of each) various translated pages in those two languages, I can note what I will discretely call "oddities". Both PChuck's Network and The Real Blogger Status are techie blogs, and I will bet quite heavily that not all technical terms that I use will be properly translated. But this is a start.

And next, I will note that the setup described above translates from English into other languages. If your blog is written in, let's say, Spanish, you'll want to translate from Spanish to the other languages. Change "English to Spanish" to "Spanish to English", and replace "en|es" with "es|en" (and, change the flag). Similarly, change "English to French" to "Spanish to French", and replace "en|fr" with "es|fr".

Do similarly with the other language pairs, noting a possible limitation. I strongly doubt that Google Translator, right now, will support all language pairs in all "from" and "to" combinations, symmetrically. You will find this out by experimentation, as I have yet to find a referential document enumerating what language pairs are supported.

I've been asked to make it easier for folks who produce blogs not written in English (what country is "English" native in?), in that I should include an "English" flag, for their use. That's now a future project, so watch this space.

For a more detailed discussion about this exciting blog accessory, see Roberto's Report: Language Translator Set-up.

For the official Google Translated Language Pairs list, see Google Translate FAQ: Language Pairs. Be advised that my applet above won't always be 100% up to date; but if you spot a new language in the Google list, that isn't in my applet, and let me know, I'll do my best to add it.

>> Top

19 comments:

C.R Jones said...

Greetings,

By coincidence I just created my own "Translate HTML" - but is not as sophisticated as this!

However I do note that cutting and pasting the above code STILL refers back to the miniflag.png's on your blogsite.

In my efforts I found that Google maintains a complete selection of world flags (ie http://www.google.com/images/flags/ar_flag.png). After a bit of head scratching I realized the flags use the International 2 letter identifiers for those countries TLD's - and not the Google TRANSLATE language codes (although in some cases they match - like Spain. It is es). As a neophye blogger I have added your resource blog to my "follow" list.

Thanks for the help. crj

http://personalqwest.blogspot.com/

Chuck said...

Welcome C.R.,

You're hitting on one of the first challenges in this project - the issue that country flags and languages won't map one to one. Some languages are shared between countries, and some countries have multiple languages.

When I want to yank Grumpy's chain (Grumpy is an Aussie), I mention "en|ae" (English translation to Aussie English). This makes him still Grumpier (LOL). Grumps is another Blog*Star, and half of this language project.

Similarly, Rose Desrochers is Canadian, and possibly Quebec Francois. The French language is common to France, to French Canadians, and to Louisana in the USA too. Each country of the world may lay claim to seeing their flag on our language toolbars.

But we'll take it one language pair at a time, for now. Thanks for your comments.

Now, let's see what this comment looks like.

RAV TUX said...

I have about four questions:

1. Where is the best place to place this in the HTML code?...before? after?

2. I want to enable both Hebrew and Arabic which both require the bi-directional text justification, where should this be placed?

3. I have a custom template that I use on both my blogs will these work on those?
reference:
http://www.ravtux.com/
http://www.lagomorphs.org/

4. Can this be added by a published Google Gadget?

Chuck said...

Rav,

1. You do NOT place this in the code - read above. You make an HTML / JavaScript gadget, and copy the code into the gadget.
2. If you want to include Arabic and Hebrew, you make sure that your template supports bi directional text justification.
3. Try it and see. If you have a layouts template, see if it will accept an HTML / JavaScript gadget, with the code above.
4. The Google Gadget idea is something that I am working on, in the back of my mind. This will happen one day, but I have no schedule for it right now.

Tony B said...

Very cool, keep up the good work

Mi-ka-El said...

I followed your instrutions above, but the translator isn't working. I get sent to the Google translate page that asks for text or webpage to be translated. I tried entering my blog's url and clicked on Translate. When the page reappears it isn't translated. I can't figure out what the problem is. Can you help.

By the way, I only found one instance of the http://blogurl that needed to be changed from yours to mine.

Chuck said...

Mi-ka,

(What nationality is that)? OK, I corrected the extra "blogurl" entry (from when I caused the coding problem noted above I think). I'm not sure what your problem is (you don't provide me a blog URL), but I'd start by making sure that there's no gratuitous line breaks in the code.

Mi-ka-El said...

Chuck,

Thanks for your reply to my previous comment. You ask what nationality Mi-ka-El is from. If you read the blog (once I get the design finished) you'll be able to find out. Would take too much space to explain here.

You also ask for the url of the blog. It is http://mi-ka-elmusings.blogspot.com. There you can try the translator gadget and see the result, which isn't working correctly. I copied the code you listed above (at this point excluding the Aribic bi-directional stuff). I tried to include in this comment the portion of the code I modified to reflect my blog's url (as I understood your instructions), but the code snippet wouldn't be accepted.

I went through the code and removed all extraneous line breaks, but that doesn't seem to be the problem. I tested the translator by clicking on the Spanish, French, German and Italian flags. However, I still get sent to the Google Translator as you should see if you test it yourself. What have I done wrong? Thanks for your help.

Also, for those whose native language is not English, it would be nice if you included an English flag (perhaps commented out until needed) with the appropriate insturctions for modifying the code to reflect the blogger's native language.

Thanks for your help.
Mike

Chuck said...

Mike,

LOL. The English flag? There is none. I live in the USA, but if I was to use a USA flag, I would piss off the Australians, the British, and a few USA citizens too (to say nothing of some "Americans"). See my comment to C.R. above for more on that subject.

I'll take a peek at your blog later today.

BTW, why don't you have a profile?

Chuck said...

Mike,

Let's try again. Recopy the code, and do not remove anything - neither content, nor line breaks. Make the one single change, as noted above, in my improved instructions.

Mi-ka-El said...

My profile? Don't you know angels don't have profiles? (lol) Actually, the blog is just being designed and I haven't gotten "that far" yet.

Let's see if I understand you correctly. I copied all of the (lengthy) code in the main post. I didn't remove anything. All I did is a) replace the "u" with my blog's url and b) went through the code and made sure the breaks were were wordwraps. You want me to copy/paste the code aain?

Chuck said...

Mike,

What I saw in your code was two places where you inserted the URL of your blog - both where it didn't belong, and one place where you left the URL of my blog - which is where the URL of your blog belonged.

So try again, re read the instructions very carefully, and re copy the code. And don't muck with the line breaks.

If it doesn't work this time, post in the BHG Broken forum, and we can go over the problem in detail. And comment back here so I know to look for your post in the forum.

marain said...

I experienced a similar problem as Mi-ka El and I solved it by going to the sidebar and with my right mouse click selecting View Source, and then searching for the "form" and copying from there until the end of the form and then pasting that into the HTML Java Script gadget and changing the URL to my blog URL. It works now. It's really beautiful and I thank you!

hackeandoelblog said...

thanks you help a lot whit this,i was looking for something like this,,

www.http://hackeandoelblog.blogspot.com/

thanks

The Fab Four said...

Excellent thank you so much!!!

Talk Pretty To Me said...

I am experiencing the same problem at Mi-ka El. I copied the code into the HTML javascript gadget and changed your URL to my URL and when I attempt to translate my blog it brings me to the google translator homepage and asks me to enter the url of the page I wish to translate. I enter my url and it still doesn't translate it.

R2K said...

This is nice :)

Elizabeth said...

thank you, will put this in my blog roll on my blog. Good work

Ligurio said...

Hi.

I copied the code to the html editor because finding a html/java gadget is not forward

When I run it it goes to google's translate page to input the page url.

I inserted my url http://www.drinkedin.blogspot.com/ as your instructions.