====== Basic Multilanguage Support for local.php ====== With these lines of code, you can: * display the user interface in browsers favorite language * change the UI language depending on leading namespace * provide different start pages for every language * install it in 5 minutes and uninstall in 30 seconds. ===== Installation ===== To enable multilanguage support for your dokuwiki installation: - open the file **conf/local.php** (or conf/dokuwiki.php if you dont have local.php) - paste the following code at the end of the file and save - press reload in your browser! /* Multilanguage Support * Paste these lines at the end of your local.php and have a look if it works! * DokuWiki shall detect your user agents favorite language and switch interface language depending on leading namespace * Your (international) start page will still be 'start' by default, unless you create a page like en:start or de:start */ // Configuration $conf['lang_enabled'] = array(); //allowed languages (leave this array blank or comment out for auto-detection) // Autodetect all languages your dokuwiki installation supports $supportedLanguages = array(); if ($handle = opendir(DOKU_INC.'inc/lang')) { while (false !== ($file = readdir($handle))) { if (is_dir(DOKU_INC.'inc/lang/'.$file)) array_push($supportedLanguages,$file); } closedir($handle); } if (!isset($conf['lang_enabled'])) $conf['lang_enabled'] = array(); if (count($conf['lang_enabled'])==0) $conf['lang_enabled'] = $supportedLanguages; // Set default language to the user agents most favorite one $languages = split(',', preg_replace('/(;q=\d+.\d+)/i', '', getenv('HTTP_ACCEPT_LANGUAGE'))); foreach ($languages as $lang) if (in_array($lang, $conf['lang_enabled'])) { $conf['lang'] = $lang; break; } // Check, if language is set by namespace and overwrite choosed language $lang = preg_replace('/^(..+)[:\/].*/i','$1',$_REQUEST['id']); if (!in_array($lang, $conf['lang_enabled'])) $lang = preg_replace('/^(..+)[:\/].*/i','$1',$_REQUEST['ns']); if (in_array($lang, $conf['lang_enabled'])) $conf['lang'] = $lang; // prepend default start page with language namespace, if this page already exists. if (file_exists($conf['savedir'].'/pages/'.str_replace(':','/',$conf['lang'].':'.$conf['start']).'.txt')) $conf['start'] = $conf['lang'].':'.$conf['start']; ===== Testing ===== Test your new multilanguage features: * lets say your dokuwiki is located at http://mydokuwiki.org/, and your default start page is 'start', ok? * open http://mydokuwiki.org/ -> your start page appears and the user interface is in the language, your browser likes most. * open a page like de:test or fr:test -> the user interface is in german or french * create a localized start page like de:start (try it with the tested browser language in 1.), open http://mydokuwiki.org/ again -> your localized start page with localized UI appears * press the login button -> localized UI appears as well. ===== Release Notes ===== The following lines of code are compatible to PHP4+ and any dokuwiki, that configures $conf['lang'], $conf['savedir'] and $conf['start'] and defines DOKU_INC. I think this is valid for at least 2006-03-09 and every later release. (give some feedback) ===== Discussion ===== Please leave your comments here. Thank you for try out! --- //[[jv525052@inf.tu-dresden.de|Johannes Vockeroth]] 2006-07-01 20:41// Your code does not work with the current revision of DokuWiki: << the prepend default start page with language >> trick expands an internal link like [[project:]] to id=project2:fr:start (where fr is my preferred language in my browser). --- //[[gb@isis.u-strasbg.fr|Guy Brand]] 2006-08-27 23:40// Use [[project:start]] or [[fr:project:start]] and this work fine. --- Patrick ---- Really nice, seems to work well. Just one question, you have on your webpage links to the same page in another language. How did you achieve this? --- [[loco@tag-am-meer.info|Dirk `el loco´ Haage]] ---- Hello, I based my website http://www.pxxo.net on dokuwiki with your multilanguale patch but I extended it a bit in order to : - add a lang switcher (clickable flags buttons) - keep trace of the choosen language : adapte the menu links to the current choosed language In my local.php : // Configuration $conf['lang_enabled'] = array(); //allowed languages (leave this array blank or comment out for auto-detection) // Autodetect all languages your dokuwiki installation supports $supportedLanguages = array(); if ($handle = opendir(DOKU_INC.'inc/lang')) { while (false !== ($file = readdir($handle))) { if (is_dir(DOKU_INC.'inc/lang/'.$file)) array_push($supportedLanguages,$file); } closedir($handle); } if (!isset($conf['lang_enabled'])) $conf['lang_enabled'] = array(); if (count($conf['lang_enabled'])==0) $conf['lang_enabled'] = $supportedLanguages; // Set default language to the user agents most favorite one $languages = split(',', preg_replace('/(;q=\d+.\d+)/i', '', getenv('HTTP_ACCEPT_LANGUAGE'))); foreach ($languages as $lang) if (in_array($lang, $conf['lang_enabled'])) { $conf['lang'] = $lang; break; } // Check, if language is set by namespace and overwrite choosed language $lang = preg_replace('/^(.[^:\/]+)[:\/].*/i','$1',$_REQUEST['id']); if (!in_array($lang, $conf['lang_enabled'])) $lang = preg_replace('/^(.[^:\/]+)[:\/].*/i','$1',$_REQUEST['ns']); if (in_array($lang, $conf['lang_enabled'])) $conf['lang'] = $lang; // prepend default start page with language namespace, if this page already exists. if (file_exists($conf['savedir'].'/pages/'.str_replace(':','/',$conf['lang'].'.txt'))) $conf['start'] = $conf['lang']; function tpl_youarehere2() { ob_start(); tpl_youarehere(); $data = ob_get_contents(); ob_end_clean(); $data = str_replace('href="/en"','href="/"',$data); echo $data; } in main.php template file I replaced the tpl_youarehere() by tpl_youarehere2() and I added the langswitcher.php section which allows to dynamicaly change the language by clicking on the flags : [...] [...]
[...]

[...]
in langswitcher.php :
  • '); } ?>
  • '); } ?>
  • in menu.php :
  • in my ''images/lang/'' directory I added these two images : {{http://www.pxxo.net/lib/tpl/pxxo/images/lang/en.png}} {{http://www.pxxo.net/lib/tpl/pxxo/images/lang/fr.png}} Hope this will help someone. best regards, [[http://www.zeitoun.net|Stéphane Gully]] ---- I think the regular expression in the original script should be ''%%'/^(..+?)[:\/].*/i%%'' (with question sign after the plus) in order to match ungreedy. This is important for deep namespace hierarchies. --- //[[wikidesign@gmail.com|Esther Brunner]] 2006-11-21 19:17// ----- :?: Is there any possibility Stéphane Gully's excellent work could be merged with [[tips:nls|Cha ReeSeo's work on nls]]? I asked this in [[http://forum.dokuwiki.org/post/1500|the dokuwiki forum]]. --- //[[tito.vergara@gmail.com|Tito Vergara]] 2006-12-01 15:50//FIXME ---- Great !!! :!: local.php get wiped every time changes are made via the admin control panel.:?:Is that normal? //--jack// > Yes, but you should find a **@include(DOKU_CONF.'local.protected.php');** line in **local.php**, so you can put handmade changes in your **local.protected.php** file. Don't know if this would work here though.--- //[[christophegragnic@yahoo.fr|Grahack]] 2008/04/25 13:54// ---- The ''local.protected.php'' works fine. Mine looks like this (I combined several tips from this page): $lang) $supportedLanguages[$idx] = basename($lang); if (!isset($conf['lang_enabled']) || count($conf['lang_enabled'])==0) $conf['lang_enabled'] = $supportedLanguages; if (!in_array($conf['lang_default'], $conf['lang_enabled'])) $conf['lang_default'] = reset($conf['lang_enabled']); // make sure, default lang is valid // Set default language to the user agent's most favorite one $languages = split(',', preg_replace('/(;q=\d+.\d+)/i', '', getenv('HTTP_ACCEPT_LANGUAGE'))); foreach ($languages as $lang) if (in_array($lang, $conf['lang_enabled'])) { $conf['lang'] = $lang; break; } // Check, if language is set by namespace and overwrite chosen language $lang = preg_replace('/^(..+?)[:\/].*/i','$1',$_REQUEST['id']); if (!in_array($lang, $conf['lang_enabled'])) $lang = preg_replace('/^(..+?)[:\/].*/i','$1',$_REQUEST['ns']); if (in_array($lang, $conf['lang_enabled'])) $conf['lang'] = $lang; // prepend default start page with language namespace, if this page already exists. // if (file_exists($conf['savedir'].'/pages/'.str_replace(':','/',$conf['lang'].':'.$conf['start']).'.txt')) $conf['start'] = $conf['lang'].':'.$conf['start']; function tpl_youarehere2() { global $conf; ob_start(); tpl_youarehere(); $data = ob_get_contents(); ob_end_clean(); $data = str_replace('href="' . DOKU_BASE . $conf['lang_default'] . '/', 'href="' . DOKU_BASE, $data); $data = str_replace('title="' . $conf['lang_default'] . ':', 'title="', $data); $prefixpos = strpos($data, '>'.$conf['lang'].''); if ($prefixpos !== false) { // find start of anchor (strrpos() only works for single characters, not strings) $prefixstart = -1; do { $prefixstart = strpos($data, ' 0 && $prefixend > 0) $data = substr($data, 0, $prefixstart) . substr($data, $prefixend); } echo $data; } function tpl_flagimg($lang) { // translate language-code to country-code (where the lang is mostly spoken/written) switch ($lang) { case 'da': $lang = 'dk'; break; // Danish -> Denmark case 'el': $lang = 'gr'; break; // Greek -> Greece case 'en': $lang = 'en-all'; break; // English -> combined GB/US flag case 'he': $lang = 'il'; break; // Hebrew -> Israel case 'ja': $lang = 'jp'; break; // Japanese -> Japan case 'ko': $lang = 'kr'; break; // Korean -> Korea case 'ku': $lang = 'iq'; break; // Kurdish -> Iraq case 'pt-br': $lang = 'br'; break; // Braz. Portuguese -> Brazil case 'uk': $lang = 'ua'; break; // Ukrainian -> Ukraine case 'zh': $lang = 'cn'; break; // Simpl. Chinese -> China case 'zh-tw': $lang = 'tw'; break; // Trad. Chinese -> Taiwan default: break; } $img = DOKU_BASE . 'lib/images/flags/' . $lang . '.gif'; return $img; } // assumes Flag icons (.gif) from http://www.famfamfam.com/lab/icons/flags/ in /lib/images/flags (rename us.gif or gb.gif to en-all.gif) function tpl_langswitcher() { global $ID, $conf; echo PHP_EOL . '
    '; echo ''; echo '
      '; foreach ($conf['lang_enabled'] as $lang) { $thislang = ($conf['lang']==$lang); $newID = (($lang!=$conf['lang_default'])?$lang.':':'') . (($ID{2}==':')?substr($ID, 3):$ID); // TODO: check existance of file $img = '' . hsc($lang) . ''; echo '
    • '; if (!$thislang) tpl_link(wl($newID), $img); else echo $img; echo '
    • '; } echo '
    '; echo '
    ' . PHP_EOL; } ?>
    The flags are from [[http://www.famfamfam.com/lab/icons/flags/|FamFamFam]]. To show the flags, add to main.php: '''' where you want it to be (right after the //Old revisions//-button is a perfectly place!). Also change ''tpl_youarehere()'' to ''tpl_youarehere2()''. Clicking a flag shows the page in the clicked language. You can easily make it only show flags for languages where there are translations. I had to comment out the ''$conf['start']'' override because it borked something in cache so that indexmenu was unsure which start-item to show. But using the sidebar-layout with indexmenu in the sidebar, you can easily add a specific sidebar for each language which only shows the localized tree (i.e. everything below that namespace). Would be nice if there were hooks to make such things as a real plugin, though. --- //[[mbirth@webwriters.de|Markus Birth]] 2008-07-16 20:05// I've made change in orginal script by removing regex and using explode since it's safe and less CPU hungry and because it catch pl:something:somethin:something right :) Trick with: @include(DOKU_CONF.'local.protected.php'); doesn't work anymore. I just saved code as **lang.php** in **/conf**, added include in **local.php** and made it read only... This solution has one problem. I't disables admin settings pannel, but auth and rest are fine. If i need to modify something I do it manually or by backing up **local.php** --- //[[dr4cul4@o2.pl|dr4cul4]] 2009-05-07 00:25// In order for ''local.protected.php'' to work again you can edit the ''lib/plugins/config/settings/config.class.php'' file: Add the line $out .= "\n@include(DOKU_CONF.'local.protected.php');\n"; just before the line $out .= "\n// end auto-generated content\n"; of ''function _out_footer()'' Now, every time you change your configuration via the admin panel, the include line will be automatically added to ''local.php''