Podívejte se na všechny díly seriálu nebo na zdrojáky příkladu.
Všiml jsem si, že jsem si rozepsal díl 5, ale nikdy jsem ho nedopsal ani nepublikoval, takže tam máme díru. Měl být o lokalizaci. Třeba ho někdy napíšu, ale bude o něčem jiném.
Je to taková zajímavá věc. Když máme desktopovou aplikaci, lokalizovanou, tak někdy na začátku se nějak vybere jazyk, zaregistruje se funkce _(…), a je to. Naproti tomu, webová aplikace, která má navíc být vícejazyčná to má složitější. Tam prostě nejde mít globální _(…), protože tam žádné globální nastavení jazyka není – je nanejvýš per-request. To jsem si v Pylons 1 neuvědomoval, protože ty mi na to udělaly threadlocal _(…). To mi zjednodušilo volání _(…), ale skrylo to fakt, že takhle to prostě nefunguje. A jelikož mám rád, když vím, jak věci fungují, tak jsem se toho v Pyramid rád zbavil. Takže beru jako fakt, že ten překlad opravdu můžu udělat jen tam, kde mám request, a když ho nemám, tak mi tam utíká logika. Pokud vidíte v modelu volání _(…), tak kousek výš uvidíte definici
def _(s): return sTam se nic nepřekládá, ale označí se text, který pak gettext vytáhne do souboru pot. Zároveň mě nečeká žádné překvapení např. v testech. A teď už do práce.
# nezapomeňte git pull cd step12 python setup.py develop pserve --reload development.ini
Dnes si tam jenom přidáme podporu pro pluralizaci. Ač jsem dosáhl jistého věku, pluralizaci jsem zatím nikdy nepoužil. Snažil jsem se hledat nějaké konvence, ale na žádnou jsem nenarazil, možná proto, že pluralizace je tak málo častá, že se asi volá přímo funkce ngettext nebo ungettext. Pro ty, kdo neví nic: Např. v angličtině máme 2 formy, jednu pro jednotné číslo, druhou pro množné číslo. V češtině mám 3. Jednu pro 1, druhou pro 2, 3, 4, a třetí pro zbytek. Např.:
No a v kódu se to dělá tak, že napíšete:
ungettext("One tomato", "%d tomatoes", count)
Následně setup.py extract_messages a setup.py update_catalog vám vygeneruje v po souboru:
msgid "One tomato" msgid_plural "%d tomatoes" msgstr[0] "Jedno rajče" msgstr[1] "%d rajčata" msgstr[2] "%d rajčat"Zdalipak víte, proč to takhle nemůže fungovat?
Teď z jiného soudku. Ověříme si, že lokalizace funguje i ve validátorech, které jsme si nadefinovali v našem kódu. Uděláme si jednoduchý validátor, který ověří, že zadané číslo je sudé. V model/tools.py:
def even(value, field=None): """ A validator, successful if the value is even. """ value = integer(value, field) if value is None: return None if value % 2: try: _ = field.parent.active_request.translate except: _ = lambda x: x raise ValidationError(_('Value is not even')) return value
V model/fieldsets.py to použijeme:
class Person(FieldSet): def __init__(self, model, session=None, data=None, prefix=None, format=u'%(model)s-%(pk)s-%(name)s', request=None): super(Person, self).__init__(model, session, data, prefix, format, request) self.configure(options=[ self.number.validate(faapp.model.tools.even), ])Tady si také uvědomte, že není třeba nikde psát, že máme speciální FieldSet pro Person. To nám zařídí ty podpůrné funkce v model/resources.py.
A teď zpět k té pluralizaci. Ten překlad by se použil asi takto:
ungettext("One tomato", "%d tomatoes", count) % count
Z toho nám vypadne pro count=5:
"%d rajčat" % count
jenže pro count=1 dostaneme:
"Jedno rajče" % count
Takže v pluralizovaných textech musíme bezpodmínečně nutně dělat:
ungettext("One tomato", "%(COUNT)d tomatoes", count) ungettext("One tomato", "%(COUNT)d tomatoes", count) % { "COUNT": count }
Jmenuju se Petr Blahoš. Programuju něco přes 20 let. Tady se snažím psát hlavně o Pythonu, webovém frameworku Pyramid, a občas i o něčem úplně jiném.
Přečteno 19 224×
Přečteno 11 852×
Přečteno 9 344×
Přečteno 8 802×
Přečteno 8 592×