Migrasi¶
Jika proyek Anda sudah memakai gettext, pertanyaan yang menentukan apakah pustaka ini layak diadopsi bersifat sempit: apakah ia membatalkan katalog yang sudah Anda punya, dapatkah ia berdampingan dengan kode yang belum siap Anda ubah, dan seberapa banyak perpindahannya harus terjadi sekaligus. Jawabannya, yang terpendek lebih dulu:
| Pertanyaan | Jawaban |
|---|---|
Apakah berkas .po dan .mo yang ada tetap berfungsi? |
Ya. Berkas yang sama, perkakas yang sama. |
| Bisakah panggilan lama dan baru hidup dalam satu berkas? | Bisa, dan satu pemetaan ekstraktor mencakup keduanya. |
| Apakah msgid-nya berubah? | Tidak, dari .format(). Ya, dari %-format. |
| Haruskah seluruh proyek berpindah sekaligus? | Tidak. Satu titik panggilan sudah merupakan perubahan yang sah. |
| Bagaimana dengan Jinja, templat Django, JavaScript? | Tak tersentuh, katalog yang sama. |
Sisa halaman ini adalah rinciannya, satu per satu.
Dari .format(): msgid-nya tidak berubah¶
Ini kasus di mana migrasinya nyaris tanpa biaya. Sebuah pesan str.format dan
sebuah pesan t-string menurunkan kunci katalog yang sama, karena kuncinya
adalah teksnya dengan {name} tetap berada di dalamnya, dengan cara mana pun:
# Before
_("Hello {name}").format(name=name)
# After — the msgid is still "Hello {name}"
tr(t"Hello {name}")
Jadi terjemahan yang ada tetap melekat. Berangkat dari katalog yang memuat
ubah panggilannya, ekstrak ulang, dan perbarui:
$ pybabel extract -F babel.cfg -o locales/messages.pot .
extracting messages from app.py (encoding="utf-8")
writing PO template file to locales/messages.pot
$ pybabel update -i locales/messages.pot -d locales
updating catalog locales/ja/LC_MESSAGES/messages.po based on locales/messages.pot
Entri yang kembali berbeda dalam dua baris metadata dan tidak lebih dari itu — sebuah komentar penanda yang mengidentifikasinya sebagai pesan t-string, dan sebuah nomor baris sumber:
Tanpa flag fuzzy, tanpa penerjemahan ulang, dalam bahasa mana pun. Pesannya
langsung dirender:
$ pybabel compile -d locales
compiling catalog locales/ja/LC_MESSAGES/messages.po to locales/ja/LC_MESSAGES/messages.mo
$ python app.py
こんにちは Ada
update --check akan melaporkan katalognya sudah kedaluwarsa
Komentar penanda itu dan nomor baris yang bergeser sudah cukup bagi
pybabel update --check untuk mengatakan sebuah katalog perlu dibuat
ulang, karena ia membandingkan seluruh entrinya dan bukan hanya
terjemahannya. Jalankan pybabel update yang sebenarnya dalam commit yang
sama dengan perubahan kodenya, dan commit katalognya bersama itu —
kebiasaan yang sama yang sudah diminta
gerbang CI.
Dari %-format: msgid-nya berubah, jadi terjemahannya menjadi fuzzy¶
Sintaks printf hidup di dalam pesannya, jadi menggantinya berarti menulis
ulang kunci katalognya. Tidak ada jalan memutar untuk itu, dan itulah biaya
jujur dari meninggalkan %(name)s:
pybabel update mengenali pesan baru itu sebagai kerabat dekat pesan yang
dihapus dan membawa terjemahan lamanya menyeberang, ditandai fuzzy:
#. gettext-tstrings
#: app.py:4
#, fuzzy, python-brace-format, python-format
msgid "Hello {name}"
msgstr "こんにちは %(name)s"
Tiga hal yang perlu diketahui tentang keadaan itu:
- Tidak ada yang rusak saat runtime. Entri fuzzy dikecualikan dari
.mohasil kompilasi, jadi aplikasi merender pesan sumbernya sampai seorang manusia mengonfirmasi pasangan itu — degradasi yang sama yang dilalui setiap pesan yang kata-katanya diubah. pybabel compilemelaporkan setiap entrinya, karena%(name)syang terbawa bukan placeholder brace yang valid, dan ia keluar dengan status bukan nol. Daftar itu adalah antrean kerja Anda, bukan alarm palsu; entri di dalamnya memang benar-benar perlu disunting.- Flag
python-formatlama ikut menumpang dan sebaiknya dihapus bersama flagfuzzy, ataumsgfmt --check-formatakan terus menerapkan aturan printf pada pesan brace-format.
Untuk placeholder printf bernama, suntingannya bersifat mekanis — %(name)s
menjadi {name} dan tidak ada lagi yang bergeser — sehingga katalog besar
berarti satu jalannya skrip diikuti tinjauan seorang penerjemah, alih-alih
penerjemahan ulang. %s posisional tidak mekanis: ia tidak punya nama untuk
dibawa menyeberang, dan memilih nama itulah inti perubahannya.
Karena itu, urutan praktisnya adalah memigrasikan pesan %-format secara
terencana — satu modul, satu rilis, satu bahasa pada satu waktu — alih-alih
dalam satu sapuan yang membuat setiap katalog merah sekaligus.
Panggilan lama dan baru berdampingan¶
Ekstraktor yang membaca t-string juga membaca panggilan gettext biasa, jadi satu pemetaan mencakup sebuah berkas yang sedang di tengah migrasi:
from gettext_tstrings import tr
from myapp.i18n import _
name = "Ada"
print(_("Save changes"))
print(tr(t"Hello {name}"))
Kedua pesan mendarat di templat yang sama, dan hanya yang t-string yang membawa komentar penanda yang menyalakan pemeriksaan ekstra pustaka ini:
#: app.py:5
msgid "Save changes"
msgstr ""
#. gettext-tstrings
#: app.py:6
#, python-brace-format
msgid "Hello {name}"
msgstr ""
Ia mengenali _(), keempat nama gettext standar, alias tr() / ntr(), serta
lazy_gettext() / lazy_pgettext() yang tertunda. Sebuah helper milik Anda
sendiri harus disebutkan di pemetaannya.
Saat runtime kedua gaya itu sama-sama mandiri: gettext.translation()
mengembalikan satu objek terjemahan, dan baik _ maupun titik masuk pustaka
ini membaca dari objek tersebut.
Apa yang tidak berpindah¶
- Bahasa templat.
{% trans %}milik Jinja2, tag templat Django, dan ekstraktor Babel mereka tetap bekerja tanpa perubahan dan tetap memasok katalog PO yang sama. t-string adalah sintaks Python; ia berlaku untuk kode sumber Python. - Berkas katalog Anda. Tanpa perubahan format, tanpa berkas baru, tanpa langkah konversi.
- Platform penerjemahan Anda. Pertukaran
.po-nya identik, dan flagpython-brace-formatyang dibawa pesan t-string adalah flag yang sama yang dibawa pesan.format()— jadi QA placeholder tetap berfungsi. - Kode non-Python. Katalog JavaScript atau C di proyek yang sama tidak terpengaruh.
Daftar periksa migrasi¶
- Tambahkan extra
babeldi tempatpybabelberjalan, dan ubah pemetaanpythondibabel.cfgmenjadi metodegettext_tstrings— satu pemetaan kemudian mencakup kedua gaya, dan-ktetap berfungsi untuk panggilan biasanya. - Konversikan titik panggilan
.format()lebih dulu. Ekstrak ulang, jalankanpybabel update, dan commit katalognya bersama kodenya; jangan harapkan ada entri fuzzy. - Konversikan titik panggilan
%-format dalam kelompok yang dapat Anda tinjaukan, sambil menulis ulang placeholder yang terbawa dan membersihkan flagfuzzysertapython-format. - Perbaiki apa yang ditolak pembatasannya: sebuah interpolasi harus berupa
nama polos, jadi
t"Hello {user.name}"menjadi variabel lokal lebih dulu. Ini suntingan di titik panggilan, bukan di katalog. - Nyalakan
strict = truedi pemetaan ekstraktor setelah sapuannya selesai, sehingga pesan yang tidak dapat diekstrak menggagalkan build-nya alih-alih lenyap dari templat. - Tambahkan pemeriksaan runtime dari Dalam produksi:
render satu pesan per bahasa yang dikirim melalui
Translatoryang strict.
Langkah 2 dan 3 adalah commit biasa. Tidak ada apa pun dalam daftar ini yang membutuhkan hari-H.