tips:nls
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
wiki:tips:nls [2007-06-25 19:04] – mfh | tips:nls [2013-01-12 01:39] (current) – [(Unofficial) National Language Support (NLS)] Klap-in | ||
---|---|---|---|
Line 1: | Line 1: | ||
+ | ====== (Unofficial) National Language Support (NLS) ====== | ||
+ | The current version is **2005-09-22e-1.1.0**. | ||
+ | * [[http:// | ||
+ | * working examples, and | ||
+ | * the latest update (if any) | ||
+ | of this technique in [[http:// | ||
+ | Please discuss here if you have any comment. | ||
+ | |||
+ | ---- | ||
+ | |||
+ | The National Language Support (NLS) feature introduced in this document | ||
+ | is not a built-in functionality nor an official plugin of DokuWiki, | ||
+ | but an unofficial patch applied to the 2005-09-22e version. | ||
+ | A future version of DokuWiki may officially ship another NLS feature | ||
+ | which is irrelevant to one described in this document. | ||
+ | Please look for plugins or consult [[tips: | ||
+ | for more information about NLS in DokuWiki. | ||
+ | |||
+ | |||
+ | ===== Suitable Situation ===== | ||
+ | |||
+ | The technique introduced in this document is suitable for situations such that: | ||
+ | |||
+ | * You cannot add or change the domain name and host name of your web site arbitrarilly. | ||
+ | * You want to operate only one installation of DokuWiki because of convenience of the user management and so on. In other word, you don't want to operate two or more DokuWiki installations according to the languages of UI's or translations. | ||
+ | * Each document in your site will be translated into various languages, where the set of translation languages need not be the same for every document. | ||
+ | |||
+ | ===== Features (as visitors) ===== | ||
+ | |||
+ | The technique in this page works as follows: | ||
+ | |||
+ | * Readers visiting your web site can freely choose any existing translations for the documents they read. If they don't specify any language explicitly, they will be redirected to appropriate translations according to the language settings of their web browsers. | ||
+ | * User Interface (UI) language is decided only by the language setting of the reader' | ||
+ | * The documents translated in different languages have different URL's, and readers can move from one translation to another not by submitting forms but via simple links. | ||
+ | |||
+ | ===== Prerequisites (as administrators and users) ===== | ||
+ | |||
+ | In order to use the technique introduced in this document, | ||
+ | the following conditions are required: | ||
+ | in a future version (1.2.x or above) of this technique.)) | ||
+ | |||
+ | * DokuWiki version 2005-09-22e is needed. | ||
+ | * For ALL documents in the wiki site to which this technique is about to be applied, the ' | ||
+ | |||
+ | The ' | ||
+ | which denotes in what language it is translated. | ||
+ | When //pageID// is the valid ID format (including namespaces) permitted by DokuWiki, | ||
+ | the new page ID with a translation flag should be | ||
+ | |||
+ | // | ||
+ | |||
+ | in regular expression. | ||
+ | For example, '' | ||
+ | for the same content. | ||
+ | |||
+ | Because the page ID '' | ||
+ | readers will be redirected to an appropriate translation pages according to their browser setting | ||
+ | if they query this kind of page. | ||
+ | Though they will be redirected basically to the most appropriate one | ||
+ | among existing translations as far as possible, | ||
+ | they will be redirected to a non-existing page if no existing translation matches to their browser' | ||
+ | In other words, readers will not be able to read '' | ||
+ | therefore the site administrator should append translation flags to all the pages in his/her site | ||
+ | before using this technique. | ||
+ | |||
+ | A method I used and recommend for appending translation flags to pre-existings page is: | ||
+ | |||
+ | - Check in what language a pre-existing page '' | ||
+ | - Create a new page '' | ||
+ | - Modify links ID's of all the internal links in the copied content appropiately. | ||
+ | - Delete '' | ||
+ | |||
+ | This procedure, of course, is very tedious, but I don't know better way to change page ID's in DokuWiki. | ||
+ | |||
+ | |||
+ | ===== Algorithm (as developers) ===== | ||
+ | |||
+ | The algorithm is very simple: | ||
+ | |||
+ | - A reader query a page. | ||
+ | - If the queried page has no translation flag (e.g. '' | ||
+ | - Extract languages from the browser setting and sort them by their priority. | ||
+ | - If one of these language (e.g. '' | ||
+ | - If none matches, redirect him/her to the default translation page configured by the administrator (e.g. '' | ||
+ | - If the queried page has a translation flag, show it to the reader. | ||
+ | - Aumatically choose an appropriate language for UI by comparing browser settings and '' | ||
+ | - Overwrite chosen language for UI on '' | ||
+ | - Reset locale. | ||
+ | - Provide API in order for administrators to be able to add a menu (choosing other translations) to their template. | ||
+ | |||
+ | That's all. :-) | ||
+ | |||
+ | ===== Code and Usage ===== | ||
+ | |||
+ | Please remind again that you should append translation flags to all the page ID's before using this. | ||
+ | |||
+ | ==== Creating inc/NLS.php File ==== | ||
+ | |||
+ | Create '' | ||
+ | (Administrators can modify two arrays '' | ||
+ | |||
+ | <code php> | ||
+ | <?php | ||
+ | /** | ||
+ | * National Language Support (NLS) script for DokuWiki | ||
+ | * | ||
+ | * @version | ||
+ | * @license | ||
+ | * @author | ||
+ | * | ||
+ | * Usage: | ||
+ | | ||
+ | | ||
+ | * | ||
+ | * CAUTION: | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | * | ||
+ | | ||
+ | | ||
+ | | ||
+ | * | ||
+ | | ||
+ | * | ||
+ | * To do: | ||
+ | | ||
+ | */ | ||
+ | |||
+ | |||
+ | /* --------------------------------------------------------------- | ||
+ | * Configuration options: You can modify or add something to these */ | ||
+ | |||
+ | $NLS_locarr[' | ||
+ | $NLS_locarr[' | ||
+ | |||
+ | $NLS_langname[' | ||
+ | $NLS_langname[' | ||
+ | |||
+ | /* Configuration options end | ||
+ | * --------------------------------------------------------------- */ | ||
+ | |||
+ | |||
+ | |||
+ | // Setting $ID | ||
+ | $ID = getID(); | ||
+ | |||
+ | // Redirecting if no language is specified at the end of $ID | ||
+ | if (! NLS_pagelang($ID)) { | ||
+ | $target = NLS_page4browser($ID); | ||
+ | if (! array_key_exists(" | ||
+ | header(' | ||
+ | } | ||
+ | |||
+ | // Resetting $conf[' | ||
+ | $conf[' | ||
+ | // Resetting $lang array | ||
+ | @require_once(DOKU_INC.' | ||
+ | // Resetting locale | ||
+ | setlocale(LC_ALL, | ||
+ | |||
+ | |||
+ | /** | ||
+ | * Getting locale string | ||
+ | * | ||
+ | * FIXME: What a poor function this is! | ||
+ | */ | ||
+ | function NLS_locale($ln = NULL) { | ||
+ | global $conf; | ||
+ | global $lang; | ||
+ | global $NLS_locarr; | ||
+ | if (! $ln) $ln = $conf[' | ||
+ | $loc = array_key_exists($ln, | ||
+ | $loc .= ' | ||
+ | $loc .= array_key_exists(' | ||
+ | return $loc; | ||
+ | } | ||
+ | |||
+ | |||
+ | /** | ||
+ | * Printing links to other translations of the given page | ||
+ | * (API for template files such as DOKU_TPL/ | ||
+ | */ | ||
+ | function NLS_transmenu($pid = NULL, $delimiter = ", | ||
+ | global $NLS_langname; | ||
+ | if (! $pid) { | ||
+ | global $ID; | ||
+ | $pid = $ID; | ||
+ | } | ||
+ | $currplang = NLS_pagelang($pid); | ||
+ | $tpages = NLS_transpages($pid); | ||
+ | if ($currplang && ! $withself) | ||
+ | unset($tpages[$currplang]); | ||
+ | if ($tpages) { | ||
+ | $first = TRUE; | ||
+ | foreach ($tpages as $ln => $tid) { | ||
+ | $repr = array_key_exists($ln, | ||
+ | if (! $first) | ||
+ | echo $delimiter; | ||
+ | $first = FALSE; | ||
+ | if ($currplang == $ln) | ||
+ | echo "< | ||
+ | else | ||
+ | echo "<a href=\"" | ||
+ | } | ||
+ | } else { | ||
+ | echo " | ||
+ | } | ||
+ | } | ||
+ | |||
+ | |||
+ | |||
+ | /** | ||
+ | * Selecting a redirection target (page) which best match the browser setting | ||
+ | * | ||
+ | * Default: page of $conf[' | ||
+ | * Choice : among existing translations, | ||
+ | */ | ||
+ | function NLS_page4browser($pid = NULL) { | ||
+ | if (! $pid) { | ||
+ | global $ID; | ||
+ | $pid = $ID; | ||
+ | } | ||
+ | $blang = NLS_browserlang(); | ||
+ | $existing_pages = NLS_transpages($pid); | ||
+ | $pid_base = NLS_ID_base($pid); | ||
+ | $tmp_page = $pid_base . ' | ||
+ | foreach ($blang as $lang_str => $priority) { | ||
+ | $lang_str = str_replace(" | ||
+ | if (array_key_exists($lang_str, | ||
+ | $tmp_page = $pid_base . ' | ||
+ | elseif (array_key_exists(substr($lang_str, | ||
+ | $tmp_page = $pid_base . ' | ||
+ | } | ||
+ | return $tmp_page; | ||
+ | } | ||
+ | |||
+ | |||
+ | /** | ||
+ | * Selecting a language for UI | ||
+ | * | ||
+ | * Default: $conf[' | ||
+ | * Choice : among existing ' | ||
+ | */ | ||
+ | function NLS_UI4browser() { | ||
+ | global $conf; | ||
+ | $tmp_lang = $conf[' | ||
+ | $blang = NLS_browserlang(); | ||
+ | foreach ($blang as $lang_str => $priority) { | ||
+ | $lang_str = str_replace(" | ||
+ | if (is_dir(DOKU_INC . " | ||
+ | $tmp_lang = $lang_str; | ||
+ | elseif (is_dir(DOKU_INC . " | ||
+ | $tmp_lang = substr($lang_str, | ||
+ | } | ||
+ | return $tmp_lang; | ||
+ | } | ||
+ | |||
+ | |||
+ | /** | ||
+ | * Getting a sorted (by priority) array of the languages | ||
+ | * from the language setting of the user's web browser | ||
+ | */ | ||
+ | function NLS_browserlang() { | ||
+ | $acclang_arr = split(" | ||
+ | foreach ($acclang_arr as $acclang) { | ||
+ | if (ereg(" | ||
+ | $acclang_sorted[$acclang_parts[1]] = (double)($acclang_parts[2]); | ||
+ | else | ||
+ | $acclang_sorted[$acclang] = 1.0; | ||
+ | } | ||
+ | asort($acclang_sorted, | ||
+ | reset($acclang_sorted); | ||
+ | return $acclang_sorted; | ||
+ | } | ||
+ | |||
+ | |||
+ | /** | ||
+ | * Getting an associative array (lang => ID) of | ||
+ | * all the translated pages for the given page | ||
+ | */ | ||
+ | function NLS_transpages($pid = NULL) { | ||
+ | global $conf; | ||
+ | if (! $pid) { | ||
+ | global $ID; | ||
+ | $pid = $ID; | ||
+ | } | ||
+ | $transpages = array(); | ||
+ | $pid_base_path = $conf[' | ||
+ | foreach(glob($pid_base_path . " | ||
+ | $aid = str_replace("/", | ||
+ | if ($alang = NLS_pagelang($aid)) { | ||
+ | $transpages[$alang] = $aid; | ||
+ | } | ||
+ | } | ||
+ | return $transpages; | ||
+ | } | ||
+ | |||
+ | |||
+ | /** | ||
+ | * Drop language notation (.xx or .xx-xx) from the given ID | ||
+ | */ | ||
+ | function NLS_ID_base($pid = NULL) { | ||
+ | if (! $pid) { | ||
+ | global $ID; | ||
+ | $pid = $ID; | ||
+ | } | ||
+ | if (substr($pid, | ||
+ | return substr($pid, | ||
+ | elseif (substr($pid, | ||
+ | return substr($pid, | ||
+ | else | ||
+ | return $pid; | ||
+ | } | ||
+ | |||
+ | |||
+ | /** | ||
+ | * Get language (xx, xx-xx, or NULL) from the given ID | ||
+ | */ | ||
+ | function NLS_pagelang($pid = NULL) { | ||
+ | if (! $pid) { | ||
+ | global $ID; | ||
+ | $pid = $ID; | ||
+ | } | ||
+ | if (substr($pid, | ||
+ | return substr($pid, | ||
+ | elseif (substr($pid, | ||
+ | return substr($pid, | ||
+ | else | ||
+ | return NULL; | ||
+ | } | ||
+ | ?> | ||
+ | </ | ||
+ | |||
+ | ==== Modifying doku.php File ==== | ||
+ | |||
+ | Now, let's add an inclusion of '' | ||
+ | **The location of this inclusion is very important!** | ||
+ | Though NLS script should be loaded as early as possible, | ||
+ | it should be placed after '' | ||
+ | Please insert the line of inclusion just after including '' | ||
+ | (This code shows only the first few lines): | ||
+ | |||
+ | <code php> | ||
+ | <?php | ||
+ | /** | ||
+ | * DokuWiki mainscript | ||
+ | * | ||
+ | * @license | ||
+ | * @author | ||
+ | */ | ||
+ | |||
+ | // xdebug_start_profiling(); | ||
+ | |||
+ | if(!defined(' | ||
+ | require_once(DOKU_INC.' | ||
+ | require_once(DOKU_INC.' | ||
+ | require_once(DOKU_INC.' | ||
+ | require_once(DOKU_INC.' | ||
+ | require_once(DOKU_INC.' | ||
+ | require_once(DOKU_INC.' | ||
+ | require_once(DOKU_INC.' | ||
+ | |||
+ | //import variables | ||
+ | ... | ||
+ | </ | ||
+ | |||
+ | ==== Adding Menu (for Selecting Translations) to the Template ==== | ||
+ | |||
+ | For the last, let's add a menu for selecting translations to the template | ||
+ | in order for the readers to choose another translations of current page. | ||
+ | Just insert the following code into the '' | ||
+ | |||
+ | <code php> | ||
+ | Other translations of this page: <?php NLS_transmenu(); | ||
+ | </ | ||
+ | |||
+ | '' | ||
+ | and defines following parameters: | ||
+ | |||
+ | '' | ||
+ | |||
+ | Each parameter is: | ||
+ | |||
+ | * string ''// | ||
+ | * string ''// | ||
+ | * boolean ''// | ||
+ | |||
+ | ===== To do ===== | ||
+ | |||
+ | * As written in the code above as a comment, '' | ||
+ | |||
+ | ===== Discussion ===== | ||
+ | I like this concept. In reading through the dokuwiki site I see that namespaces are/can also be used. For reference please check [[multilingual_content]] and also [[multilingual_content: | ||
+ | |||
+ | I would love to see these two approaches merged... | ||
+ | |||
+ | * The automatic creation of mirror documents in the first language in the alternate languages with a to be translated tag - as you suggest in this article. | ||
+ | |||
+ | * The link between the documents is automatic (as in your site) and just clicking on a language will show the translated doc in the right place - or show that it has not yet been done...as in both of your approaches. | ||
+ | |||
+ | My main concern is the document naming convention. You suggest to add the language code at the end of your page name **foo: | ||
+ | |||
+ | :?: What are the pro's and con's of these two approaches? | ||
+ | |||
+ | ---- | ||
+ | |||
+ | I like the present approach better than the multilang. content which adds the " | ||
+ | |||
+ | OTOH, I'd like it to be even more discrete and at the same time " | ||
+ | * get $LANG from REQUEST or SESSION (see below) | ||
+ | * if foo:bar is requested, check if foo: | ||
+ | There are several advantages of the URLs not containing the .LANG : esthetical, portability, | ||
+ | |||
+ | Setting the $LANG (SESSION or COOKIE or GET) would be done | ||
+ | * from GET (i.e. if "& | ||
+ | * if avail, from the last click on a "lang. flag" or similar explicit choice | ||
+ | * from browser setting | ||
+ | * site default (questionable if this should set the LANG or leave it empty, which might be not equivalent) | ||
+ | --- //MFH, 25.6.07// |
tips/nls.txt · Last modified: 2013-01-12 01:39 by Klap-in