Pāriet uz saturu

Pamācība

Šī lapa ved no tukša direktorija līdz programmai, kas sveicina japāņu valodā. Pieci soļi, pieredze ar gettext netiek prasīta, un katra komanda ir parādīta kopā ar izvadi, ko tā patiešām rada — tā ikvienā solī jūs zināt, vai esat uz pareizā ceļa.

Vajadzīgs Python 3.14 vai jaunāks, jo t-virknes ir jauna sintakse 3.14 versijā. Japāņu valoda ir šīs lapas piemēra mērķis, taču nekas no šīs izvēles nav atkarīgs. Lai lietotu citu valodu, 4. solī aizstājiet ja — šis lokāles kods ir vienīgais, kas to nosauc.

1. Instalēšana

python -m pip install "gettext-tstrings[babel]"

Papildinājums [babel] atnes Babel — rīku, kas 3. solī savāc jūsu ziņojumus kataloga failos. Tas ir izstrādes laika rīks: produkcijas kods renderē ar standarta bibliotēku vien.

2. Atzīmējiet ziņojumu savā kodā

Izveidojiet app.py:

from gettext_tstrings import tr

name = "Ada"
print(tr(t"Hello {name}"))

t"Hello {name}" izskatās pēc f-virknes, bet prefikss t tur tekstu un vērtību atsevišķi, nevis saplūdina tos uz vietas. Tieši šis dalījums ļauj tr() atrast tulkojumu visam teikumam Hello {name} un ielikt vērtību pēc tam.

Palaidiet to tagad:

$ python app.py
Hello Ada

Tulkojumi vēl nav uzstādīti, tāpēc avota teksts tiek renderēts tāds, kāds tas ir. Programmai, kas lieto šo bibliotēku, katalogs nekad nav obligāts, lai tā darbotos — angļu valoda (vai kāda cita ir jūsu avota valoda) ir iebūvētā atkāpšanās.

3. Ekstrahējiet ziņojumus

Tulkotāji parasti strādā ar katalogiem, nevis ar pirmkodu, tāpēc starp jums un viņiem ceļo neliels fails, ko sauc par katalogu. Pirmais solis ceļā uz to ir savākt no koda katru atzīmēto ziņojumu.

Pastāstiet Babel, kur meklēt jūsu ziņojumus, izveidojot babel.cfg:

[gettext_tstrings: **.py]
encoding = utf-8

Tad ekstrahējiet tos veidnes failā (.pot):

$ mkdir -p locales
$ pybabel extract -F babel.cfg -c "Translators:" -o locales/messages.pot .
extracting messages from app.py (encoding="utf-8")
writing PO template file to locales/messages.pot

locales/messages.pot tagad satur vienu ierakstu katram ziņojumam:

#. gettext-tstrings
#: app.py:4
#, python-brace-format
msgid "Hello {name}"
msgstr ""

msgid ir atslēga, ko jūsu kods meklēs. Tukšais msgstr ir vieta, kur nonāk tulkojums — bet ne šajā failā: .pot ir veidne, un nākamais solis to nokopē pa vienai reizei katrai valodai.

4. Iztulkojiet un kompilējiet

Izveidojiet japāņu katalogu no veidnes:

$ pybabel init -i locales/messages.pot -d locales -l ja
creating catalog locales/ja/LC_MESSAGES/messages.po based on locales/messages.pot

Atveriet locales/ja/LC_MESSAGES/messages.po un aizpildiet msgstr:

msgid "Hello {name}"
msgstr "こんにちは {name}"

Paturiet {name} tieši tādu, kāds tas ir — vietturis ir veids, kā vērtība atrod savu vietu iztulkotajā teikumā, un tulkojums to drīkst pārvietot turp, kur to prasa mērķa valoda. Īstā projektā tieši šo .po failu jūs nododat tulkotājam vai augšupielādējat tulkošanas platformā; formāts abos gadījumos ir viens un tas pats.

Katalogus rediģē kā tekstu, bet ielādē binārā formā (.mo), tāpēc kompilējiet:

$ pybabel compile -d locales
compiling catalog locales/ja/LC_MESSAGES/messages.po to locales/ja/LC_MESSAGES/messages.mo

Šī komanda ir arī drošības tīkls. Ja tulkojums būtu sabojājis vietturi — teiksim, {nome}, nevis {name} —, tā atteiktos to izlaist cauri:

$ pybabel compile -d locales
error: locales/ja/LC_MESSAGES/messages.po:24: translation does not match the
source placeholders: {name} is missing; {nome} is not in the source message
1 errors encountered.

Viena atruna, ko vērts zināt jau tagad: tā ziņo par kļūdu un beidz darbu ar nenulles statusu, bet .mo tomēr uzraksta. Īstā projektā tieši CI ir tas, kam jāapstājas pie šī izejas statusa — Produkcijā to iestata.

5. Palaidiet to

2.–4. solī tika lietots tr(), kas meklē katalogu un neatrod nevienu. Tagad, kad tāds ir, ielādējiet to un piesaistiet vienu reizi: Translator tur katalogu, lai izsaukuma vietām tas nebūtu jānosauc, un _ ir ierastais gettext nosaukums rezultātam.

Pavērsiet app.py uz kompilēto katalogu. Uzklikšķiniet uz marķieriem, lai redzētu, ko dara katra rinda:

import gettext

from gettext_tstrings import Translator

_ = Translator(gettext.translation("messages", localedir="locales", languages=["ja"]))  # (1)!

name = "Ada"
print(_(t"Hello {name}"))  # (2)!
  1. Standarta bibliotēka ielādē kompilēto .mo, un Translator piesaista to izsaucamam objektam. _ ir ierastais gettext nosaukums nozīmei “iztulko šo” — īss tāpēc, ka tas parādās pie katras lietotājam redzamās virknes. Tā veic to pašu tulkošanu, ko tr, piesaistīta vienam katalogam.
  2. Izsaukuma brīdī: t-virknes teksts kļūst par meklēšanas atslēgu Hello {name}, katalogs atbild こんにちは {name}, atbilde tiek pārbaudīta pret avota vietturiem, un tikai tad tiek ielikta vērtība.
$ python app.py
こんにちは Ada

Tāds ir viss cikls, un to ir vērts ieraudzīt kā vienu attēlu:

flowchart LR
  mark["1.–2. atzīmēt<br>t-virknes kodā"] --> extract["3. ekstrahēt<br>messages.pot"]
  extract --> translate["4. iztulkot<br>ja/…/messages.po"]
  translate --> compile["4. kompilēt<br>ja/…/messages.mo"]
  compile --> run["5. palaist<br>こんにちは Ada"]

Atzīmēt → ekstrahēt → iztulkot → kompilēt → palaist. Viss pārējais šajā vietnē ir kāda no šiem pieciem soļiem pilnveidojums.

Kurp tālāk

  • Kāpēc t-virknes — no kā šis dizains jūs pasargā, salīdzinot ar %(name)s, .format() un $-virknēm.
  • Ceļvedis — daudzskaitļi, valodas katram pieprasījumam, atliktās virknes un tas, kas izpildlaikā notiek, ja katalogs tomēr ir kļūdains.
  • Produkcijā — tas pats cikls tā, kā to nedēļu pēc nedēļas izpilda komanda: katalogu atjaunināšana, CI vārti un tulkošanas platformas.
  • Ekstrakcija — pilnā pybabel uzziņa: pielāgoti funkciju nosaukumi, stingrais CI režīms un pārbaudes, kas sargā jūsu katalogus.
  • Migrācija — ja projektā, kurā jūs patiesībā gribat to darīt, jau ir gettext katalogi.
  • Tulkotājiem — vienīgā lapa, ko iedot tam, kurš aizpilda šīs msgstr rindas.