Menerjemahkan perangkat lunak menggunakan GNU gettext

GNU gettext adalah salah satu alat yang paling banyak digunakan untuk internasionalisasi perangkat lunak bebas. Alat ini menyediakan cara yang sederhana namun fleksibel untuk melokalkan perangkat lunak. Alat ini sangat mendukung bentuk jamak, dapat menambahkan konteks lebih lanjut ke string yang diterjemahkan, dan terdapat banyak alat yang dikembangkan berdasarkan alat ini. Tentu saja, alat ini juga sangat mendukung Weblate (lihat deskripsi format berkas GNU gettext PO (Objek Portabel)).

Catatan

Jika Anda hendak menggunakannya pada perangkat lunak berpemilik, silakan konsultasikan terlebih dahulu perizinannya, mungkin tidak cocok untuk Anda.

GNU gettext dapat digunakan dalam berbagai bahasa pemrograman (C, Python, PHP, Ruby, JavaScript, dan masih banyak lagi) dan biasanya kerangka kerja UI sudah mendukungnya. Penggunaan standarnya adalah melalui pemanggilan fungsi gettext(), yang sering kali diberi alias _() agar kode lebih sederhana dan mudah dibaca.

Selain itu, ia menyediakan panggilan pgettext() untuk memberikan konteks tambahan kepada penerjemah dan ngettext() yang dapat menangani jenis jamak sebagaimana yang didefinisikan untuk bahasa target.

Sebagai alat yang digunakan secara luas, ia memiliki banyak pembungkus yang membuat penggunaannya sangat sederhana, daripada memanggil gettext secara manual seperti yang dijelaskan di bawah, Anda mungkin ingin mencoba salah satunya, misalnya intltool.

Ikhtisar alur kerja

GNU gettext menggunakan beberapa berkas untuk mengelola lokalisasi:

  • PACKAGE.pot berisi string yang diekstrak dari kode sumber Anda, biasanya menggunakan xgettext atau beberapa pembungkus tingkat tinggi seperti intltool.

  • LANGUAGE.po berisi string dengan terjemahan ke satu bahasa. Itu harus diperbarui oleh msgmerge setelah PACKAGE.pot diperbarui. Anda dapat membuat berkas bahasa baru menggunakan msginit atau di dalam Weblate.

  • LANGUAGE.mo berisi representasi biner dari LANGUAGE.po dan digunakan pada waktu eksekusi aplikasi. Biasanya tidak disimpan di bawah kendali versi, tetapi dihasilkan pada waktu kompilasi menggunakan msgfmt. Jika Anda ingin memilikinya di kontrol versi, Anda dapat membuatnya di Weblate menggunakan pengaya Hasilkan berkas MO.

Secara keseluruhan alur kerja GNU gettext terlihat seperti ini:

digraph translations { graph [fontname = "sans-serif", fontsize=10]; node [fontname = "sans-serif", fontsize=10, shape=note, margin=0.1, height=0]; edge [fontname = "monospace", fontsize=10]; "Source code" -> "PACKAGE.pot" [label=" xgettext "]; "PACKAGE.pot" -> "LANGUAGE.po" [label=" msgmerge "]; "LANGUAGE.po" -> "LANGUAGE.mo" [label=" msgfmt "]; }

Contoh program

Program sederhana dalam C menggunakan gettext mungkin terlihat seperti berikut:

#include <libintl.h>
#include <locale.h>
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    int count = 1;
    setlocale(LC_ALL, "");
    bindtextdomain("hello", "/usr/share/locale");
    textdomain("hello");
    printf(
        ngettext(
            "Orangutan has %d banana.\n",
            "Orangutan has %d bananas.\n",
            count
        ),
        count
    );
    printf("%s\n", gettext("Thank you for using Weblate."));
    exit(0);
}

Mengekstrak string yang dapat diterjemahkan

Setelah Anda memiliki kode yang menggunakan panggilan gettext, Anda dapat menggunakan xgettext untuk mengekstrak pesan darinya dan menyimpannya ke dalam .pot:

$ xgettext main.c -o po/hello.pot

Catatan

Ada program alternatif untuk mengekstrak string dari kode, misalnya pybabel.

Ini membuat berkas templat yang dapat Anda gunakan untuk memulai terjemahan baru (menggunakan msginit) atau memperbarui yang sudah ada setelah perubahan kode (Anda akan menggunakan msgmerge untuk itu). Berkas yang dihasilkan hanyalah berkas teks terstruktur:

# 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: 2015-10-23 11:02+0200\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"
"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"

#: main.c:14
#, c-format
msgid "Orangutan has %d banana.\n"
msgid_plural "Orangutan has %d bananas.\n"
msgstr[0] ""
msgstr[1] ""

#: main.c:20
msgid "Thank you for using Weblate."
msgstr ""

Setiap baris msgid mendefinisikan string untuk diterjemahkan, string kosong khusus di awal adalah kepala berkas yang berisi metadata tentang terjemahan.

Memulai terjemahan baru

Dengan templat yang ada, kita dapat memulai terjemahan pertama kita:

$ msginit -i po/hello.pot -l cs --no-translator -o po/cs.po
Created cs.po.

cs.po yang baru saja dibuat sudah memiliki beberapa informasi yang terisi. Yang terpenting, berkas ini memiliki definisi bentuk jamak yang tepat untuk bahasa yang dipilih dan Anda dapat melihat jumlah bentuk jamak yang telah berubah sesuai dengan definisi tersebut:

# Czech translations for PACKAGE package.
# Copyright (C) 2015 THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# Automatically generated, 2015.
#
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-10-23 11:02+0200\n"
"PO-Revision-Date: 2015-10-23 11:02+0200\n"
"Last-Translator: Automatically generated\n"
"Language-Team: none\n"
"Language: cs\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=ASCII\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"

#: main.c:14
#, c-format
msgid "Orangutan has %d banana.\n"
msgid_plural "Orangutan has %d bananas.\n"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""

#: main.c:20
msgid "Thank you for using Weblate."
msgstr ""

Berkas ini dikompilasikan menjadi bentuk biner yang dioptimalkan, berkas .mo yang digunakan oleh fungsi GNU gettext saat dijalankan.

Memperbarui string

Setelah Anda menambahkan lebih banyak string atau mengubah beberapa string dalam program Anda, Anda menjalankan lagi xgettext yang menghasilkan ulang berkas templat:

$ xgettext main.c -o po/hello.pot

Kemudian Anda dapat memperbarui berkas terjemahan individual agar sesuai dengan templat yang baru dibuat (ini termasuk menyusun ulang string agar sesuai dengan templat baru):

$ msgmerge --previous --update po/cs.po po/hello.pot

Catatan

Saat menggunakan Weblate, Anda biasanya tidak perlu menjalankan msgmerge secara manual. Weblate dapat menanganinya secara otomatis melalui pengaya Perbarui berkas PO agar sesuai dengan POT (msgmerge), atau Anda dapat mengunggah berkas POT yang telah diperbarui menggunakan metode unggah Perbarui string sumber. Lihat Memperbarui berkas bahasa target untuk rinciannya.

Mengimpor ke Weblate

Untuk mengimpor terjemahan tersebut ke Weblate, yang perlu Anda tentukan hanyalah kolom berikut saat membuat komponen (lihat Konfigurasi komponen untuk deskripsi kolom secara terperinci):

Kolom

Nilai

Repositori kode sumber

URL repositori VCS dengan proyek Anda

Mask berkas

po/*.po

Templat untuk terjemahan baru

po/hello.pot

Format berkas

Pilih Berkas PO gettext

Bahasa baru

Pilih Buat berkas bahasa baru

Dan selesai, Anda sekarang siap untuk mulai menerjemahkan perangkat lunak Anda!

Lihat juga

Anda dapat menemukan contoh gettext dengan banyak bahasa di proyek Weblate Hello di GitHub: <https://github.com/WeblateOrg/hello>.