Extractie¶
Extractie is de stap die elk gemarkeerd bericht uit je broncode verzamelt in
een .pot-sjabloon voor vertalers — stap 3 van de lus uit de
tutorial. Deze pagina is de referentie voor die stap:
configuratie, eigen functienamen, strikte CI-modus, en de controles die je
catalogi daarna bewaken.
Extractie heeft de babel-extra nodig:
De workflow¶
Maak babel.cfg aan:
Gebruik vervolgens de gewone Babel-commando's:
pybabel extract -F babel.cfg -c "Translators:" -o locales/messages.pot .
pybabel init -i locales/messages.pot -d locales -l ja
pybabel compile -d locales
init draait één keer per taal; daarna vouwt pybabel update elk vers
sjabloon in de bestaande catalogi. Die terugkerende cyclus — en wat zijn
fuzzy-entries voor een release betekenen — wordt doorgelopen in
In productie.
De gettext_tstrings-extractor verwerkt ook gewone _()-, gettext()- en
ngettext()-aanroepen, zodat één mapping een gemengde codebase dekt. Hij
herkent _(), de vier standaard gettext-namen, de tr()- / ntr()-aliassen
en de uitgestelde lazy_gettext() / lazy_pgettext().
Zet vertalerscommentaren aan met -c
pybabel extract verzamelt vertalerscommentaren alleen wanneer je
-c "Translators:" meegeeft, precies zoals bij gewone gettext-aanroepen.
Laat je het weg, dan werkt de extractie nog steeds — de commentaren
bereiken de catalogus alleen nooit, waar ze
de goedkoopste kwaliteitshefboom
in de hele workflow zijn.
Je eigen functienamen registreren¶
Een ini-bestand geeft één string, een TOML-mapping geeft een lijst, en binnen een string scheiden witruimte of komma's de namen. Alle vier de spellingen werken.
De opties zijn tr_functions, ntr_functions, gettext_functions,
ngettext_functions, pgettext_functions en npgettext_functions.
-k bereikt een t-string niet
Een eigen helper zoals mytr(t"…") moet in een van de bovenstaande
opties worden benoemd. Babels --keyword-machinerie kan een
t-string-literal niet lezen, dus pybabel extract -k mytr vindt niets en
zegt niets — de berichten ontbreken simpelweg in de POT. -k blijft
werken voor de gewone gettext-aanroepen die ernaast worden geëxtraheerd.
Alleen de standaard argumentvolgorde wordt ondersteund: bericht eerst,
context dan bericht voor pgettext, context dan enkelvoud dan meervoud
voor npgettext.
Soepel lokaal, streng in CI¶
Standaard beëindigt één slecht bestand de run niet:
- Een t-string die de extractor afwijst — attribuuttoegang, een expressie, een verkeerd argument — wordt als waarschuwing gerapporteerd en overgeslagen.
- Een bestand dat niet parseert wordt op dezelfde manier overgeslagen.
- Net als een bestand dat alleen
tokenizeweigert terwijlasthet accepteert, waarop Babels eigen doorloop anders zou afbreken.
Dat is handig terwijl je aan het bewerken bent en gevaarlijk wanneer je dat
niet bent: een overgeslagen bericht is simpelweg afwezig uit de POT, dus
het wordt nooit vertaald en niets zegt dat. Zet strict = true in de
mapping-opties overal waar geen mens naar de extractie kijkt:
Elke waarschuwing hierboven wordt dan een harde fout. Behandel dit als de productie-instelling en de standaard als de lokale.
Je bestaande toolchain valideert deze catalogi¶
Babel markeert elk geëxtraheerd bericht met een standaardvlag, en die ene regel is wat placeholdercontrole activeert in de tools die je al draait:
Vertaal het als こんにちは {nombre} en de fout wordt zonder enige
configuratie gevangen:
$ msgfmt --check-format -o /dev/null locales/ja/LC_MESSAGES/messages.po
locales/ja/LC_MESSAGES/messages.po:25: a format specification for argument
'name' doesn't exist in 'msgstr'
msgfmt: found 1 fatal error
Weblate documenteert dezelfde controle als Python brace format, en de commerciële platforms hebben hun eigen placeholder-QA op dezelfde vlag. Het gedrag van elk platform is van henzelf; de twee tools hieronder zijn degene die hier geverifieerd zijn.
Daarbovenop registreert het pakket een Babel-checker, zodat
pybabel compile de regels van de specificatie toepast op elk bericht dat
het markeringscommentaar gettext-tstrings draagt:
$ pybabel compile -d locales -l ja
error: locales/ja/LC_MESSAGES/messages.po:24: translation does not match the
source placeholders: {name} is missing; {nombre} is not in the source message
1 errors encountered.
Voor een meervoudsbericht benoemt de aanwijzer de vorm, omdat het
regelnummer dat Babel rapporteert dat van de msgid is en een Russisch blok er
drie msgstr onder heeft staan:
error: locales/ru/LC_MESSAGES/messages.po:31: msgstr[1]: translation does not
match the source placeholders: {n} is missing
pybabel compile schrijft de .mo toch
De fout hierboven wordt gerapporteerd, de exitstatus is 1 — en de
kapotte catalogus wordt evengoed gecompileerd. Alleen die exitstatus kan
een pipeline tegenhouden hem uit te leveren;
Wat CI bewaakt toont de buildstap die dat
laat gebeuren.
De twee controles zijn niet redundant. De checker van het pakket is in minstens twee gevallen strikter:
- Een msgid waarvan de enige accolades geëscaped zijn (
Config {{raw}} only) krijgt nooit de vlagpython-brace-format, dus geen enkele externe tool valideert hem überhaupt. - Meervoudsvormen worden één voor één gecontroleerd.
msgfmt --check-formatleest precies dat bestand hierboven en eindigt met0; een vorm die een placeholder laat vallen die zijn broers behouden, wordt daar geaccepteerd en hier afgewezen.
msgfmt controleert alleen placeholdernamen die het als Python-brace-format
kan parseren, dus ASCII-namen houden elke tool in de keten in staat het
bericht te valideren. De bibliotheek zelf accepteert elke
str.isidentifier()-naam.
Sjablonen en andere tools¶
t-strings zijn Python-syntaxis, dus deze bibliotheek dekt Python-broncode.
Sjabloontalen blijven hun eigen i18n gebruiken — Jinja2's {% trans %},
Django's template-tags — en Babels extractors daarvoor. Alles voedt dezelfde
PO-catalogus, dus één vertaalworkflow dekt nog steeds een gemengde codebase.
pygettext kan vandaag geen t-strings parseren, en daarom loopt extractie
via Babel. De conventie is vastgelegd in de specificatie, zodat
een andere extractor, of een toekomstige pygettext, haar kan
implementeren.