A Solution for a Bilingual WordPress

Bilingual ?The ability to maintain a weblog in two (or more) languages is an often requested feature, especially by people like me who just can't make up their mind between French and English :)
I've come up with a very easy way to implement this in an existing website, as you can see by yourself if you click on the tiny flags. I've also added cookie support, so you just need to chose a language once. This may not be *the* perfect solution, it's just one way, and a very simple one to add in an existing site.


The trick : you have two div's, one with attribute "lang=fr", one with "lang=en". A small javascript hides every divs with a particular "lang" and shows the others.

The javascript part

First, put the following code in your index.php, or in an external javascript file :

  1. function createCookie(name,value,days) {
  2.   if (days) {
  3.     var date = new Date();
  4.     date.setTime(date.getTime()+(days*24*60*60*1000));
  5.     var expires = "; expires="+date.toGMTString();
  6.   }
  7.   else expires = "";
  8.   document.cookie = name+"="+value+expires+"; path=/";
  9. }
  10.  
  11. function readCookie(name) {
  12.   var nameEQ = name + "=";
  13.   var ca = document.cookie.split(';');
  14.   for(var i=0;i < ca.length;i++) {
  15.     var c = ca&#91;i&#93;;
  16.     while (c.charAt(0)==' ') c = c.substring(1,c.length);
  17.     if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
  18.   }
  19.   return null;
  20. }
  21.  
  22. function language(lang_on, lang_off) {
  23.   createCookie("langue_on",lang_on,365);
  24.   createCookie("langue_off",lang_off,365);
  25.     for (var i=0; i<document.getElementsByTagName("div").length; i++ ) {
  26.       if (document.getElementsByTagName("div")&#91;i&#93;.lang == lang_on) {
  27.         document.getElementsByTagName("div")&#91;i&#93;.style.display="block";
  28.       }
  29.       if (document.getElementsByTagName("div")&#91;i&#93;.lang == lang_off) {
  30.         document.getElementsByTagName("div")&#91;i&#93;.style.display="none";
  31.       }
  32.     }
  33. }
  34.  
  35. function startlanguage() {
  36.   var notdefined;
  37.   var lang_on = readCookie("langue_on");
  38.   var lang_off = readCookie("langue_off");
  39.   if (lang_on == notdefined) {lang_on = "fr";}
  40.   if (lang_off == notdefined) {lang_off = "en";}
  41.   language(lang_on,lang_off);
  42. }
  43.  
  44. window.onload = function () {startlanguage();} &#91;/js&#93;
  45.  
  46. <h2>A few explanations</h2>
  47.  
  48. The first two functions, <strong>createCookie()</strong> and <strong>readCookie()</strong>, store cookies and read cookies so the user can set for once a preferred language. If you are already using a rather lengthy javascript file, chances are you already have cookie functions. In this case, no need to duplicate things, just modify the lines above to use your functions.
  49.  
  50. The next function, <strong>language()</strong>, is the core of the thingie. First, when called, it creates two cookies : one for language to display, one for language to hide. Then, it "loops" through all <em>div</em> elements of the pages, and toggle their display according to the parameters.
  51. (You're wondering, Why not a simpler function with just one parameter ? Well, first, I suck at javascript, and second, so it is simpler to extend the script to support three or more languages)
  52.  
  53. Next is <strong>startlanguage()</strong> : thanks to the last line, this function is called when the page loads, and its purpose is to set the language preferences : either there is cookies, or a default value is set (here, default is "display french and hide english")
  54.  
  55. <h2>Embed in your site</h2>
  56.  
  57. Add two links with the following code :
  58.  
  59. [js]<a href="javascript:language('fr','en')" title="Version Francaise">En Fran&ccedil;ais</a>
  60. <a href="javascript:language('en','fr')" title="English Version">In English</a>

And, for example, two divs :

  1. <div lang="en">Hello World !</div>
  2. <div lang="fr">Salut Poupoule !</div>

And that's it.

Use this in WordPress

To use this in WordPress, you simply have to write your posts with the div's. If XHTML validation is an important matter to you, you'll have to write a bit of HTML tags so that when WP automatically adds

and so on, you still validate. A validating example is following :

  1. <div lang="en"><p>Include an opening "p" tag in the first line from first paragraph.
  2.  
  3. Another line goes here. And as paragraphs as you want.
  4.  
  5. And don't forget to close the "p" it at the end.</p></div>
  6. <div lang="fr"><p>A la premiere ligne du premier paragraphe, incluez un tag "p".
  7.  
  8. Autant de lignes et de paragraphes que vous le souhaitez, bien s&ucirc;r.
  9.  
  10. Et avant de terminer la div, fermez le "p" que vous avez ouvert.</p></div>

The only real difficulty is that long posts become pretty huge when you type them twice to translate :)

Improvements ?

Instead of a simple default value for lang_on and lang_off, I think I'll add a language guess function. It could be guessed from referrer IP, or user's remote address, or maybe with browser's information, I still have to think a bit about this :)

You could also add loops to the main javascript function, so it will not toggle only div elements, but anything you'd need : p, img, span. Actually, working with span elements could be much more simple than with div's.

33 comments

  1. arya » construindo o wordpress

    […] ipertexto — site admin @ 2:37 pm este link ensina um hack para ter um site bi-lingual http://planetozh.com/blog//archives/2004/05/11/a-solution-for-a-bilingual-wordpress/ –> Comments […]

  2. Sidney’s Blog » Give respect where it’s due
  3. aletheia

    I have the same problem, but do you translate each post or just write in whatever language you feel like? Maybe I'm a bit lazzy, but I haven't been able to bring myself to translate each post I write.
    The only thing I see with your method is that you would be loading double each time. If posts are long, loading is longer. Good solution though!

  4. RaiL-FleX

    Yeah, that's true you have to load both languages but I still believe it's a good solution as you make your reader reload the posts (in the other language) if you use the method i described further up (and which is widely used). Then it's the same, but The Ozh's system is extremely pleasant and if you have a fast sql server (here it is the case … look at the benchmark at the bottom …) and a great internet connection, the "double-load" is almost transparent !

  5. Ozh

    Yes actually it loads both languages, but even on rather lengthy posts, say 5K for example, it's still a lot less than any .gif in this page, so load time is unseen

  6. Thunderbyrd

    I think you did a great job at tackling a problem that most people wouldn't have dreamed of taking on. Well done!

    Je pense que vous avez fait un grand travail à aborder un problème que la plupart des personnes wouldn't ont rêvé de la prise dessus. Puits fait !

  7. piou
  8. RaiL-FleX

    J'ai besoin de ton script pour mon site.
    C'est facile à mettre en place, et c'est rapide, mais j'ai trouvé un défaut: l'attribut lang de

    n'est plus valide avec xhtml 1.1 .
    J'ai essayé de modifier ton code js pour qu'il parse les attributs class et non plus lang, mais sans succès (je suis une vraie quiche en js).

    Une idée ? :)

  9. Ozh

    Pour utiliser "class" à la place de "lang" dans l'HTML, remplace dans le javascript "lang" par "className" (regarde l'exemple)

    Mais bon. Caisse t'as n'a fout' du XHTML 1.1 …

  10. RaiL-FleX

    Merci beaucoup Ozh, ça marche nickel !! :o)
    Je changeais 'lang' par 'class', ça ne pouvait pas marcher …
    Pourquoi XHTML 1.1 ? Parce que pour se la pét… enfin pour jouer à fond le jeu des validations w3c, autant le faire jusqu'au bout et respecter leur dernière norme (en attendant xhtml 2.0 :P).

  11. » Language switching for Basic Bilingual freshlabs

    […] efore you start Get the BasicBilingual plugin for WordPress. Make sure you have checked Ozh's solution for a bilingual WordPress which is also […]

  12. nathan

    bravo pour ce petit guide, je viens de l'installer chez moi sans aucun problème ! :-)

  13. Ozh

    Merci :)

  14. Petit

    Hi!
    Seems like a great idea. I was just googling for langauage and cookies, as I thought that would be the proper solution. However, for some reason I can't get your tiny flags to work either in firefox or MSIE.
    Strange!

  15. Petit

    Wow!
    Somthing else worked. You presented my flag.
    How did you do that?
    Deeply impressed :-)

  16. Ozh

    Petit » it works in both browsers. It's just that this page in english only :) Try the next post for a live example.
    As for guessing your country, it's a plugin for WordPress I wrote, IP to Nation.

  17. Daniel

    Hi, I really want to use your method, but I can´t get the javascript to validate! I´m trying to put your functions in my-hacks.php but I keep getting a parse error:

    Parse error: parse error, unexpected T_STRING, expecting ')' in … on line 13

  18. Ozh

    Daniel » my-hacks.php is for PHP. This is javascript.

  19. Triqui

    I managed to solve the problem of having WordPress in two (or more) languages in a rather new way, check it out if you think it can be useful
    http://www.emanueleferonato.com/2006/05/26/wordpress-in-two-or-more-languages/

  20. Rodrigo

    Hi,

    I didn't understand where to put "Embed in your site" section code… Can somebody tell me where I should put that portion of code?

    Thanks

  21. namakemono » Archiwum » DwujÄ™zyczny blog? Bilingual blog?

    […] RozwiÄ…zanie znalazÅ‚em bardzo szybko, a jego prostota byÅ‚a dla mnie na tyle wystarczajÄ…ca by nie szukać dalej. […]

  22. Urls Sinistras » Blog Archive » del.icio.us entre 23/10/2007 e 03/11/2007

    […] A Solution for a Bilingual WordPressThe ability to maintain a weblog in two (or more) languages is an often requested feature, especially by people like me who just can't make up their mind between French and English […]

  23. Mr Surbade

    "Instead of a simple default value for lang_on and lang_off, I think I'll add a language guess function. It could be guessed from referrer IP, or user's remote address, or maybe with browser's information, I still have to think a bit about this :)"

    I found this : http://erik.range-it.de/wordpress/plugins/getbrowserlanguage/

  24. Pup

    Genius! A lot of people having trouble with multi-lang-posting around the web and waiting for development of complex plugins. This simple solution worked sweet for me.

  25. Frank

    Very nice, but one drawback surely remains – the interface itself stays in the original language? Or is there any way to get all the headings, etc translated too?

  26. Ozh

    Frank » boy, that's a 5+ year old solution, when there were no translation plugins. There are much more advanced stuff now.

  27. nikolas

    Hello Ozh,

    I am a new wordpress user and I have a question (it may sound stupid). The two links and the two divs you mention in the section "Embed in your site" where do I embed them in each post?

    thanx

  28. Karibou

    Hey Ozh!
    thanks a million for this script! I spent all night trying to figure out how to switch between french and english on my blogger, so you saved the day!
    Twas so much better and easier than the other scripts I tried

  29. Karibou

    arg, juste un petit hic :
    quand je poste un message en bilingue sur mon blog, il apparait dans les deux langues l'une après l'autre, dès que je clique sur un de mes drapeaux le toggle prend le relais et c'est bien soit l'un soit l'autre…

    n'auriez vous pas une technique pour l'afficher par défaut en français?

  30. Ozh

    Karibou » c'est normalement activé par la dernière ligne du script ici (le windows.onload). C'est peut-etre a affiner en fonction d'autres scripts qui pourraient interagir

  31. tom

    this works perfect ! However: in a bilangual blog you will also need bilingual labels: did you by any chance develop a solution for this problem ?

  32. Ozh

    tom » No. This said, that solution is 8 year old now. Nowadays, there are WordPress plugins to do this, you should consider using modern techniques :)

Comments are closed.