계정: 로그인
AA 📝
Previous Releases: version 1.0

(!) 이 문서는 한국어판도 있습니다.

Assumptions for the Requirements

The techniques described in this document can be used when there are requirements as follows:

Basic Ideas

Basic idea is very simple. I'll assume one thing for the convenience: administrator wants to manage only two languages, Korean (ko) and English (en).

Simple, huh? :-)

Codes

Create a file named inc/NLS.php. The code below is a inc/NLS.php I wrote, but you can change the list of languages and rules for the content negotiation. The most important point is that the two or three constants in this code should be defined correctly. (You should modify the address for the redirection appropriately.)

   1 <?php
   2 /**
   3  * NLS features
   4  */
   5 
   6 $tmp_NLS_pageID = getID();
   7 
   8 // parsing page ID for language detection
   9 if (substr($tmp_NLS_pageID, -3) == '.ko') {
  10         define('NLS_LANG', 'ko');
  11         define('NLS_ALT', 'en');
  12 } elseif (substr($tmp_NLS_pageID, -3) == '.en') {
  13         define('NLS_LANG', 'en');
  14         define('NLS_ALT', 'ko');
  15 } else {
  16         $tmp_lang = 'en';       // This (English) is the default!
  17         // parsing 'Accept-Language' header from UA
  18         $acclang_arr = split(" *, *", trim($_SERVER['HTTP_ACCEPT_LANGUAGE']));
  19         foreach ($acclang_arr as $acclang) {
  20                 if (ereg("^(.+) *;.+= *(.+)$", $acclang, $acclang_parts))
  21                         $acclang_sorted[$acclang_parts[1]] = (double)($acclang_parts[2]);
  22                 else
  23                         $acclang_sorted[$acclang] = 1.0;
  24         }
  25         asort($acclang_sorted, SORT_NUMERIC);
  26         reset($acclang_sorted);
  27         foreach ($acclang_sorted as $lang_str => $priority) {
  28                 if (ereg("ko.*", $lang_str))
  29                         $tmp_lang = 'ko';
  30                 elseif (ereg("en.*", $lang_str))
  31                         $tmp_lang = 'en';
  32         }
  33         define('NLS_LANG', $tmp_lang);
  34         define('NLS_ALT', ($tmp_lang == 'ko') ? 'en' : 'ko');
  35         define('NLS_REDIRECT', $tmp_NLS_pageID.".".NLS_LANG);
  36         if (! array_key_exists("idx", $_GET))  // No redirection when indexing
  37                 header('Location: /' . str_replace(":", "/", NLS_REDIRECT));
  38 }
  39 
  40 // a quick hack for UI  -- testing version
  41 global $conf;
  42 $conf['lang'] = NLS_LANG;
  43 require_once(DOKU_INC.'inc/lang/'.$conf['lang'].'/lang.php');
  44 setlocale(LC_ALL, (NLS_LANG == 'ko' ? 'ko_KR' : 'en_US'). ".UTF-8");
  45 ?>

Then, add a line for this NLS feature at the front part of doku.php file. The position of this line is very important. NLS should be loaded as early as possible, but should be loaded after the inc/pageutils.php file because NLS utilizes a feature in this file. So, load NLS just after the inc/pageutils.php. (The last part of this code is omitted.)

   1 /**
   2  * DokuWiki mainscript
   3  *
   4  * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
   5  * @author     Andreas Gohr <andi@splitbrain.org>
   6  */
   7 
   8 //  xdebug_start_profiling();
   9 
  10 if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__)).'/');
  11 require_once(DOKU_INC.'inc/init.php');
  12 require_once(DOKU_INC.'inc/common.php');
  13 require_once(DOKU_INC.'inc/pageutils.php');
  14 require_once(DOKU_INC.'inc/NLS.php');  // 이 줄을 추가합니다.
  15 require_once(DOKU_INC.'inc/html.php');
  16 require_once(DOKU_INC.'inc/auth.php');
  17 require_once(DOKU_INC.'inc/actions.php');
  18 ...

By the works done until now, two features are implemeted:

Now, let's implement a feature which let a visitor click a link saying "English version of this document", for example. The code below is a part of main.php in my own template:

   1 <?php if ($ACT == 'show' && ! defined('NLS_REDIRECT')) { ?>
   2         <?php
   3         $NLS_altp_ID = substr($ID, 0, -2) . NLS_ALT;
   4         $NLS_altp_URL = str_replace(':', '/', $NLS_altp_ID);
   5         $NLS_altp_exists = false;
   6         resolve_pageid(getNS($NLS_altp_ID), $NLS_altp_ID, $NLS_altp_exists);
   7         ?>
   8         <a href="/<?php echo $NLS_altp_URL; ?>"><img
   9             src="<?php echo DOKU_TPL ?>images/gnome-24/config-language.png"
  10             width="24" height="24" alt="NLS feature"/>
  11         <?php if ($NLS_altp_exists && NLS_ALT == 'ko') { ?>
  12         이 문서의 한국어판
  13         <?php } elseif ($NLS_altp_exists) { ?>
  14         English version of this document
  15         <?php } elseif ((! $NLS_altp_exists) && NLS_ALT == 'ko') { ?>
  16         이 문서에는 아직 한국어판이 없습니다.
  17         <?php } else { ?>
  18         No English version for this document yet
  19         <?php } ?></a>
  20 <?php } ?>

The functions resolve_pageid and getNS here are built-in functions of DokuWiki.

You can use the constant NLS_LANG in many other places.

To Do

I want to separate the content NLS from the UI NLS. The work for this seems not heavy, but still tedious. :-( The goal for separations are:

I'm procrastinating because it seems not so urgent. Maybe I'll do it oneday. :-?

The last methods seems not so good. I'll postpone it indefinitely.


  1. For more complete NLS features, see Multilingual sites with DokuWiki and Browser Language Detection. (1)

  2. For the UI, however, this requirement can be changed. After the content NLS is separated from the UI NLS oneday, almost every visitors will be able to see the UI in their own language. (2)

  3. This will be changed. The language for UI will be selected and saved as a cookie, or will be automatically changed according to the browser setting. (3)

  4. This is not so simple, but still possible. :-) (4)