Gettext na 100% v šablonách
- h4kuna
- Backer | 740
Aktuálnější dokumentace na githubu
Zdravím,
hrál jsem si překlady a taky jsem došel k gettext translatoru všiml jsem si že využívá gettext z minima vlasně vůbec jen binarni soubor který naparsuje a pak z něj udělá pole. Na jednu stranu je výhoda v tom že když jsem rozjížděl gettext tak jsem pravděpodobně zestárnul a toto to naprosto obchází takže jsem to zachoval ve svém kódu, Roman Sklenář to nemá na gitu, tak je to u mě.
Potřebujete:
- mít zapnutý gettext
- mít nainstalovanou podporu jazyka na servru $ locale -a
- všechno mít v UTF-8 (což 99,99% z vás bude mít)
- soubory ke stažení
- poedit
Pokud se nepodaří něco zajistit nezoufejte ještě je naděje, rozepíšu úplně dole.
Na gitu je ukázkový config.neon
definice jazyků, které chcete viz $ locale -a
parameters:
langs: {'cs' : 'cs_CZ.utf8', 'en' : 'en_US.utf8'}
Přetížení makra {_' ‚} a přidání dalšího, pro množné číslo {_n‘ '}
factories:
nette.latte:
factory: \h4kuna\GettextLatte::latte
Registrace samotného překladače
services:
translator:
class: \h4kuna\GettextLatte(%appDir%/../locale/, %langs%)
Soubory jsou uloženy v adresáři locale, kde musíte dodrže další adresářovou strukturu. Stejná adresářová struktura je také na githubu.
locale (volitelný název)
+ cs
+ LC_MESSAGES
+ messages.mo
+ jiný jazyk (klíč z pole %langs%)
+ LC_MESSAGES (adresář definovaný phpkem)
+ váš binární soubor messages.mo (název lze změnit, je to 4. parametr @translator)
Adresáře LC_MESSAGE vyžadují práva 777 bug
V tom nejhlavnějším startupu je potřeba spustit servisu a dát ji parametrem jazyk, pokud ho máte jako persistentní v presenteru, tak asi takto.
<?php
$this->context->translator->setLanguage($this->lang);
// Zase musí odpovídat jednomu z klíčů v poli %langs%.
?>
Mimo šablony používáte gettext tzn:
<?php
echo gettext('Hi'); //nebo alias _
echo _('Hi');
echo ngettext('dog', 'dogs', 2);
echo $this->context->translator->translate(gettext('%s possible %s %s'), 'dalsi', 'volitelne', 'parametry');
?>
Aplikaci by jste měli psát v angličtině/němčině, aby šlo dobře definovat skloňování. Pokud budete psát aplikaci v češtině, tak počítejte s tím že si budete muset udržovat slovník z češtiny do češtiny, ale stačí jen u frází, kde je potřeba skloňovat, já to tak dělám.
A v šablonách první parametry dělají to samé co originální funkce gettextu, ale tím to nekončí. Budu požívat vykřičníky, ale jde to i bez nich a určitě je vyhoďte pokud text bude od uživatele. Všechny řetězce pro nahrazení požívejte %s.
{!_'Hi'}
překlad
echo gettext('Hi');
nic zajmavýho, ale toto je killer
{!_'Today is %s', $date}
překlad
echo sprintf(gettext('Today is %s'), $date);
Počet parametů není omezený to samé je pro množné číslo, podpora plurálu je vyřešená.
{!_n'%s dog', $count}
překlad
echo sprintf(ngettext('%s dog', '%s dog', $count), $count);
{!_n'dog', $count}
překlad
echo ngettext('dog', 'dog', $count);
Pokud se v proměnné nachází abs příklad $absCount vygeneruje
echo sprintf(ngettext('%s dog', '%s dogs', abs($absCount)), $absCount); // když bude potřeba skloňovat i záporné hodnoty (°C)
sprintf se doplňuje pokud je opravdu potřeba. Konec nesmyslných helperů a nemusíte používat ITranslator ikdyž to mám implementované, ale opravdu není potřeba ho registrovat do formulářů nebo šablon. Skloňování se v šablonách nepíše, to si úkládejte vždy do slovníku, pak jej nebudete muset kopírovat.
Celé k nahlédnutí a ke stažení
Na gitu je adresář locale a v něm dva prázdné slovníky (*.po) připravené pro češtinu a angličtinu včetně správné adresářové struktury.
Než začnete prohledávát poeditem je potřeba mít vygenerované všechny
šablony ukázka jak toho docílit je v ukázkové
presenteru zkopírujte, upravte namespace a je potřeba docílit spuštění
actionTranslate.
Poeditem pak necháte prohledat adresáře
temp/cache/_Nette.FileTemplate a app
Restart serveru po aktualizaci katalogu není potřeba.
Nesplněné podmínky
Není podpora gettextu nainstalovaná
- nemělo by vadit je naimplementovaná podpora (testováno)
Nemohu zapnout požadovaný jazyk, server nevlastním.
- 3. parametr @translator nastavte na TRUE a pak je potřeba zaregistrovat si translator do formulářů
- tento stav silně nedoporučuji
Windows nepodporuje setlocale()
- ano, je to na to připravené (testováno)
Nemám UTF-8
- smůla nebo sáhnout do zdrojáku a upravit GettextLatte.php + katalogy
S chutí do toho.
Editoval h4kuna (14. 3. 2013 9:51)
- h4kuna
- Backer | 740
pekelnik napsal(a):
@h4kuna mas to pekne zpracovany :) o tom zadna…
Děkuji
Ja gettext nepouzivam. Vadi mi na nem 2 veci:
- poedit
- nutnost psat plural vsude kde ho chci pouzit – s preklady je prace i tak a tolik duplicit navic… :\
- poedit beru jako výhodu takové GUI nad xgettextem, vytáhnu si texty vrazím je někomu na zkontrolování a nemusí procházet aplikaci a najde překlepy
- plurál ano musíš a zase kolikrát ho použiješ? A kolikrát v aplikaci napíšeš například slovo email :)
Pak tu jsou výhody
- kešování binárního slovníku
- nativní php (rychlost)
Jak jsi psal s překládáním aplikace jsou celkem patálie, a každý způsob má své neduhy a tyto mi zatím příjdou přijatelné.
Editoval h4kuna (22. 11. 2012 21:33)
- h4kuna
- Backer | 740
pekelnik napsal(a):
@h4kuna mas to pekne zpracovany :) o tom zadna…
- nutnost psat plural vsude kde ho chci pouzit – s preklady je prace i tak a tolik duplicit navic… :\
Tak jsem zjistil že tento bod není úplně pravdivý, pomocí lehké kličky se nechá obejít a plurál používáš jednou z katalogu a pokud v něm budeš mít překlep upravuješ ho na jednom místě a projeví se všude. Bude-li zájem předvedu.
- Jan Tvrdík
- Nette guru | 2595
h4kuna wrote: u statických textů není potřeba escapovat.
Jak to? Co když se v překladu vyskytne třeba ampersand?
- h4kuna
- Backer | 740
pekelnik napsal(a):
Nikde neni napsano ze ty texty jsou bezpecne.
To vychází z toho, aby fungovalo čtení textů ze souborů pomocí poeditu tak texty musí být staticky.
{!_'Hi'}
se přeloží na
echo gettext('Hi');
Nejde udělat.
{!_$foo}
přeloženo na
echo gettext($foo);
Ono se to takto přeloží ale přestane ti fungovat vyhledávání textů poeditem.
Jediný kde escapování nechat je když nahrazuješ.
{_'Heslo bylo odesláno na váš email %s', $email}
Je to na uvážení programátora, ale asi máš pravdu v tom že to dramaticky výkon nemění a vede to k bad practice a v ukázce by takový věci na hraně ano nebo ne být neměli.
Jan Tvrdík napsal(a):
h4kuna wrote: u statických textů není potřeba escapovat.
Jak to? Co když se v překladu vyskytne třeba ampersand?
Máš pravdu, ale pořád je to na zodpovědnosti programátora. Jde o to že ty předem znáš co to bude za texty.
Editoval h4kuna (10. 2. 2013 9:02)
- Jan Tvrdík
- Nette guru | 2595
h4kuna wrote: Jde o to že ty předem znáš co to bude za texty.
Ale neznáš předem překlad. Ani {!_'Hi'}
není dobrý nápad.
Je to náchylné na to, že někdo (nemusí to být ani programátor) upraví
text a zapomene odstranit vykřičník. Prostě nedává smysl psát víc a
úmyslně si tak snížit bezpečnost aplikace.
- h4kuna
- Backer | 740
Jan Tvrdík napsal(a):
Ale neznáš předem překlad.
Zrovna u překladů čtené ze slovníku nevím jestli by měl někdo úmysl ohrozit aplikaci.
Je to náchylné na to, že někdo (nemusí to být ani programátor) upraví text a zapomene odstranit vykřičník.
Ok chápu, v dokumentaci jsem to upravil.
Btw: taky jsem přidal automatickou detekci jazyka při první návštěvě stránek.
- h4kuna
- Backer | 740
Překladač v praxi:
hajek-kaktusy.cz majitel pracuje s Poeditem a posílá nám zpátky přeložené *.po soubory.
Mám ještě další web, ale ten není ještě hotový.