Dvojitá alchymie VII - Neumí čésky

25. 10. 2013 20:44 Petr Blahoš

Podívejte se na všechny díly seriálu nebo na zdrojáky příkladu.

S lokalizací byl problém ve formencode, a stejný, jenom trochu větší problém je i ve formalchemy. Větší je proto, že formalchemy se používá i ke generování formulářů, zatímco formencode jen k validaci. Takže když nefunguje lokalizace s formencode, tak se nepřeloží chybové hlášky u špatně vyplněných polí, ale když nefunguje ve formalchemy, tak se buď nepřeloží ony, nebo se nepřeloží názvy tabulek a sloupců, věci v (mých) šablonách a tak.

Ve formencode jsem použil takovou tupou metodu, že jsem zkusil přeložit text pomocí formencode, a když se tím překladem nezměnil, tak jsem to zkusil přeložit v aplikaci. Tupé, pomalé, ale jelikož se v kontextu formencode překládalo strašně málo, tak mi to nevadilo. Tady to ale nechci.

formalchemy má jakousi podporu pro pyramid, ale není zrovna zdokumentovaná. Dokonce bych řekl, že se dost nepovedla. Když formalchemy detekuje, že je nainstalována pyramid (zkusí import), tak použije na request funkci get_localizer(request).translate, a tím dostane translator, tedy funkci, která provádí překlad v kontextu aplikace. To je sice vpořádku, ale dostali jsme se do stavu, kdy nepřeložíme texty, které jsou ve formalchemy (takže máme podobnou situaci, jako jsme měli ve formencode). Jakmile formalchemy získá translator, tak si ho schová do request.environ[„fa.translate“], a pak ho používá.

Takže když už si tu lokalizaci v aplikaci dělám, tak ve funkci faapp.locale.add_localizer, která se volá pro každý nový request a nastaví mu localizer, nastavím i request.environ[‚fa.translate‘] = auto_translate, a je to. Funkci, kterou jsem už měl připravenou jsem explicitně předhodil ještě formalchemy. Stále mi ale chybí překlad těch textů definovaných ve formalchemy. To je oříšek, protože buď se dostanu do stavu, že mám translator z formalchemy, a ten mi přeloží jen texty formalchemy (ale ne texty z mojí aplikace – jména tabulek a tak), nebo mám translator z aplikace, a ten mi přeloží jen texty z aplikace (ale ne texty z formalchemy – jako chyby validace).

Pyramid umožňuje přidat adresář, ze kterého se mají načíst překlady (mo soubory). To ale nestačí, protože budou v jiné doméně, než moje aplikace. Nakonec jsem nepřišel na nic lepšího, než si napsat svůj vlastní get_localizer a make_localizer, které jsou úplně stejné, jako ty v Pyramid, až na to, že když make_localizer nahrává překlady formalchemy, tak jim nastaví stejnou doménu, jako má moje aplikace:

                        domain = mofile[:-3]
                        if "formalchemy"==domain: domain = "faapp"

Nejsem nadšen, ale pro obranu tohoto hacku: nezesložitěla se tím ta funkce translate/_.

step11

Pro připomenutí: zdroják najdete na githubu, a návod k použití v prvním dílu. Formalchemy nemá české překlady, takže jestli je chcete, stáhněte si můj branch. Dál pak naše známé:

# nezapomeňte git pull
cd step11
python setup.py develop

pserve --reload development.ini

Nejprve se asi podívejte, co se děje v locale/__init__.py. Tam jsou ty „kopie“ funkcí get_localizer a make_localizer. Taky se v add_localizer nastavuje to

    request.environ['fa.translate'] = auto_translate

Dále si všimněte funkcí rendermodel/fieldsets.py a model/grids.py. V nich nastavím pár symbolů, které pak budou přímo dosažitelné v šablonách formalchemy, takže nebudu muset dělat

collection.active_request.resource_url(collection.active_request.context,
        urllib.urlencode(get_pk_map(row)))
${ collection.active_request.translate("Edit") }

ale bude stačit

request.resource_url(request.context, urllib.urlencode(get_pk_map(row)))
${ _("Edit") }

Dnes už toho bylo dost. Příště si řekneme, jak threadlocals pěkně pomohou tomu, že nerozumíme, co se v kódu děje, zkusíme si pluralizaci, a vyzkoušíme, že fungují překlady ve vlastním validátoru.

Sdílet