Migrace¶
Pokud váš projekt gettext už používá, jsou otázky, které rozhodují o tom, zda je tato knihovna přijatelná, poměrně úzké: znehodnotí katalogy, které máte, umí koexistovat s kódem, který zatím měnit nechcete, a jak velká část přesunu musí proběhnout naráz? Odpovědi, od nejkratší:
| Otázka | Odpověď |
|---|---|
Fungují stávající soubory .po a .mo dál? |
Ano. Tytéž soubory, tytéž nástroje. |
| Můžou stará a nová volání žít v jednom souboru? | Ano, a jedno mapování extraktoru pokryje obojí. |
| Změní se msgid? | Z .format() ne. Z %-formátu ano. |
| Musí se celý projekt přesunout naráz? | Ne. Jedno místo volání je platná změna. |
| A co Jinja, šablony Django, JavaScript? | Nedotčené, tytéž katalogy. |
Zbytek této stránky jsou podrobnosti ke každé z nich.
Z .format(): msgid se nemění¶
Tohle je případ, kdy migrace nestojí téměř nic. Zpráva psaná přes str.format
a zpráva z t-stringu odvozují týž klíč katalogu, protože klíčem je tak jako
tak text s ponechaným {name}:
# Before
_("Hello {name}").format(name=name)
# After — the msgid is still "Hello {name}"
tr(t"Hello {name}")
Stávající překlad tedy zůstane připojený. Vyjdeme-li z katalogu, který obsahuje
změňte volání, znovu extrahujte a aktualizujte:
$ 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
Záznam, který se vrátí, se liší ve dvou řádcích metadat a v ničem jiném — ve značkovacím komentáři, který jej označuje za zprávu z t-stringu, a v čísle řádku ve zdroji:
Žádný příznak fuzzy, žádné překládání znovu, v žádném jazyce. Zpráva se
vykreslí okamžitě:
$ 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 katalogy nahlásí jako zastaralé
Onen značkovací komentář a posunutá čísla řádků stačí na to, aby
pybabel update --check prohlásil katalog za potřebující přegenerovat —
porovnává totiž celý záznam, nejen překlad. Spusťte skutečný
pybabel update v témž commitu jako změnu kódu a katalogy s ní
commitněte; je to tentýž návyk, jaký si žádá už
brána v CI.
Z %-formátu: msgid se mění, takže překlady zfuzzyví¶
Syntaxe printf žije uvnitř zprávy, takže její nahrazení přepíše klíč
katalogu. Nedá se to obejít a je to poctivá cena za opuštění %(name)s:
pybabel update rozpozná v nové zprávě blízkou příbuznou té odstraněné a
starý překlad přenese, označený jako fuzzy:
#. gettext-tstrings
#: app.py:4
#, fuzzy, python-brace-format, python-format
msgid "Hello {name}"
msgstr "こんにちは %(name)s"
O tomto stavu je dobré vědět tři věci:
- Za běhu se nic nerozbije. Fuzzy záznamy jsou ze zkompilovaného
.movyloučené, takže aplikace vykresluje zdrojovou zprávu, dokud dvojici nepotvrdí člověk — tatáž degradace, jakou prochází každá přeformulovaná zpráva. - CI zůstává zelené, dokud jsou fuzzy. Checker zástupných symbolů fuzzy
záznamy přeskakuje, přesně jako to dělá
msgfmt --check-format, protože záznam, který se nemůže dostat do běhu, by neměl shazovat build. Jakmile překladatel příznak odstraní, kontroluje se záznam jako každý jiný — takže%(name)sponechané v potvrzeném překladu se odhalí právě tehdy, tedy ve chvíli, kdy by se jinak začalo vykreslovat. - Starý příznak
python-formatjede s sebou a měl by se smazat spolu s příznakemfuzzy, jinak budemsgfmt --check-formatdál uplatňovat pravidla printf na zprávu ve formátu brace.
U pojmenovaných zástupných symbolů printf je úprava mechanická — %(name)s
se stane {name} a nic jiného se nehýbe —, takže velký katalog znamená
skriptovaný průchod a po něm revizi překladatele, nikoli překlad znovu.
Poziční %s mechanické není: nemá jméno, které by se dalo přenést, a jeho
volba je právě podstatou té změny.
Migrace tedy může postupovat tempem, jaké dovolí revize: nepřevedený fuzzy záznam je viditelný kus práce v katalogu, ne rozbitý build.
Stará a nová volání koexistují¶
Extraktor, který čte t-stringy, čte i běžná volání gettextu, takže jedno mapování pokryje soubor uprostřed migrace:
from gettext_tstrings import tr
from myapp.i18n import _
name = "Ada"
print(_("Save changes"))
print(tr(t"Hello {name}"))
Obě zprávy skončí v téže šabloně a jen ta z t-stringu nese značkovací komentář, který zapíná kontroly navíc z této knihovny:
#: app.py:5
msgid "Save changes"
msgstr ""
#. gettext-tstrings
#: app.py:6
#, python-brace-format
msgid "Hello {name}"
msgstr ""
Rozpoznává _(), čtyři standardní gettextová jména, aliasy tr() / ntr()
a odložené lazy_gettext() / lazy_pgettext(). Vlastní pomocná funkce musí
být uvedena v mapování.
Za běhu jsou oba styly stejně nezávislé: gettext.translation() vrátí jeden
objekt s překlady a čtou z něj jak _, tak vstupní body této knihovny.
Co se nehýbe¶
- Šablonovací jazyky.
{% trans %}u Jinja2, šablonové tagy Django a jejich extraktory pro Babel fungují beze změny dál a dál plní tytéž katalogy PO. T-stringy jsou syntaxe Pythonu; platí pro pythonovské zdroje. - Vaše katalogové soubory. Žádná změna formátu, žádný nový soubor, žádný krok konverze.
- Vaše překladatelská platforma. Výměna přes
.poje identická a příznakpython-brace-format, který zpráva z t-stringu nese, je tentýž příznak, jaký nese zpráva z.format()— takže QA zástupných symbolů funguje dál. - Kód mimo Python. Katalog pro JavaScript nebo C v témž projektu zůstává nedotčen.
Kontrolní seznam migrace¶
- Přidejte extra
babeltam, kde běžípybabel, a vbabel.cfgzměňte mapovánípythonna metodugettext_tstrings— jedno mapování pak pokrývá oba styly a-ku běžných volání funguje dál. - Převeďte nejdřív místa volání s
.format(). Znovu extrahujte, spusťtepybabel updatea katalogy commitněte spolu s kódem; žádné fuzzy záznamy nečekejte. - Převádějte místa volání s
%-formátem po dávkách, které dokážete nechat zrevidovat, přepisujte přenesené zástupné symboly a mažte příznakyfuzzyapython-format. - Opravte to, co omezení odmítne: interpolace musí být prosté jméno, takže
z
t"Hello {user.name}"se nejdřív musí stát lokální proměnná. Je to úprava v místě volání, ne v katalogu. - Jakmile je průchod hotový, zapněte ve volbách mapování
strict = true, aby zpráva, kterou nelze extrahovat, shodila build, místo aby ze šablony zmizela. - Přidejte běhovou kontrolu z V produkci:
vykreslete jednu zprávu za každý dodávaný jazyk přes striktní
Translator.
Kroky 2 a 3 jsou obyčejné commity. Nic v tomto seznamu nepotřebuje den D.