Migráció¶
Ha a projekted már használ gettextet, szűk kérdések döntik el, bevezethető-e ez a könyvtár: érvényteleníti-e a meglévő katalógusaidat, megfér-e azzal a kóddal, amelyet még nem állsz készen megváltoztatni, és mennyinek kell az átállásból egyszerre megtörténnie. A válaszok, a legrövidebbel kezdve:
| Kérdés | Válasz |
|---|---|
Működnek még a meglévő .po és .mo fájlok? |
Igen. Ugyanazok a fájlok, ugyanazok az eszközök. |
| Megfér egy fájlban a régi és az új hívás? | Igen, és egyetlen kinyerő-leképezés lefedi mindkettőt. |
| Változik a msgid? | A .format() felől nem. A %-formázás felől igen. |
| Az egész projektnek egyszerre kell átállnia? | Nem. Egyetlen hívási hely is érvényes változtatás. |
| Mi lesz a Jinjával, a Django-sablonokkal, a JavaScripttel? | Érintetlenek, ugyanazok a katalógusok. |
Az oldal többi része a fentiek mindegyikének a részlete.
A .format() felől: a msgid nem változik¶
Ez az az eset, amelyben a migráció szinte semmibe nem kerül. Egy str.format
üzenet és egy t-string üzenet ugyanazt a katalóguskulcsot vezeti le, mert a
kulcs mindkét esetben az a szöveg, amelyben a {name} benne maradt:
# Before
_("Hello {name}").format(name=name)
# After — the msgid is still "Hello {name}"
tr(t"Hello {name}")
Így a meglévő fordítás a helyén marad. Indulj egy katalógusból, amely ezt tartalmazza:
módosítsd a hívást, nyerd ki újra, és frissíts:
$ 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
A visszakapott bejegyzés két metaadatsorban tér el, semmi másban — egy jelölő megjegyzésben, amely t-string üzenetként azonosítja, és egy forrássor számában:
Semmilyen fuzzy jelző, semmilyen újrafordítás, egyetlen nyelven sem. Az
üzenet azonnal megjelenik:
$ pybabel compile -d locales
compiling catalog locales/ja/LC_MESSAGES/messages.po to locales/ja/LC_MESSAGES/messages.mo
$ python app.py
こんにちは Ada
Az update --check elavultként fogja jelenteni a katalógusokat
Az a jelölő megjegyzés és az elmozdult sorszámok elegendők ahhoz, hogy a
pybabel update --check szerint egy katalógust újra kell generálni, mert
az egész bejegyzést hasonlítja össze, nem csak a fordítást. Futtasd le a
valódi pybabel update parancsot ugyanabban a commitban, amelyben a
kódváltozás van, és a katalógusokat is vele együtt commitold — ugyanaz a
szokás, amelyet a CI-kapu már amúgy is kér.
A %-formázás felől: a msgid változik, így a fordítások fuzzyk lesznek¶
A printf-szintaxis magán az üzeneten belül él, ezért a lecserélése átírja a
katalóguskulcsot. Ezt nem lehet megkerülni, és ez a %(name)s elhagyásának
őszinte ára:
A pybabel update felismeri, hogy az új üzenet közeli rokona az
eltávolítottnak, és átviszi a régi fordítást, fuzzyként megjelölve:
#. gettext-tstrings
#: app.py:4
#, fuzzy, python-brace-format, python-format
msgid "Hello {name}"
msgstr "こんにちは %(name)s"
Három dolgot érdemes tudni erről az állapotról:
- Futásidőben semmi nem romlik el. A fuzzy bejegyzések kimaradnak a
lefordított
.mofájlból, így az alkalmazás a forrásüzenetet rendereli, amíg egy ember meg nem erősíti a párosítást — ugyanaz a degradáció, amelyen minden átfogalmazott üzenet átmegy. - A CI zöld marad, amíg fuzzyk. A helyőrző-ellenőrző kihagyja a fuzzy
bejegyzéseket, pontosan úgy, ahogy a
msgfmt --check-formatteszi, mert az a bejegyzés, amely el sem juthat a futásidőig, ne buktasson el egy buildet. Abban a pillanatban, amikor egy fordító leveszi a jelzőt, a bejegyzést a többivel egyformán ellenőrizzük — így a megerősített fordításban hagyott%(name)sakkor akad fenn, vagyis pontosan akkor, amikor egyébként megjelenni kezdene. - A régi
python-formatjelző is átjön, és afuzzyjelzővel együtt törölni kell, különben amsgfmt --check-formattovábbra is printf-szabályokat alkalmaz egy brace-formátumú üzenetre.
A nevesített printf-helyőrzőknél a szerkesztés gépies — a %(name)s helyére
{name} kerül, és semmi más nem mozdul —, tehát egy nagy katalógus
szkriptelt átfutás plusz egy fordítói átnézés, nem pedig újrafordítás. A
pozicionális %s viszont nem gépies: nincs neve, amit át lehetne vinni, a név
megválasztása pedig épp a változtatás lényege.
A migráció tehát abban a tempóban haladhat, amelyet az átnézés megenged: egy át nem alakított fuzzy bejegyzés látható munkadarab a katalógusban, nem pedig elromlott build.
A régi és az új hívások megférnek egymással¶
Az a kinyerő, amely a t-stringeket olvassa, a szokásos gettext-hívásokat is olvassa, így egyetlen leképezés lefed egy migráció közepén lévő fájlt:
from gettext_tstrings import tr
from myapp.i18n import _
name = "Ada"
print(_("Save changes"))
print(tr(t"Hello {name}"))
Mindkét üzenet ugyanabba a sablonba kerül, és csak a t-stringes viseli azt a jelölő megjegyzést, amely bekapcsolja ennek a könyvtárnak a többletellenőrzését:
#: app.py:5
msgid "Save changes"
msgstr ""
#. gettext-tstrings
#: app.py:6
#, python-brace-format
msgid "Hello {name}"
msgstr ""
Felismeri a _() hívást, a négy szabványos gettext-nevet, a tr() / ntr()
aliasokat, valamint a késleltetett lazy_gettext() / lazy_pgettext()
hívásokat. A saját segédfüggvényedet
meg kell nevezni a leképezésben.
Futásidőben a két stílus ugyanennyire független egymástól: a
gettext.translation() egyetlen fordításobjektumot ad vissza, és a _
éppúgy, mint ennek a könyvtárnak a belépési pontjai, abból olvasnak.
Ami nem mozdul¶
- Sablonnyelvek. A Jinja2
{% trans %}szerkezete, a Django sabloncímkéi és a hozzájuk tartozó Babel-kinyerők változtatás nélkül működnek tovább, és ugyanazokat a PO-katalógusokat táplálják. A t-string Python-szintaxis; Python-forrásra vonatkozik. - A katalógusfájljaid. Nincs formátumváltás, nincs új fájl, nincs konverziós lépés.
- A fordítási platformod. A
.pocsereformátum azonos, és az apython-brace-formatjelző, amelyet egy t-string üzenet visel, ugyanaz a jelző, amelyet egy.format()üzenet visel — így a helyőrző-QA tovább működik. - A nem Python kód. Egy ugyanabban a projektben lévő JavaScript- vagy C-katalógust ez nem érint.
Migrációs ellenőrzőlista¶
- Add hozzá a
babelextrát ott, ahol apybabelfut, és állítsd át ababel.cfgpythonleképezését agettext_tstringsmetódusra — egyetlen leképezés ekkor mindkét stílust lefedi, a-kpedig továbbra is működik a szokásos hívásokra. - Először a
.format()hívási helyeket alakítsd át. Nyerd ki újra, futtasd apybabel updateparancsot, és a katalógusokat a kóddal együtt commitold; fuzzy bejegyzésre nem kell számítani. - A
%-formázású hívási helyeket olyan adagokban alakítsd át, amelyeket át tudsz nézetni: írd át az átvitt helyőrzőket, és töröld afuzzyés apython-formatjelzőt. - Javítsd ki, amit a megszorítás elutasít: egy interpolációnak puszta névnek
kell lennie, tehát a
t"Hello {user.name}"előbb lokális változó lesz. Ez hívási helyi szerkesztés, nem katalógusbeli. - Kapcsold be a
strict = truebeállítást a kinyerő-leképezésben, amint a átfutás kész, hogy a ki nem nyerhető üzenet inkább a buildet buktassa el, mintsem eltűnjön a sablonból. - Vedd fel az Éles üzemben oldalról a futásidejű
ellenőrzést: rendereld le nyelvenként egy üzenetet egy szigorú
Translator-on keresztül.
A 2. és a 3. lépés szokványos commit. Ebben a listában semmihez nem kell egyetlen nagy átállási nap.