다국어 앱을 구축하는 방법: PHP 및 Gettext를 사용한 데모
게시 됨: 2022-03-11웹 사이트를 구축하든 본격적인 웹 애플리케이션을 구축하든 더 많은 청중이 액세스할 수 있도록 하려면 종종 다른 언어와 로케일로 사용할 수 있어야 합니다.
대부분의 인간 언어 간의 근본적인 차이점은 이것을 쉽게 만듭니다. 문법 규칙, 언어 뉘앙스, 날짜 형식 등의 차이점이 결합되어 현지화를 독특하고 어려운 과제로 만듭니다.
이 간단한 예를 고려하십시오.
영어의 복수화 규칙은 매우 간단합니다. 단어의 단수형이나 복수형을 가질 수 있습니다.
그러나 슬라브어와 같은 다른 언어에는 단수형 외에 두 개의 복수형이 있습니다. 슬로베니아어, 아일랜드어 또는 아랍어와 같이 총 4개, 5개 또는 6개의 복수형이 있는 언어를 찾을 수도 있습니다.
코드가 구성되는 방식과 구성 요소와 인터페이스가 설계되는 방식은 애플리케이션을 얼마나 쉽게 현지화할 수 있는지 결정하는 데 중요한 역할을 합니다.
코드베이스의 국제화 (i18n)를 통해 다른 언어나 지역에 비교적 쉽게 적응할 수 있습니다. 국제화는 일반적으로 한 번 수행되며, 향후 소스 코드를 크게 변경할 필요가 없도록 프로젝트 초기에 수행하는 것이 좋습니다.
코드베이스가 국제화되면 현지화 (l10n)는 애플리케이션 콘텐츠를 특정 언어/로케일로 번역하는 문제가 됩니다.
새로운 언어나 지역을 지원해야 할 때마다 현지화를 수행해야 합니다. 또한 인터페이스의 일부(텍스트 포함)가 업데이트될 때마다 새 콘텐츠를 사용할 수 있게 되어 지원되는 모든 로캘로 현지화(즉, 번역)되어야 합니다.
이 기사에서는 PHP로 작성된 소프트웨어를 국제화하고 현지화하는 방법을 배웁니다. 다양한 구현 옵션과 프로세스를 쉽게 하기 위해 사용할 수 있는 다양한 도구를 살펴보겠습니다.
국제화를 위한 도구
PHP 소프트웨어를 국제화하는 가장 쉬운 방법은 배열 파일을 사용하는 것입니다. 배열은 번역된 문자열로 채워지며 템플릿 내에서 조회할 수 있습니다.
<h1><?=$TRANS['title_about_page']?></h1>
그러나 이것은 심각한 프로젝트에 권장되지 않는 방법입니다. 왜냐하면 이는 확실히 향후 유지 관리 문제를 야기할 것이기 때문입니다. 변수 보간 또는 명사의 복수화에 대한 지원 부족과 같은 일부 문제는 초기에 나타날 수도 있습니다.
가장 고전적인 도구(종종 i18n 및 l10n에 대한 참조로 사용됨) 중 하나는 Gettext라는 Unix 도구입니다.
1995년으로 거슬러 올라가지만 여전히 사용하기 쉬운 소프트웨어 번역을 위한 포괄적인 도구입니다. 시작하기가 매우 쉽지만 여전히 강력한 지원 도구가 있습니다.
Gettext는 이 포스트에서 사용할 것입니다. 우리는 l10n 소스 파일을 쉽게 업데이트하여 명령줄을 다룰 필요가 없도록 하는 데 사용할 수 있는 훌륭한 GUI 응용 프로그램을 선보일 것입니다.
일을 쉽게 만드는 라이브러리
Gettext 및 기타 i18n 구현을 지원하는 주요 PHP 웹 프레임워크 및 라이브러리가 있습니다. 일부는 다른 것보다 설치가 더 쉽거나 추가 기능을 제공하거나 다른 i18n 파일 형식을 지원합니다. 이 문서에서는 PHP 코어와 함께 제공되는 도구에 중점을 두고 있지만 다음은 언급할 가치가 있는 몇 가지 다른 도구 목록입니다.
oscarotero/Gettext: 객체 지향 인터페이스로 Gettext 지원; 향상된 도우미 기능, 여러 파일 형식을 위한 강력한 추출기(일부는
gettext
명령에서 기본적으로 지원하지 않음)를 포함합니다. .mo/.po 파일 이외의 형식으로 내보낼 수도 있습니다. 이는 JavaScript 인터페이스와 같은 시스템의 다른 부분에 번역 파일을 통합해야 하는 경우에 유용할 수 있습니다.symfony/translation: 다양한 형식을 지원하지만 자세한 XLIFF를 사용하는 것이 좋습니다. 도우미 함수 또는 내장 추출기는 포함하지 않지만 내부적으로
strtr()
을 사용하여 자리 표시자를 지원합니다.zend/i18n: 배열 및 INI 파일 또는 Gettext 형식을 지원합니다. 매번 파일 시스템을 읽을 필요가 없도록 캐싱 계층을 구현합니다. 또한 보기 도우미, 로케일 인식 입력 필터 및 유효성 검사기가 포함됩니다. 그러나 메시지 추출기가 없습니다.
다른 프레임워크에는 i18n 모듈도 포함되지만 코드베이스 외부에서는 사용할 수 없습니다.
Laravel: 기본 배열 파일을 지원합니다. 자동 추출기는 없지만 템플릿 파일용
@lang
도우미가 포함되어 있습니다.Yii: 배열, Gettext 및 데이터베이스 기반 번역을 지원하고 메시지 추출기를 포함합니다. PHP 5.3부터 사용할 수 있고 ICU 프로젝트를 기반으로 하는
Intl
확장으로 지원됩니다. 이를 통해 Yii는 숫자 철자, 날짜, 시간, 간격, 통화 및 서수 형식 지정과 같은 강력한 대체 작업을 실행할 수 있습니다.
추출기를 제공하지 않는 라이브러리 중 하나를 사용하기로 결정했다면 Gettext 형식을 사용할 수 있으므로 이 장의 나머지 부분에 설명된 대로 원본 Gettext 도구 모음(Poedit 포함)을 사용할 수 있습니다.
Gettext 설치
apt-get 또는 yum과 같은 패키지 관리자를 사용하여 Gettext 및 관련 PHP 라이브러리를 설치해야 할 수도 있습니다. 설치 후 php.ini
파일에 extension=gettext.so
(Linux/Unix) 또는 extension=php_gettext.dll
(Windows)을 추가하여 활성화합니다.
여기에서도 Poedit를 사용하여 번역 파일을 만들 것입니다. 아마도 시스템의 패키지 관리자에서 찾을 수 있을 것입니다. Unix, Mac 및 Windows에서 사용할 수 있으며 웹 사이트에서도 무료로 다운로드할 수 있습니다.
Gettext 파일 유형
Gettext로 작업하는 동안 일반적으로 처리하는 세 가지 파일 형식이 있습니다.
주요 파일은 PO(Portable Object) 및 MO(Machine Object) 파일이며, 첫 번째는 읽을 수 있는 "번역된 개체" 목록이고 두 번째는 해당 바이너리(현지화를 수행할 때 Gettext에서 해석됨)입니다. 소스 파일의 기존 키를 모두 포함하고 모든 PO 파일을 생성 및 업데이트하기 위한 가이드로 사용할 수 있는 POT(PO 템플릿) 파일도 있습니다.
템플릿 파일은 필수가 아닙니다. l10n을 수행하는 데 사용하는 도구에 따라 PO/MO 파일만 있으면 문제가 없습니다. 언어 및 지역당 한 쌍의 PO/MO 파일이 있지만 도메인당 하나의 POT만 있습니다.
도메인 분리
큰 프로젝트에서 같은 단어가 다른 맥락에서 다른 의미를 전달할 때 번역을 분리해야 하는 경우가 있습니다.
이러한 경우 파일 이름은 해당 번역 도메인 인 POT/PO/MO 파일의 기본적으로 명명된 그룹인 다른 "도메인"으로 분할해야 합니다.
중소 규모의 프로젝트는 일반적으로 단순성을 위해 하나의 도메인만 사용합니다. 이름은 임의적이지만 코드 샘플에 "main"을 사용할 것입니다.
예를 들어 Symfony 프로젝트에서 도메인은 유효성 검사 메시지의 번역을 분리하는 데 사용됩니다.
로케일 코드
로케일은 단순히 언어의 한 버전을 식별하는 코드입니다. ISO 639-1 및 ISO 3166-1 alpha-2 사양에 따라 정의됩니다. 언어에 대한 두 개의 소문자, 선택적으로 밑줄과 국가 또는 지역 코드를 식별하는 두 개의 대문자가 뒤따릅니다.
희귀 언어의 경우 세 글자가 사용됩니다.
일부 스피커의 경우 국가 부분이 중복되어 보일 수 있습니다. 사실, 일부 언어에는 오스트리아 독일어(de_AT) 또는 브라질 포르투갈어(pt_BR)와 같은 다른 국가의 방언이 있습니다. 두 번째 부분은 이러한 방언을 구별하는 데 사용됩니다. 존재하지 않는 경우 언어의 "일반" 또는 "하이브리드" 버전으로 간주됩니다.
디렉토리 구조
Gettext를 사용하려면 특정 폴더 구조를 준수해야 합니다.
먼저 소스 저장소에서 l10n 파일에 대한 임의의 루트를 선택해야 합니다. 그 안에는 필요한 각 로케일에 대한 폴더와 모든 PO/MO 쌍을 포함할 고정 "LC_MESSAGES" 폴더가 있습니다.
복수형
서론에서 말했듯이 언어마다 복수화 규칙이 다를 수 있습니다. 그러나 Gettext는 이러한 문제를 해결해 줍니다.
새 .po 파일을 만들 때 해당 언어에 대한 복수화 규칙을 선언해야 하며 복수형을 구분하는 번역된 부분은 각 규칙에 대해 다른 형식을 갖습니다.
코드에서 Gettext를 호출할 때 문장과 관련된 숫자를 지정해야 하며(예: "You have n messages."라는 문구의 경우 n 값을 지정해야 함) 올바른 형식을 계산합니다. 사용 - 필요한 경우 문자열 대체를 사용하는 경우에도.
복수의 규칙은 각 규칙에 대한 boolean 테스트에 필요한 수의 규칙으로 구성됩니다(최대 하나의 규칙에 대한 테스트는 생략될 수 있음). 예를 들어:
일본어:
nplurals=1; plural=0;
nplurals=1; plural=0;
- 하나의 규칙: 복수형은 없다영어:
nplurals=2; plural=(n != 1);
nplurals=2; plural=(n != 1);
- 두 가지 규칙: n이 1이 아닌 경우에만 복수형을 사용하고, 그렇지 않으면 단수형을 사용합니다.브라질 포르투갈어:
nplurals=2; plural=(n > 1);
nplurals=2; plural=(n > 1);
- 두 가지 규칙, n이 1보다 큰 경우에만 복수형을 사용하고, 그렇지 않으면 단수형을 사용합니다.
더 자세한 설명을 위해 온라인에서 사용할 수 있는 유익한 LingoHub 자습서가 있습니다.
Gettext는 제공된 번호를 기반으로 사용할 규칙을 결정하고 문자열의 올바른 현지화 버전을 사용합니다. 복수화를 처리해야 하는 문자열의 경우 정의된 각 복수형 규칙에 대해 다른 문장을 .po 파일에 포함해야 합니다.
샘플 구현
모든 이론이 끝나면 약간의 실습을 해 봅시다. 다음은 .po 파일의 일부입니다(구문에 대해 너무 걱정하지 말고 전체 내용을 파악하세요).
msgid "" msgstr "" "Language: pt_BR\n" "Content-Type: text/plain; charset=UTF-8\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" msgid "We're now translating some strings" msgstr "Nos estamos traduzindo algumas strings agora" msgid "Hello %1$s! Your last visit was on %2$s" msgstr "Ola %1$s! Sua ultima visita foi em %2$s" msgid "Only one unread message" msgid_plural "%d unread messages" msgstr[0] "So uma mensagem nao lida" msgstr[1] "%d mensagens nao lidas"
첫 번째 섹션은 msgid
및 msgstr
이 비어 있는 헤더처럼 작동합니다.
파일 인코딩, 복수형 및 기타 몇 가지 사항을 설명합니다. 두 번째 섹션은 간단한 문자열을 영어에서 브라질 포르투갈어로 번역하고 세 번째 섹션은 동일한 작업을 수행하지만 sprintf
에서 문자열 대체를 활용하여 번역에 사용자 이름과 방문 날짜를 포함할 수 있습니다.
마지막 섹션은 복수화 형식의 샘플로, 단수 및 복수 버전을 영어로 msgid
로 표시하고 해당 번역을 msgstr
0 및 1로 표시합니다(복수 규칙에 의해 제공된 번호에 따름).
거기에서 문자열 교체도 사용되므로 %d
를 사용하여 문장에서 숫자를 직접 볼 수 있습니다. 복수형은 항상 2개의 msgid
(단수 및 복수)를 가지므로 번역 소스로 복잡한 언어를 사용하지 않는 것이 좋습니다.
현지화 키
눈치채셨겠지만, 우리는 실제 영어 문장을 소스 ID로 사용하고 있습니다. 그 msgid
는 모든 .po 파일에서 동일하게 사용됩니다. 즉, 다른 언어도 동일한 형식과 동일한 msgid
필드를 갖지만 msgstr
행은 번역됩니다.
번역 키에 대해 말하자면 여기에는 두 가지 표준 "철학적" 접근 방식이 있습니다.
1. 실제 문장으로서의 msgstr
이 접근 방식의 주요 이점은 다음과 같습니다.
특정 언어로 번역되지 않은 소프트웨어 부분이 있는 경우 표시된 키는 여전히 일부 의미를 유지합니다. 예를 들어 영어에서 스페인어로 번역하는 방법을 알고 있지만 프랑스어로 번역하는 데 도움이 필요한 경우 프랑스어 문장이 누락된 새 페이지를 게시하고 웹사이트의 일부가 대신 영어로 표시될 수 있습니다.
번역가가 무슨 일이 일어나고 있는지 이해하고
msgid
를 기반으로 적절한 번역을 하는 것이 훨씬 쉽습니다.하나의 언어에 대해 "무료" l10n을 제공합니다. 즉, 소스 언어입니다.
반면에 실제 텍스트를 변경해야 하는 경우 여러 언어 파일에서 동일한 msgid
를 바꿔야 한다는 가장 큰 단점이 있습니다.
2. 고유하고 구조화된 키로 msgstr
이것은 내용 대신 문자열이 있는 템플릿이나 부분을 포함하여 구조화된 방식으로 응용 프로그램의 문장 역할을 설명합니다.
이것은 템플릿 논리에서 텍스트 내용을 분리하여 코드를 구성하는 좋은 방법입니다. 그러나 이는 문맥을 놓치는 번역가에게 문제를 일으킬 수 있습니다.
다른 번역의 기초로 소스 언어 파일이 필요합니다. 예를 들어, 개발자는 번역가가 "fr.po"에 무엇을 쓸지 이해하기 위해 읽을 "en.po" 파일이 이상적으로 있을 것입니다.
번역이 누락되면 화면에 의미 없는 키가 표시됩니다(해당 번역되지 않은 프랑스어 페이지에서 "Hello there, User!" 대신 "top_menu.welcome").
출판 전에 강제로 번역을 완료해야 하기 때문에 좋지만 번역 문제가 인터페이스에서 정말 끔찍하기 때문에 나쁩니다. 그러나 일부 라이브러리에는 다른 접근 방식과 유사한 동작을 하는 "대체"로 지정된 언어를 지정하는 옵션이 포함되어 있습니다.
Gettext 매뉴얼은 일반적으로 문제가 발생한 경우 번역가와 사용자가 더 쉽기 때문에 첫 번째 접근 방식을 선호합니다. 이것이 우리가 여기서도 사용할 접근 방식입니다.
그러나 Symfony 문서는 템플릿에도 영향을 주지 않고 모든 번역을 독립적으로 변경할 수 있도록 키워드 기반 번역을 선호합니다.
일상적인 사용
일반적인 응용 프로그램에서는 페이지에 정적 텍스트를 작성하는 동안 일부 Gettext 함수를 사용합니다.
그런 다음 해당 문장은 .po 파일에 표시되고 번역되고 .mo 파일로 컴파일된 다음 실제 인터페이스를 렌더링할 때 Gettext에서 사용됩니다. 이를 감안할 때 지금까지 논의한 내용을 단계별 예에서 함께 묶어 보겠습니다.

1. 몇 가지 다른 gettext 호출을 포함하는 샘플 템플릿 파일
<?php include 'i18n_setup.php' ?> <div> <h1><?=sprintf(gettext('Welcome, %s!'), $name)?></h1> <!-- code indented this way only for legibility → <?php if ($unread): ?> <h2> <?=sprintf( ngettext('Only one unread message', '%d unread messages', $unread), $unread )?> </h2> <?php endif ?> </div> <h1><?=gettext('Introduction')?></h1> <p><?=gettext('We\'re now translating some strings')?></p>
gettext()
는 단순히msgid
를 주어진 언어에 대한 해당msgstr
로 변환합니다. 같은 방식으로 작동하는 약식 함수_()
도 있습니다.ngettext()
는 동일하지만 복수 규칙을 사용합니다.단일 호출에 대해 도메인을 재정의할 수 있는
dgettext()
및dngettext()
도 있습니다(다음 예에서 도메인 구성에 대해 자세히 설명).
2. 샘플 설정 파일(위에서 사용된 i18n_setup.php), 올바른 로케일 선택 및 Gettext 구성
Gettext를 사용하려면 약간의 상용구 코드가 필요하지만 대부분 로케일 디렉토리를 구성하고 적절한 매개변수(로케일 및 도메인)를 선택하는 것입니다.
<?php /** * Verifies if the given $locale is supported in the project * @param string $locale * @return bool */ function valid($locale) { return in_array($locale, ['en_US', 'en', 'pt_BR', 'pt', 'es_ES', 'es'); } //setting the source/default locale, for informational purposes $lang = 'en_US'; if (isset($_GET['lang']) && valid($_GET['lang'])) { // the locale can be changed through the query-string $lang = $_GET['lang']; //you should sanitize this! setcookie('lang', $lang); //it's stored in a cookie so it can be reused } elseif (isset($_COOKIE['lang']) && valid($_COOKIE['lang'])) { // if the cookie is present instead, let's just keep it $lang = $_COOKIE['lang']; //you should sanitize this! } elseif (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) { // default: look for the languages the browser says the user accepts $langs = explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']); array_walk($langs, function (&$lang) { $lang = strtr(strtok($lang, ';'), ['-' => '_']); }); foreach ($langs as $browser_lang) { if (valid($browser_lang)) { $lang = $browser_lang; break; } } } // here we define the global system locale given the found language putenv("LANG=$lang"); // this might be useful for date functions (LC_TIME) or money formatting (LC_MONETARY), for instance setlocale(LC_ALL, $lang); // this will make Gettext look for ../locales/<lang>/LC_MESSAGES/main.mo bindtextdomain('main', '../locales'); // indicates in what encoding the file should be read bind_textdomain_codeset('main', 'UTF-8'); // if your application has additional domains, as cited before, you should bind them here as well bindtextdomain('forum', '../locales'); bind_textdomain_codeset('forum', 'UTF-8'); // here we indicate the default domain the gettext() calls will respond to textdomain('main'); // this would look for the string in forum.mo instead of main.mo // echo dgettext('forum', 'Welcome back!'); ?>
3. 첫 실행을 위한 번역 준비
Gettext가 사용자 정의 프레임워크 i18n 패키지에 비해 갖는 가장 큰 장점 중 하나는 광범위하고 강력한 파일 형식입니다.
아마도 당신은 "오 이런, 손으로 이해하고 편집하는 것이 상당히 어렵습니다. 간단한 배열이 더 쉬울 것입니다!"라고 생각하고 있을 것입니다. 실수하지 마세요. Poedit와 같은 응용 프로그램이 많은 도움이 될 것입니다. 웹사이트에서 프로그램을 다운로드할 수 있으며 무료이며 모든 플랫폼에서 사용할 수 있습니다. Gettext에서 사용할 수 있는 모든 기능을 사용하여 익숙해지기 매우 쉬운 도구이자 동시에 매우 강력한 도구입니다. 우리는 여기에서 최신 버전인 Poedit 1.8로 작업할 것입니다.
첫 번째 실행에서는 메뉴에서 "파일 > 새로 만들기…"를 선택해야 합니다. 언어를 묻는 메시지가 표시됩니다. 번역하려는 언어를 선택/필터링하거나 en_US
또는 pt_BR
과 같이 앞에서 언급한 형식을 사용합니다.
이제 우리가 언급한 디렉토리 구조를 사용하여 파일을 저장합니다. 그런 다음 "원본에서 추출"을 클릭해야 합니다. 여기에서 추출 및 번역 작업에 대한 다양한 설정을 구성합니다. 나중에 "카탈로그 > 속성"을 통해 모든 항목을 찾을 수 있습니다.
소스 경로:
gettext()
(및 형제)가 호출되는 프로젝트의 모든 폴더를 포함합니다. 이는 일반적으로 템플릿/보기 폴더입니다. 이것은 유일한 필수 설정입니다.번역 속성:
- 프로젝트 이름 및 버전, 팀 및 팀의 이메일 주소: .po 파일 헤더에 들어가는 유용한 정보입니다.
- 복수형: 이것은 우리가 앞에서 언급한 규칙입니다. Poedit에는 이미 여러 언어에 대한 복수 규칙의 편리한 데이터베이스가 포함되어 있으므로 대부분의 경우 기본 옵션으로 그대로 둘 수 있습니다.
- 문자 집합: UTF-8, 가급적이면.
- 소스 코드 charset: 코드베이스에서 사용하는 charset - 아마도 UTF-8도 마찬가지겠죠?
소스 키워드: 기본 소프트웨어는
gettext()
및 유사한 함수 호출이 여러 프로그래밍 언어에서 어떻게 보이는지 알고 있지만 고유한 번역 함수를 만들 수도 있습니다. 여기에 다른 방법을 추가할 것입니다. 이것은 "팁" 섹션의 뒷부분에서 논의될 것입니다.
이러한 속성을 설정한 후 Poedit는 소스 파일을 스캔하여 모든 현지화 호출을 찾습니다. 스캔할 때마다 Poedit는 소스 파일에서 발견된 항목과 제거된 항목에 대한 요약을 표시합니다. 새 항목은 번역 테이블에 비어 있으므로 해당 문자열의 현지화된 버전을 입력할 수 있습니다. 저장하면 .mo 파일이 동일한 폴더에 (재)컴파일되고 프로젝트가 국제화됩니다!
Poedit는 웹 및 이전 파일에서 일반적인 번역을 제안할 수도 있습니다. 편리한지 확인하고 수락하기만 하면 됩니다. 번역이 확실하지 않은 경우 퍼지로 표시하면 노란색으로 표시됩니다. 파란색 항목은 번역이 없는 항목입니다.
4. 문자열 번역
눈치채셨겠지만, 지역화된 문자열에는 두 가지 주요 유형이 있습니다. 단순 문자열과 복수형 문자열입니다.
간단한 것들은 소스와 현지화된 문자열이라는 두 개의 상자만 있습니다. Gettext/Poedit에는 소스 파일을 변경할 수 있는 기능이 포함되어 있지 않기 때문에 소스 문자열을 수정할 수 없습니다. 대신 소스 자체를 변경하고 파일을 다시 스캔해야 합니다. ( 팁: 번역 라인을 마우스 오른쪽 버튼으로 클릭하면 해당 문자열이 사용되는 라인과 소스 파일에 대한 힌트가 표시됩니다.)
복수형 문자열에는 두 개의 소스 문자열을 표시하는 두 개의 상자와 다른 최종 형식을 구성할 수 있는 탭이 포함됩니다.
Poedit의 복수형 문자열의 예, 각각에 대한 번역 탭이 표시됩니다.
소스 코드 파일을 변경하고 번역을 업데이트해야 할 때마다 새로 고침을 누르면 Poedit가 코드를 다시 스캔하여 존재하지 않는 항목을 제거하고 변경된 항목을 병합하고 새 항목을 추가합니다.
Poedit는 또한 사용자가 수행한 다른 번역을 기반으로 일부 번역을 추측하려고 할 수 있습니다. 이러한 추측과 변경된 항목은 검토가 필요함을 나타내는 "퍼지" 표시를 받게 되며 목록에서 노란색으로 표시됩니다.
번역 팀이 있고 누군가 확실하지 않은 내용을 작성하려고 하는 경우에도 유용합니다. 그냥 퍼지로 표시하면 다른 사람이 나중에 검토할 것입니다.
마지막으로 "보기 > 번역되지 않은 항목 먼저"를 표시한 상태로 두는 것이 항목을 잊어버리는 것을 방지하는 데 도움이 됩니다. 해당 메뉴에서 UI의 일부를 열어 필요한 경우 번역가에게 문맥 정보를 남길 수도 있습니다.
팁 & 트릭
웹 서버는 결국 .mo 파일을 캐싱할 수 있습니다.
Apache(mod_php)에서 PHP를 모듈로 실행하는 경우 캐시되는 .mo 파일에 문제가 발생할 수 있습니다. 처음 읽을 때 발생하고 업데이트하려면 서버를 다시 시작해야 할 수 있습니다.
Nginx 및 PHP5에서 번역 캐시를 새로 고치는 데 일반적으로 몇 번의 페이지 새로 고침이 필요하며 PHP7에서는 거의 필요하지 않습니다.
라이브러리는 현지화 코드를 짧게 유지하는 도우미 기능을 제공합니다.
많은 사람들이 선호하는 것처럼 gettext()
_()
를 사용하는 것이 더 쉽습니다. 프레임워크의 많은 사용자 지정 i18n 라이브러리도 t()
와 유사한 것을 사용하여 번역된 코드를 더 짧게 만듭니다. 그러나 그것은 바로 가기를 자랑하는 유일한 기능입니다.
프로젝트에 ngettext()
)용 __()
또는 _n()
또는 gettext()
및 sprintf()
호출을 결합하는 멋진 _r()
과 같은 다른 것을 추가할 수 있습니다. oscarotero의 Gettext와 같은 다른 라이브러리도 이와 같은 도우미 기능을 제공합니다.
이러한 경우 새 함수에서 문자열을 추출하는 방법에 대해 Gettext 유틸리티에 지시해야 합니다. 두려워하지 마십시오. 매우 쉽습니다. .po 파일의 필드 또는 Poedit의 설정 화면입니다(편집기에서 해당 옵션은 "카탈로그 > 속성 > 소스 키워드" 안에 있음).
기억하십시오: Gettext는 이미 많은 언어에 대한 기본 기능을 알고 있으므로 해당 목록이 비어 있는 것처럼 보이더라도 걱정하지 마십시오. 이 특정 형식에 따라 새 기능의 사양을 해당 목록에 포함해야 합니다.
단순히 문자열에 대한 번역을 반환하는
t()
와 같은 것을 생성하면 이를t
로 지정할 수 있습니다. Gettext는 유일한 함수 인수가 번역될 문자열임을 알게 됩니다.함수에 둘 이상의 인수가 있는 경우 첫 번째 문자열이 어느 것인지 지정할 수 있으며 필요한 경우 복수형도 지정할 수 있습니다. 예를 들어, 함수 서명이
__('one user', '%d users', $number)
인 경우 사양은__:1,2
가 됩니다. 즉, 첫 번째 형식은 첫 번째 인수이고 두 번째 형식은 두 번째 인수. 숫자가 대신 첫 번째 인수로 제공되는 경우 사양은__:2,3
이며 첫 번째 형식이 두 번째 인수임을 나타내는 식입니다.
.po 파일에 이러한 새 규칙을 포함하고 나면 새 스캔을 통해 이전처럼 쉽게 새 문자열을 가져올 수 있습니다.
Gettext로 PHP 앱을 다국어로 만드세요
Gettext는 PHP 프로젝트를 국제화하기 위한 매우 강력한 도구입니다. 많은 인간 언어를 지원할 수 있는 유연성 외에도 20개 이상의 프로그래밍 언어를 지원하므로 PHP와 함께 사용하는 지식을 Python, Java 또는 C#과 같은 다른 언어로 쉽게 이전할 수 있습니다.
또한 Poedit는 코드와 번역된 문자열 사이의 경로를 매끄럽게 하여 프로세스를 보다 간단하고 따르기 쉽게 만들 수 있습니다. 또한 Crowdin 통합을 통해 공유 번역 작업을 간소화할 수 있습니다.
가능하면 사용자가 말할 수 있는 다른 언어를 고려하십시오. 이것은 영어가 아닌 프로젝트에서 가장 중요합니다. 영어와 모국어로 릴리스하면 사용자 액세스를 높일 수 있습니다.
물론 모든 프로젝트에 국제화가 필요한 것은 아니지만 처음에는 필요하지 않더라도 프로젝트 초기에 i18n을 시작하는 것이 나중에 요구 사항이 될 경우 나중에 수행하는 것보다 훨씬 쉽습니다. 그리고 Gettext 및 Poedit와 같은 도구를 사용하면 그 어느 때보다 쉽습니다.