{"id":39,"date":"2004-05-11T20:49:16","date_gmt":"2004-05-11T18:49:16","guid":{"rendered":"http:\/\/frenchfragfactory.net\/ozh\/archives\/2004\/05\/11\/a-solution-for-a-bilingual-wordpress\/"},"modified":"2007-04-20T19:42:26","modified_gmt":"2007-04-20T17:42:26","slug":"a-solution-for-a-bilingual-wordpress","status":"publish","type":"post","link":"https:\/\/planetozh.com\/blog\/2004\/05\/a-solution-for-a-bilingual-wordpress\/","title":{"rendered":"A Solution for a Bilingual WordPress"},"content":{"rendered":"<p><img decoding=\"async\" class=\"imgleft\" src=\"\/blog\/images\/two_flags.gif\" alt=\"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&#39;t make up their mind between French and English :)<br \/>\nI&#39;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&#39;ve also added cookie support, so you just need to chose a language once. This may not be *the* perfect solution, it&#39;s just one way, and a very simple one to add in an existing site.<\/p>\n<p><!--more--><br \/>\nThe trick : you have two <strong>div&#39;s<\/strong>, one with attribute <strong>&quot;lang=fr&quot;<\/strong>, one with <strong>&quot;lang=en&quot;<\/strong>. A small javascript hides every divs with a particular &quot;lang&quot; and shows the others.<\/p>\n<h2>The javascript part<\/h2>\n<p>First, put the following code in your index.php, or in an external javascript file :<\/p>\n<div class=\"igsh-code-box\" id=\"ig-sh-1\"><pre class=\"language-javascript line-numbers\" data-no-optimize=\"1\" data-cfasync=\"false\"><code class=\"language-javascript\">function createCookie(name,value,days) {\r\n  if (days) {\r\n    var date = new Date();\r\n    date.setTime(date.getTime()+(days*24*60*60*1000));\r\n    var expires = &quot;; expires=&quot;+date.toGMTString();\r\n  }\r\n  else expires = &quot;&quot;;\r\n  document.cookie = name+&quot;=&quot;+value+expires+&quot;; path=\/&quot;;\r\n}\r\n\r\nfunction readCookie(name) {\r\n  var nameEQ = name + &quot;=&quot;;\r\n  var ca = document.cookie.split(&#039;;&#039;);\r\n  for(var i=0;i &lt; ca.length;i++) {\r\n    var c = ca[i];\r\n    while (c.charAt(0)==&#039; &#039;) c = c.substring(1,c.length);\r\n    if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);\r\n  }\r\n  return null;\r\n}\r\n\r\nfunction language(lang_on, lang_off) {\r\n  createCookie(&quot;langue_on&quot;,lang_on,365);\r\n  createCookie(&quot;langue_off&quot;,lang_off,365);\r\n    for (var i=0; i&lt;document.getElementsByTagName(&quot;div&quot;).length; i++ ) {\r\n      if (document.getElementsByTagName(&quot;div&quot;)[i].lang == lang_on) {\r\n        document.getElementsByTagName(&quot;div&quot;)[i].style.display=&quot;block&quot;;\r\n      }\r\n      if (document.getElementsByTagName(&quot;div&quot;)[i].lang == lang_off) {\r\n        document.getElementsByTagName(&quot;div&quot;)[i].style.display=&quot;none&quot;;\r\n      }\r\n    }\r\n}\r\n\r\nfunction startlanguage() {\r\n  var notdefined;\r\n  var lang_on = readCookie(&quot;langue_on&quot;);\r\n  var lang_off = readCookie(&quot;langue_off&quot;);\r\n  if (lang_on == notdefined) {lang_on = &quot;fr&quot;;}\r\n  if (lang_off == notdefined) {lang_off = &quot;en&quot;;}\r\n  language(lang_on,lang_off);\r\n}\r\n\r\nwindow.onload = function () {startlanguage();}<\/code><\/pre><\/div>\n<h2>A few explanations<\/h2>\n<p>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.<\/p>\n<p>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 &quot;loops&quot; through all <em>div<\/em> elements of the pages, and toggle their display according to the parameters.<br \/>\n(You&#39;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)<\/p>\n<p>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 &quot;display french and hide english&quot;)<\/p>\n<h2>Embed in your site<\/h2>\n<p>Add two links with the following code :<\/p>\n<div class=\"igsh-code-box\" id=\"ig-sh-2\"><pre class=\"language-javascript line-numbers\" data-no-optimize=\"1\" data-cfasync=\"false\"><code class=\"language-javascript\">&lt;a href=&quot;javascript:language(&#039;fr&#039;,&#039;en&#039;)&quot; title=&quot;Version Francaise&quot;&gt;En Fran&amp;ccedil;ais&lt;\/a&gt;\r\n&lt;a href=&quot;javascript:language(&#039;en&#039;,&#039;fr&#039;)&quot; title=&quot;English Version&quot;&gt;In English&lt;\/a&gt;<\/code><\/pre><\/div>\n<p>And, for example, two divs :<\/p>\n<div class=\"igsh-code-box\" id=\"ig-sh-3\"><pre class=\"language-markup line-numbers\" data-no-optimize=\"1\" data-cfasync=\"false\"><code class=\"language-markup\">&lt;div lang=&quot;en&quot;&gt;Hello World !&lt;\/div&gt;\r\n&lt;div lang=&quot;fr&quot;&gt;Salut Poupoule !&lt;\/div&gt;<\/code><\/pre><\/div>\n<p>And that&#39;s it.<\/p>\n<h2>Use this in WordPress<\/h2>\n<p>To use this in WordPress, you simply have to write your posts with the div&#39;s. If XHTML validation is an important matter to you, you&#39;ll have to write a bit of HTML tags so that when WP automatically adds <em><\/p>\n<p><\/em> and so on, you still validate. A validating example is following :<\/p>\n<div class=\"igsh-code-box\" id=\"ig-sh-4\"><pre class=\"language-markup line-numbers\" data-no-optimize=\"1\" data-cfasync=\"false\"><code class=\"language-markup\">&lt;div lang=&quot;en&quot;&gt;&lt;p&gt;Include an opening &quot;p&quot; tag in the first line from first paragraph. \r\n\r\nAnother line goes here. And as paragraphs as you want.\r\n\r\nAnd don&#039;t forget to close the &quot;p&quot; it at the end.&lt;\/p&gt;&lt;\/div&gt;\r\n&lt;div lang=&quot;fr&quot;&gt;&lt;p&gt;A la premiere ligne du premier paragraphe, incluez un tag &quot;p&quot;.\r\n\r\nAutant de lignes et de paragraphes que vous le souhaitez, bien s&amp;ucirc;r.\r\n\r\nEt avant de terminer la div, fermez le &quot;p&quot; que vous avez ouvert.&lt;\/p&gt;&lt;\/div&gt;<\/code><\/pre><\/div>\n<p>The only real difficulty is that long posts become pretty huge when you type them twice to translate :)<\/p>\n<h2>Improvements ?<\/h2>\n<p>Instead of a simple default value for <em>lang_on <\/em>and <em>lang_off<\/em>, I think I&#39;ll add a language guess function. It could be guessed from referrer IP, or user&#39;s remote address, or maybe with browser&#39;s information, I still have to think a bit about this :)<\/p>\n<p>You could also add loops to the main javascript function, so it will not toggle only <em>div<\/em> elements, but anything you&#39;d need : p, img, span. Actually, working with <em>span <\/em>elements could be much more simple than with div&#39;s. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>A simple way to have a bilingual blog<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[2,7,10,85,11,245],"class_list":["post-39","post","type-post","status-publish","format-standard","hentry","tag-code","tag-javascript","tag-php","tag-plugins","tag-web","tag-wordpress"],"_links":{"self":[{"href":"https:\/\/planetozh.com\/blog\/wp-json\/wp\/v2\/posts\/39","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/planetozh.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/planetozh.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/planetozh.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/planetozh.com\/blog\/wp-json\/wp\/v2\/comments?post=39"}],"version-history":[{"count":0,"href":"https:\/\/planetozh.com\/blog\/wp-json\/wp\/v2\/posts\/39\/revisions"}],"wp:attachment":[{"href":"https:\/\/planetozh.com\/blog\/wp-json\/wp\/v2\/media?parent=39"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/planetozh.com\/blog\/wp-json\/wp\/v2\/categories?post=39"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/planetozh.com\/blog\/wp-json\/wp\/v2\/tags?post=39"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}