이 문서에서 설명하는 기법은 다음과 같은 요구조건이 주어진 경우에 쓰일 수 있습니다:
en.wikipedia.org나 ko.wikipedia.org를 사용할 수 없는 경우입니다.기본 아이디어는 무척 단순합니다만, 설명의 편의를 위해 지금부터 한 가지 가정을 하겠습니다: 관리자는 자신의 위키 사이트에 한국어(ko)와 영어(en) 번역본을 넣을 생각입니다.
*.ko(한글판)이나 *.en(영문판)으로 재조정합니다. 그렇지 않은 문서가 존재하더라도 오류를 유발하지는 않지만, 존재할 필요가 없는 문서일 뿐만 아니라 어차피 그 내용을 읽을 수도 없습니다.ko나 en 중 하나로 결정합니다.$conf[’lang’] 변수의 값을 NLS_LANG으로 재조정해둡니다. 주의: $conf 배열은 도쿠위키 스크립트의 무척 초기에 세팅됩니다. 몇 가지 이유로 NLS_LANG 상수의 값을 이보다 빨리 결정해두기가 어려우므로, NLS_LANG이 결정된 후 기존에 세팅되어있는 $conf[’lang’]을 변경하고 그 효과가 확실히 나타나도록 조치하는게 중요합니다.4)inc/lang/$conf[’lang’]/lang.php)을 재등록합니다.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가지 상수들이 반드시 올바르게 정의되어야 한다는 점 뿐입니다. (리다이렉션 주소는 알맞게 고치셔야합니다.)
<?php /** * NLS features */ $tmp_NLS_pageID = getID(); // parsing page ID for language detection if (substr($tmp_NLS_pageID, -3) == '.ko') { define('NLS_LANG', 'ko'); define('NLS_ALT', 'en'); } elseif (substr($tmp_NLS_pageID, -3) == '.en') { define('NLS_LANG', 'en'); define('NLS_ALT', 'ko'); } else { $tmp_lang = 'en'; // This (English) is the default! // parsing 'Accept-Language' header from UA $acclang_arr = split(" *, *", trim($_SERVER['HTTP_ACCEPT_LANGUAGE'])); foreach ($acclang_arr as $acclang) { if (ereg("^(.+) *;.+= *(.+)$", $acclang, $acclang_parts)) $acclang_sorted[$acclang_parts[1]] = (double)($acclang_parts[2]); else $acclang_sorted[$acclang] = 1.0; } asort($acclang_sorted, SORT_NUMERIC); reset($acclang_sorted); foreach ($acclang_sorted as $lang_str => $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 <andi@splitbrain.org> */ // 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'); ...
이상의 내용만으로도 일단
기능은 구현되었습니다. 이제, 예를 들어 사용자(방문객)가 이 문서의 영문 번역판 보기 등의 링크를 누를 수 있게 해보겠습니다. 아래 코드는 제 자작 템플릿에 들어있는 main.php 파일의 일부입니다:
<?php if ($ACT == 'show' && ! defined('NLS_REDIRECT')) { ?> <?php $NLS_altp_ID = substr($ID, 0, -2) . NLS_ALT; $NLS_altp_URL = str_replace(':', '/', $NLS_altp_ID); $NLS_altp_exists = false; resolve_pageid(getNS($NLS_altp_ID), $NLS_altp_ID, $NLS_altp_exists); ?> <a href="/<?php echo $NLS_altp_URL; ?>"><img src="<?php echo DOKU_TPL ?>images/gnome-24/config-language.png" width="24" height="24" alt="NLS feature"/> <?php if ($NLS_altp_exists && NLS_ALT == 'ko') { ?> 이 문서의 한국어판 <?php } elseif ($NLS_altp_exists) { ?> English version of this document <?php } elseif ((! $NLS_altp_exists) && NLS_ALT == 'ko') { ?> 이 문서에는 아직 한국어판이 없습니다. <?php } else { ?> No English version for this document yet <?php } ?></a> <?php } ?>
여기서 resolve_pageid나 getNS 등의 함수는 도쿠위키에 내장된 함수입니다.
이 외에도 많은 부분에 NLS_LANG 등의 상수들을 활용할 수 있습니다.
문서 내용에 대한 NLS와 UI에 대한 NLS를 분리하고 싶습니다. 작업량은 그다지 많을 것 같지 않은데, 귀찮군요.
분리 목표는:
입니다. 시급한 문제는 아니라서 귀차니즘이 발동중인데, 언젠가는 하겠죠 뭐....
마지막 방식은 아무래도 별로 좋은 방법이 아닌 것 같아서 무기한 보류합니다.