계정: 로그인
AA 📝
이전 배포판: 1.0판

(!) English version of this document also exists.

요구 조건에 대한 가정

이 문서에서 설명하는 기법은 다음과 같은 요구조건이 주어진 경우에 쓰일 수 있습니다:

기본 아이디어

기본 아이디어는 무척 단순합니다만, 설명의 편의를 위해 지금부터 한 가지 가정을 하겠습니다: 관리자는 자신의 위키 사이트에 한국어(ko)와 영어(en) 번역본을 넣을 생각입니다.

이상입니다. 간단하죠? :-)

코드

inc/NLS.php 파일을 생성합니다. 아래 코드는 제가 작성한 inc/NLS.php의 내용이지만, 언어 종류나 content negotiation 정책은 조금씩 바꿔쓰실 수 있습니다. 중요한 점은, 이 코드에서 정의하고있는 2~3가지 상수들이 반드시 올바르게 정의되어야 한다는 점 뿐입니다. (리다이렉션 주소는 알맞게 고치셔야합니다.)

   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 ?>

이제 doku.php 파일의 초판부에 다음과 같이 NLS 기능을 하는 스크립트를 추가합니다. 이 줄의 위치가 무척 중요합니다. NLS 스크립트는 가능한 한 일찍 로딩되는 것이 좋은데, inc/pageutils.php 파일에 들어있는 기능 하나를 꼭 써야하므로 이보다는 뒤에 들어와야합니다. 따라서 inc/pageutils.php 바로 아래에 추가하십시오: (이 코드는 아랫부분이 생략되어있습니다.)

   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 ...

이상의 내용만으로도 일단

기능은 구현되었습니다. 이제, 예를 들어 사용자(방문객)가 이 문서의 영문 번역판 보기 등의 링크를 누를 수 있게 해보겠습니다. 아래 코드는 제 자작 템플릿에 들어있는 main.php 파일의 일부입니다:

   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 } ?>

여기서 resolve_pageid나 getNS 등의 함수는 도쿠위키에 내장된 함수입니다.

이 외에도 많은 부분에 NLS_LANG 등의 상수들을 활용할 수 있습니다.

할 일

문서 내용에 대한 NLS와 UI에 대한 NLS를 분리하고 싶습니다. 작업량은 그다지 많을 것 같지 않은데, 귀찮군요. :-( 분리 목표는:

입니다. 시급한 문제는 아니라서 귀차니즘이 발동중인데, 언젠가는 하겠죠 뭐.... :-?

마지막 방식은 아무래도 별로 좋은 방법이 아닌 것 같아서 무기한 보류합니다.


  1. 더 완전한 다국어지원 기능을 원하시면 Multilingual sites with DokuWikiBrowser Language Detection을 참조하시기 바랍니다. (1)

  2. 단, 문서 내용이 아닌 UI에 관해서 만큼은 이 조항이 바뀔 수도 있습니다. 추후 문서 내용에 대한 다국어지원 기능과 UI에 대한 다국어지원 기능이 분리되면 모드 사용자들은 자신이 원하는 언어로 UI를 쓸 수 있게됩니다. (2)

  3. 이 부분도 추후 개선될 예정입니다. 쿠키 등을 통해 UI 언어만큼은 문서 내용 언어에 상관 없이 한 언어로 고정시키거나 브라우저 설정을 따르도록 선택할 수 있게될 것입니다. (3)

  4. 이 부분이 의외로 간단치 않습니다만, 모든 일이 그렇듯이 방법은 있습니다. :-) (4)