gettext λ‘ κ΅μ ν(i18n)μ μ§μν(L10N) λ SW κ°λ°νκΈ°
SW λ μλΉμ€λ₯Ό κ°λ°νλ€λ³΄λ©΄ μ¬μ©μμ νκ²½μ λ°λΌ λ€λ₯Έ locale λ‘ μ²λ¦¬ν΄μΌ νλ νλ κ²½μ°κ° μκΈΈμ μμ΅λλ€.
Unix μ΄μ 체μ (Linux ν¬ν¨)λ μ΄λ° μꡬ μ¬νμ λ§μ‘±νκΈ° μν΄ μ΄λ―Έ μ€λμ λΆν° κ΅μ νμ μ§μν κΈ°λ₯μ μ§μνκ³ μμ΅λλ€.
μ΅κ·Όμλ Java λ₯Ό λ§μ΄ μ¬μ©νλ―λ‘ Java μ Resource bundle μ μ΄μ©νμ¬ λ©μμ§λ₯Ό λ²μνλ λ°©μμ μ°μ μ μΌλ‘ μκ°ν μ μμ§λ§ λ©μμ§ λ²μμ κ΅μ νλ SW μ μΌλΆμΌλΏ ν΅νλ μκ° νμ, μ«μ νκΈ° λ°©λ², λ¨μ/볡μ, λͺ μ¬μ μ±λ³λ± λ€μν νλͺ©μ κ³ λ €ν΄μΌ ν©λλ€.
gettext λ μ€λλ κΈ°μ μ΄μ§λ§ κ΅μ νμ μ§μνμ λν κ°λ μ μ΄ν΄νκ³ μ μ©νκΈ° μ’κ³ PHP λ Python λ±μμλ μ§μνλ―λ‘ λ°°μλλ©΄ μ μ©ν μ§μμΈλ° λ§μΉ¨ gettext λ₯Ό μ¬μ©νλ μμ£Ό μ€λλ μμ€ν μ μμ ν μΌμ΄ μ겨μ μ λ¦¬ν΄ λ΄ λλ€.
μ λͺ ν PHP CMSμΈ wordpress λ κ΅μ ν λΆλΆμ gettext λ‘ μ²λ¦¬νκ³ μμ΅λλ€.
gettext λ?
gettext λ Unix κ³μ΄ μ΄μ체μ μμ κ΅μ ν(Internalization; μ€μ¬μ i18n), μ§μν(Localization; μ€μ¬μ l10n) λ₯Ό μ§μνλ SW λ₯Ό λ§λ€κΈ° μν μμ€ν μΌλ‘ μ΄μ λ μ€λΌν΄μ μΈμλ Sun Micros ystems κ° κ°λ°νμ΅λλ€.
gettext λ λ²μκ³Ό νλ‘κ·Έλλ°μ λΆλ¦¬ν΄μ SW λ΄ λ©μμ§ λ²μμ μν΄ κ°λ°μκ° μμ€λ₯Ό μμ ν νμκ° μμΌλ©° λ²μμλ μμ€ μ½λκ° μμ΄λ λ©μμ§λ₯Ό λ²μν μ μμ΅λλ€.
gettext μ runtime library μ libintl μ΄λ©° python μ΄λ PHP μ¬μ©μλΒ libintl μ΄ νμν μΈλΆ ν¨ν€μ§λ₯Ό κ²½μ°λ₯Ό λ³Έ μ μ΄ μμκ²λλ€.
gettext μ μ λͺ ν ꡬνλ¬Όμ€ νλλ GNU gettext μ΄λ©° μ΄ λ¬Έμλ GNU gettext λ₯Ό κΈ°μ€μΌλ‘ μ€λͺ ν©λλ€.
life cycle
gettext λ₯Ό μ¬μ©ν΄μ κ΅μ ν/μ§μνλ₯Ό ꡬννλ work flow λ λ€μκ³Ό κ°μ΅λλ€.
1. λ¨Όμ μμ€ μ½λλ΄μ κ΅μ νκ° νμν λΆλΆμ gettext ν¨μλ‘ κ°μΈμ νμν΄ μ€λλ€.
#define THIS_PACKAGE_NAME "hello" char* locale_dir = "locale"; // locale νμΌμ μ½μ΄μ¬ λλ ν°λ¦¬ setlocale (LC_ALL, ""); // ν¨ν€μ§ μ΄λ¦. locale μ΄λ¦μ ν΄λ λ°μ hello.mo κ° μμ΄μΌ ν¨. bindtextdomain (THIS_PACKAGE_NAME, locale_dir); textdomain (THIS_PACKAGE_NAME); // λ²μλμ 보μ¬μ§ λΆλΆμ gettext λ‘ κ°μΈμ€ printf(gettext("My name is %s.\n"), my_name); // gettext λμ _ macro μ¬μ©ν΄λ λ¨. printf(_("my age is %d.\n"), my_age);
2. μμ€ μμ μ΄ λλ¬μΌλ©΄ μμ€μμ gettext λ‘ νμν λΆλΆμ μΆμΆν΄ μ£Όλ xgettext λ₯Ό μ΄μ©ν΄μ λ©μμ§λ₯Ό μΆμΆννμ μ μ₯ν©λλ€. μλλ μΆμΆν λ©μμ§ νμΌμ hello.pot λ‘ μ μ₯νλ μμ μ λλ€.
xgettext -c hello.c hello.h -o hello.pot
3. pot νμΌμ μλν°λ‘ μ΄μ΄λ³΄λ©΄ μλμ κ°μ΄ λ©ν μ λ³΄κ° μκ³ λ§μ§λ§μ msgid μ msgstr μ΄ λ³΄μΌκ²λλ€.
# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-09-29 22:23-0400\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" #: hello.c:18 #, c-format msgid "my name is %s.\n" msgstr ""
msgid κ° μμ€ μ½λμ μλ λ©μμ§μ΄κ³ msgstr μ λ²μν λ©μμ§μ λλ€.
4. msginit λͺ
λ Ήμ μ΄μ©ν΄μ λ²μν μΈμ΄μ locale μ λ§κ² λ©μμ§ μΉ΄νλ‘κ·Έ νμΌμ λ§λλλ€. λ©μμ§ μΉ΄νλ‘κ·Έλ .po νμ₯μλ₯Ό κ°μ§λ©° po λ Portable Object μ
λλ€.
po νμΌμ λ¬Έμμ΄λ‘ ꡬμ±λμ΄ μμ΄μ μ νΈνλ μλν°λ‘ μμ ν΄λ λμ§λ§ μλμμ μ€λͺ
ν μ λ¬Έ μλν°λ₯Ό μ¬μ©νλ κ² μ’μ΅λλ€.Β μλλ νκΈκ³Ό λ
μΌμ΄ λ‘μΊμ© po νμΌμ λ§λλ μμμ
λλ€.
$ msginit -i hello.pot -o ko.po -l ko_KR.utf8 $ msginit -i hello.pot -o de.po -l de_DE
-i : μ
λ ₯ μμ€λ₯Ό μ€μ ν©λλ€.
-o : μ μ₯ν po νμΌ λͺ
μ μ€μ νλ©° μΌλ°μ μΌλ‘ νμΌλͺ
μ LOCALE_NAME.po νμμΌλ‘ μ μ΄μ€λλ€.
-l : locale μ μ§μ ν©λλ€.
msginit λ₯Ό μ€ννλ©΄ μλμ κ°μ΄ μλ‘μ΄ λ©μμ§ μΉ΄νλ‘κ·Έμ λ£μ email μ£Όμλ₯Ό λ¬Όμ΄λ³΄λλ° νμΈνκ³ μν°λ₯Ό μΉλ©΄Β
The new message catalog should contain your email address, so that users can give you feedback about the translations, and so that maintainers can contact you in case of unexpected technical problems. Is the following your email address? lesstif@gmail.com Please confirm by pressing Return, or enter your email address.
5. μ΄μ Po Edit κ°μ λꡬλ₯Ό μ¬μ©ν΄μ locale λ³ νμΌ(μ: ko.po)μ μμ νκ³ μ μ₯ν΄ μ€λλ€.
6. .po μμ μ΄ λλ¬μΌλ©΄ μ΄μ mo(Machine Object) λ‘ μ»΄νμΌν΄μΌ gettext μμ run time μ locale λ³ μΈμ΄ νμΌμ λ‘λ©ν μ μμ΅λλ€. Po edit μ κ²½μ° νμΌ Β β "Moλ‘ μ»΄νμΌ" λ©λ΄μμ .mo νμΌλ‘ μ»΄νμΌν΄μ€λλ€.
리λ μ€ μ»€λ§¨λμμλ msgfmt λͺ λ ΉμΌλ‘ po λ₯Ό mo λ‘ μ»΄νμΌν μ μμ΅λλ€.
$ mkdir -p locale/ko/LC_MESSAGES/ $ msgfmt ko.po -o locale/ko/LC_MESSAGES/hello.mo
locale μ© λ°μ΄ν°κ° μ€ν νμΌ(hello)μ΄ μλ ν΄λμ νμμ locale/LOCALE/LOCALE_TYPE/ κ²½λ‘λ‘ μμ κ²½μ°μ λλ€.
μ΄μ locale μ λ³κ²½μμ΄ hello λ₯Ό μ€ννλ©΄ κΈ°λ³Έ μ€μ μΈ μμ΄λ‘ νμλ©λλ€.
$ ./hello john 50 my name is john. my age is 50.
μ λλ‘ λμνλμ§ νμΈνκΈ° μν΄ locale μ ko_KR λ‘ μ€μ νκ³ locale λͺ λ Ήμ΄λ‘ νμΈν΄ λ΄ λλ€.
$ export LANG=ko_KR $ locale LANG=ko_KR LC_CTYPE="ko_KR" LC_NUMERIC="ko_KR" LC_TIME="ko_KR" LC_COLLATE="ko_KR" LC_MONETARY="ko_KR" LC_MESSAGES="ko_KR" LC_PAPER="ko_KR" LC_NAME="ko_KR" LC_ADDRESS="ko_KR" LC_TELEPHONE="ko_KR" LC_MEASUREMENT="ko_KR" LC_IDENTIFICATION="ko_KR" LC_ALL=
λ€μ hello λ₯Ό μ€ννλ©΄ λ©μμ§κ° νκΈλ‘ νμλλ κ±Έ νμΈν μ μμ΅λλ€.
$ ./hello λ λ°© 50 λ΄ μ΄λ¦μ λ λ°©μ λλ€. λ΄ λμ΄λ 50μ λλ€.
C μΈμ΄ μμ
C λ‘ λ§λ gettext μ¬μ© μμ λ₯Ό https://github.com/lesstif/gettext-example μ μ¬λ €λ¨μΌλ μ°Έκ³ νμΈμ.
κ°μ΄ 보기
Ref
- Learning gettext tools for Internationalization (i18n) β The Phrase Blog β Software Localization Experts
- gettext β λ€κ΅μ΄ κ΅μ ν μλΉμ€ β Python 3.9.2 λ¬Έμ
- Supported Formats | Crowdin Documentation
- How to Translate Python Applications with the GNU gettext Module β The Phrase Blog β Software Localization Experts