====== 도쿠위키 다국어지원 (NLS): 2005-09-22e-1.0.x ======
* 마지막 마이너 버전 업그레이드: 2005-09-22e-1.0.**2**
* **DRAFT:** 이 문서는 아직 작업중이며, 계속 변경되고 있습니다.
* 이 문서는 [[doku>wiki:dokuwiki|도쿠위키]] **2005-09-22e 판**을 대상으로 합니다. 다른 버전에서는 이 문서에서 설명하는 방법이 작동하지 않을 수 있습니다.
* 이 문서에서 말하는 다국어지원 (NLS) 기능이란 '한국어를 기본 언어로 사용하며 영어를 추가로 지원하기 위한 제한적이고 부분적인 다국어지원'을 뜻합니다. 물론 같은 아이디어를 기반으로 조금만 수정하면 한국어 이외의 다른 언어를 기본 언어로 사용하거나 몇 가지 더 많은 수의 언어들을 지원하도록 확장할 수 있습니다만, 이는 어디까지나 이 기법을 가져가서 쓰시는 분들의 역할일 뿐입니다.((더 완전한 다국어지원 기능을 원하시면 [[doku>wiki:multilingual_content|Multilingual sites with DokuWiki]]와 [[doku>wiki:tips:browserlanguagedetection|Browser Language Detection]]을 참조하시기 바랍니다.))
===== 요구 조건에 대한 가정 =====
이 문서에서 설명하는 기법은 다음과 같은 요구조건이 주어진 경우에 쓰일 수 있습니다:
* 웹 사이트의 도메인명과 호스트명이 고정되어있으며 임의로 추가하거나 바꿀 수 없습니다. 즉, [[http://www.wikipedia.org|위키 백과사전]]처럼 언어에 따라서 ''en.wikipedia.org''나 ''ko.wikipedia.org''를 사용할 수 없는 경우입니다.
* 사용자 관리 등의 여러가지 편의를 위해 오직 한 개의 도쿠위키 설치본만을 운영하고 싶습니다. 즉, 언어에 따라서 서로 다른 별도의 위키 설치본을 운영하고싶지는 않습니다.
* 표현하고자 하는 언어의 종류가 미리 확정되어있습니다. 즉, 관리자가 미처 예상하지 못했던 신기한 언어 사용자가 접속할 경우 (비록 도쿠위키 자체적으로는 그 언어에 대한 UI 번역 등이 마련되어있다고 해도) 그 사용자 특유의 언어까지 지원해줄 생각은 없으며, 이런 사용자는 미리 확정되어있는 언어들 중에서 가장 타당한 다른 언어를 보게될 것입니다.((단, 문서 내용이 아닌 UI에 관해서 만큼은 이 조항이 바뀔 수도 있습니다. 추후 문서 내용에 대한 다국어지원 기능과 UI에 대한 다국어지원 기능이 분리되면 모드 사용자들은 자신이 원하는 언어로 UI를 쓸 수 있게됩니다.))
* 사용자의 브라우저 언어 설정에 따라 유연하게 동작하게끔 만들고싶지만, 그 와중에도 사용자가 명시적으로 자신의 브라우저 언어 설정과는 다른 언어를 자유롭게 선택해서 볼 수 있는 여지도 남기고 싶습니다.
* 모든 문서들을 (미리 확정된) 모든 언어들로 전부 번역할 생각은 없습니다. 어떤 문서는 여러가지 언어로 번역되고 사용자의 브라우저 언어 설정이나 선택에 따라 각종 번역본을 제공하겠지만, 또 어떤 문서는 그 중 일부 언어들로만 (심지어 오직 하나의 언어로만) 제공될지도 모릅니다.
* A 언어로 번역된 문서를 보고있는 상태에서는 UI도 A 언어로 보입니다.((이 부분도 추후 개선될 예정입니다. 쿠키 등을 통해 UI 언어만큼은 문서 내용 언어에 상관 없이 한 언어로 고정시키거나 브라우저 설정을 따르도록 선택할 수 있게될 것입니다.))
* 검색 엔진에 모든 언어의 문서들이 제대로 등록되기 위해서
* 서로 다른 언어로 작성된 문서는 서로 다른 URL을 가져야하며,
* form submit이 아닌 단순 링크에 의해 각 언어 사이를 넘나들 수 있어야합니다.
===== 기본 아이디어 =====
기본 아이디어는 무척 단순합니다만, 설명의 편의를 위해 지금부터 한 가지 가정을 하겠습니다: 관리자는 자신의 위키 사이트에 한국어(ko)와 영어(en) 번역본을 넣을 생각입니다.
* 모든 문서들의 ID를 ''*.ko''(한글판)이나 ''*.en''(영문판)으로 재조정합니다. 그렇지 않은 문서가 존재하더라도 오류를 유발하지는 않지만, 존재할 필요가 없는 문서일 뿐만 아니라 어차피 그 내용을 읽을 수도 없습니다.
* 사용자가 요청한 문서가 한글판이냐 영문판이냐에 따라서 NLS_LANG이라는 상수를 정의해둡니다.
* 만일 사용자가 요청한 문서가 한글판도 영문판도 아니라면, 사용자 브라우저의 언어 설정에 따라 간단히 content negotiation을 수행합니다. 그 결과에 따라:
* NLS_LANG 상수의 값을 ''ko''나 ''en'' 중 하나로 결정합니다.
* NLS_REDIRECT라는 상수를 설정합니다. 요청한 문서 ID 뒤에 마침표와 NLS_LANG을 붙이면 됩니다.
* HTTP header나 HTML meta 태그를 통해 NLS_REDIRECT 문서로 자동 이동합니다.
* ''$conf['lang']'' 변수의 값을 NLS_LANG으로 재조정해둡니다. **주의:** ''$conf'' 배열은 도쿠위키 스크립트의 무척 초기에 세팅됩니다. 몇 가지 이유로 NLS_LANG 상수의 값을 이보다 빨리 결정해두기가 어려우므로, NLS_LANG이 결정된 후 기존에 세팅되어있는 ''$conf['lang']''을 변경하고 **그 효과가 확실히 나타나도록 조치**하는게 중요합니다.((이 부분이 의외로 간단치 않습니다만, 모든 일이 그렇듯이 방법은 있습니다. :-) ))
* 언어 파일 (''inc/lang/$conf['lang']/lang.php'')을 재등록합니다.
* locale을 ''ko_KR.UTF-8''이나 ''en_US.UTF-8''로 적절히 재설정합니다.
* 자신의 템플릿 파일(예: ''lib/tpl/foo/mail.php'')에서 NLS_LANG, NLS_REDIRECT 등을 적극 활용합니다.
이상입니다. 간단하죠? :-)
===== 코드 =====
''inc/NLS.php'' 파일을 생성합니다. 아래 코드는 제가 작성한 ''inc/NLS.php''의 내용이지만,
언어 종류나 content negotiation 정책은 조금씩 바꿔쓰실 수 있습니다.
중요한 점은, 이 코드에서 정의하고있는 2~3가지 상수들이 반드시 올바르게 정의되어야 한다는 점 뿐입니다.
(리다이렉션 주소는 알맞게 고치셔야합니다.)
$priority) {
if (ereg("ko.*", $lang_str))
$tmp_lang = 'ko';
elseif (ereg("en.*", $lang_str))
$tmp_lang = 'en';
}
define('NLS_LANG', $tmp_lang);
define('NLS_ALT', ($tmp_lang == 'ko') ? 'en' : 'ko');
define('NLS_REDIRECT', $tmp_NLS_pageID.".".NLS_LANG);
if (! array_key_exists("idx", $_GET)) // No redirection when indexing
header('Location: /' . str_replace(":", "/", NLS_REDIRECT));
}
// a quick hack for UI -- testing version
global $conf;
$conf['lang'] = NLS_LANG;
require_once(DOKU_INC.'inc/lang/'.$conf['lang'].'/lang.php');
setlocale(LC_ALL, (NLS_LANG == 'ko' ? 'ko_KR' : 'en_US'). ".UTF-8");
?>
이제 ''doku.php'' 파일의 초판부에 다음과 같이 NLS 기능을 하는 스크립트를 추가합니다.
이 줄의 위치가 무척 중요합니다. NLS 스크립트는 가능한 한 일찍 로딩되는 것이 좋은데,
''inc/pageutils.php'' 파일에 들어있는 기능 하나를 꼭 써야하므로 이보다는 뒤에
들어와야합니다. 따라서 ''inc/pageutils.php'' 바로 아래에 추가하십시오:
(이 코드는 아랫부분이 생략되어있습니다.)
/**
* DokuWiki mainscript
*
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
* @author Andreas Gohr
*/
// xdebug_start_profiling();
if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__)).'/');
require_once(DOKU_INC.'inc/init.php');
require_once(DOKU_INC.'inc/common.php');
require_once(DOKU_INC.'inc/pageutils.php');
require_once(DOKU_INC.'inc/NLS.php'); // 이 줄을 추가합니다.
require_once(DOKU_INC.'inc/html.php');
require_once(DOKU_INC.'inc/auth.php');
require_once(DOKU_INC.'inc/actions.php');
...
이상의 내용만으로도 일단
* 언어별 문서 번역본에 따른 UI 언어와 로켈 재설정
* 언어별 문서가 아닐 경우 적절한 언어별 문서로 자동 이동
기능은 구현되었습니다.
이제, 예를 들어 사용자(방문객)가 **이 문서의 영문 번역판 보기** 등의 링크를 누를 수 있게 해보겠습니다.
아래 코드는 제 자작 템플릿에 들어있는 ''main.php'' 파일의 일부입니다:
이 문서의 한국어판
English version of this document
이 문서에는 아직 한국어판이 없습니다.
No English version for this document yet
여기서 resolve_pageid나 getNS 등의 함수는 도쿠위키에 내장된 함수입니다.
이 외에도 많은 부분에 NLS_LANG 등의 상수들을 활용할 수 있습니다.
===== 할 일 =====
문서 내용에 대한 NLS와 UI에 대한 NLS를 분리하고 싶습니다.
작업량은 그다지 많을 것 같지 않은데, 귀찮군요. :-(
분리 목표는:
* 언어가 명시되지 않은 가상 문서 요청시 적절한 언어별 문서로 redirection하는 과정은 현행 방식대로 유지합니다. (브라우저 설정에만 의존)
* 언어별 문서를 보다가 그 문서의 다른 언어판으로 이동하는 링크도 현행대로 유지합니다.
* 다만, 도쿠위키 UI에 쓰이는 언어는 결정 방식이 바뀝니다. 상기 번역판 링크와는 별도로, UI 언어를 결정하는 select 박스와 설정 버튼을 만들고 그 선택 내용을 쿠키로 저장합니다. 선택 항목은:
* 브라우저 언어 설정에 맞춤 (향후 이것을 **기본 값**으로 할 예정입니다.)
* 읽고있는 문서의 내용 언어에 맞춤 (즉, 현행 방식)
* 무조건 한국어 UI로 고정
* 무조건 영어 UI로 고정
입니다. 시급한 문제는 아니라서 귀차니즘이 발동중인데, 언젠가는 하겠죠 뭐.... :-P
마지막 방식은 아무래도 별로 좋은 방법이 아닌 것 같아서 무기한 보류합니다.