저자: 조아오 프라도 마이아(Joao Prado Maia), 역 전순재
문제의 이해
웹 개발을 하다 보면 여러 언어를 동적으로 사용할 수 있는 웹 애플리케이션이나 웹 사이트를 만들어야 할 상황에 봉착해 본적이 있을 것이다. 기존의 많은 오픈 소스 애플리케이션들은 이러한 요구를 스스로 해결하려고 시도하고 있지만 표준적인 방식은 Gettext를 사용하는 것이다. Gettext는 자신의 애플리케이션에서 패키지들이 다중 언어 메시지들을 관리하는데 도움을 주는 GNU 도구 모음중의 하나이다.
Xchat 등등과 같은 대다수의 오픈 소스 프로젝트에서는 Gettext를 사용하여 메시지와 문자열들을 사용자 인터페이스에 여러 언어로 번역해 보여준다. 같은 개념이 웹 사이트나 웹 애플리케이션에도 적용될 수 있으며 이것이 바로 이 기사가 다루고자 하는 목표이다.
필요한 것
그렇다면 지금 당장 필요한 것은 Gettext PHP 확장을 PHP 안에서 사용할 수 있도록 만들어서 그 함수에 접근하는 방법이다. 윈도우 사용자라면 이미 Gettext DLL을 이미 가지고 있을 것이므로
php.ini 설정 파일을 확장할 수 있게만 변경해주면 될 것이다.
그렇게 하려면
php_gettext.dll이 있는 라인 앞에서 세미콜론을 제거하면 된다. 그 다음, 그 환경설정 파일을 저장하고 웹 서버 소프트웨어를 다시 실행하자. 그러면 이 기사에 사용된 조각 코드를 테스트하고 사용할 수 있을 것이다.
리눅스나 BSD, 또는 기타 다른 UNIX 운영 체제를 사용하고 있다면 이 확장을 설정하는데는 더 많은 선택사항이 있다. 가장 확실한 방법은 적절한 패키지를 레드햇 RPM이나 데비안 패키지와 같은 배포 벤더로부터 입수하는 것이다.
Gettext 101
간단히 말해, Gettext PHP 확장이 있으면 gettext() 함수를 사용해 적절히 번역된 문자열들을 선택하여 동적으로 문자열들을 PHP 코드에 번역할 수 있다. 아직 문자열이 번역되지 않았다면 대신 원래의 문자열이 사용된다.
간단한 예는 다음과 같다:
Gettext 파일들 설정하기
Gettext는
locale 디렉토리에 모든 번역된 문자열들이 다음과 같은 구조로 보관된다고 예상 하에 작동한다.
/locale
/en
/LC_MESSAGES
messages.po
messages.mo
그래서 웹 사이트의 경우,
locale 디렉토리는 웹루트(webroot) 안에 존재하게 될 것이다. 그렇지 않다면 그건 전적으로 여러분의 선택에 달린 문제이다. 위의 예제에서 보여준
bindtextdomain() 함수에서처럼 말이다.
번역된 문자열들을 보여주기 원하는 언어마다 하나의
language 하부디렉토리를 여러분이 직접 항상 만들어야 한다는 것을 기억하자. 예를 들어, 여러분의 사이트가 브라질식 포루투갈어(
pt_BR)로 번역되기를 원하면,
pt_BR 하부디렉토리를 만들고 그 적절한 언어 코드를 PHP 코드 안에 다음과 같이 삽입하면 된다.
그래서 새로
pt_BR 디렉토리를 만들고 나면 디렉토리 구조는 다음과 거의 비슷하게 보일 것이다.
/locale
/en
/LC_MESSAGES
messages.po
messages.mo
/pt_BR
/LC_MESSAGES
messages.po
messages.mo
모든 디렉토리들이 준비되고 나면 이제 실제로 "pot" 파일을 만들 차례이다. 그 파일은 보통
messages.po 파일이라고 불려진다. 이렇게 하려면 여러분이 사용할 PHP 파일은
gettext() 함수를 사용하여 번역될 문자열들을 "표식설정" 해놓아야 하고 여러분은 다음과 같이
xgettext 명령어를 사용하면 된다.
$ xgettext -n *.php
위의 라인은 번역될 약간의 문자열들이 담긴
messages.po 파일을 만들어 낼 것이다. 다음과 상당히 비슷하게 보일 것이다.
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR Free Software Foundation, Inc.
# FIRST AUTHOR , YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2002-04-06 21:44-0500\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME \n"
"Language-Team: LANGUAGE \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
#: gettext_example.php:12
msgid "A string to be translated would go here"
msgstr ""
이 파일에는
gettext() 호출안에서 발견된 모든 문자열들이 담긴다. 그리고 이 파일은 번역자들이 애플리케이션을 각 언어별로 번역하는데 사용된다(우리의 경우에는 웹 애플리케이션).
Pot 파일 분배하기
좋다, 이제 번역되어야 할 문자열들이 담긴 pot 파일을 확보하였으므로 이 파일을 번역자들에게 분배하면 된다. 성공적인 오픈 소스 프로젝트라면 여러 다양한 자원 봉사자들이 여러분의 인터페이스 메시지의 번역을 담당하고 있을 것이다. 이런 경우라면 전자우편을 개발 메일링 리스트에 보내어 다음 배포판이 언제쯤 나올 것이고 어떤 언어 목록이 갱신될 필요가 있는지를 자원 봉사자들에게 알려 줄 것이다.
물론 그것은 성공적인 프로젝트 이야기이다. 정상적인 상황이라고 하더라도 프로젝트 리더인 여러분 자신이 직접 주요한 번역작업을 하고 자원 봉사자들로부터의 자발적인 참여를 기다릴 것이기 때문이다. 웹 사이트나 웹 애플리케이션에서 상황은 보통 그렇지 않다. 다시 말해 보통 개인 웹 사이트를 위해 일해 주는 자원 봉사자 팀은 보통 없다. 그렇지만 themes.org와 같은 공동체 웹 사이트라면 상황은 다르다.
어느 경우든 여러분이나 자원 봉사자가 pot 파일을 번역할 것이고 이제 필요한 것은 그 파일을 Gettext가 실제로 "이해할 수 있는" 이진 파일로 변환하는 것이다. 변환을 위해서는 다음과 같은 명령어를 사용하면 된다.
$ msgfmt messages.po
위 라인은
messages.mo 파일을 만들어 낼 것이다. 이 파일을 그에 적절한
locale//LC_MESSAGES/ 디렉토리에 저장하자.
진화하는 Pot 파일 관리하기
이제 이 모든 것들을 멈추고 잠시 생각해 보는 시간을 갖자. 여러분은 끊임없이 갱신되는 웹 사이트를 가지고 있다. 새로운 특징이 추가되거나 문제점들이 제거되고, 번역될 문자열들 역시 변화한다. 새로운 문자열들이 추가되고, 예전 문자열들이 수정된다. 등등.
이러한 상황에서 어떻게 여러 버전의 pot 파일을 관리할 수 있겠는가? 정상적인 상황이라면 특정 언어에 대하여 완전하게 번역된
messages.po 파일과 번역될 새로운 문자열들이 담긴 새 파일이 있을 것이다. 문제는 여기에 있다. Gettext는 다른 방식으로 작동하지 않으므로, 이 새 파일은 위의 예제에서 보여준 파일과 똑 같이 보일 것이다. 즉 (msgstr을 보면) 비어 있을 것이다.
문제는 파일들을 합병하는 법이다. 이미 번역된 문자열들을 그대로 유지하면 새롭게 번역된 문자열들을 추가하는 방법말이다. 해답은
msgmerge Gettext 유틸리티가 쥐고 있다. 그 사용법은 다음과 같은 명령어 처리를 따른다.
$ ls
example.php
$ xgettext -n *.php
$ ls
example.php messages.po
// ...
// 이제 messages.po 파일을 번역한다
// ...
$ msgfmt messages.po
$ ls
example.php messages.po messages.mo
// ...
// example.php 파일을 변경한다
// ...
$ mv messages.po old.po
$ xgettext -n *.php
$ ls
example.php messages.po messages.mo old.po
$ msgmerge old.po messages.po --output-file=new.po
$ ls
example.php messages.po messages.mo new.po old.po
// ...
// new.po 파일을 번역한다
// ...
$ msgfmt new.po
다음은 무엇을
지금 할 수 있는 최선의 방법은 직접 시험해 보는 것이다. Gettext PHP 확장을 사용할 수 있도록 만들고 그것을 가지고 놀아보기만 하면 된다. 여기에 제공된 예제는 간단하지만 여러 언어에 대하여 애플리케이션을 구축하기에는 충분하리라 생각된다.
더 자세한 정보는
Gettext 매뉴얼을 참조하자.
즐거운 시간이 되었기를 바란다.
조아오 프라도 마이아(Joao Prado Maia)는 휴스턴(Houston)에 살고 있는 웹 개발자로 웹 기반 애플리케이션을 개발한 지는 4년이 넘었다. 웹 기반 애플리케이션 개발 외에도 새로운 기술과 프로그래밍 언어 배우는 것을 아주 좋아한다.