GettextTranslator a GettextExtractor
- maarlin
- Člen | 207
Stáhnul jsem si GettextExtractor od Karla na https://forum.nette.org/…extractor-v2 , v podstatě mi Extractor vygeneruje požadovaný *.po soubor, ovšem v tom souboru jsou jen překlady polí ve formulářích, překlady z phtml šablon se tam vůbec negenerují.
Moje integrace GettextTranslatoru vypadá následovně (záměrně jsem to dal do BasePresenteru, aby se automaticky používal překlad u všech presenterů):
<?php
abstract class BasePresenter extends NPresenter
{
public function beforeRender()
{
$this->template->setTranslator(new GettextTranslator('cs.mo', 'cs'));
?>
V @layout.phtml mám např. toto:
<h1>{_$title}</h1>
{foreach $flashes as $flash}<p class="flash-message {$flash->type}">{_$flash->message}</p>{/foreach}
Jak bych měl psát ty řetězce, aby Extractor to z toho mohl vytáhnout? Třeba flashMessages si dokáže sám všechny vygenerovat?
Navíc přesto, že už mám vygenerovaný cs.po přeložený a uložený do cs.mo, překlady se nijak neaplikují… Prostě se to nepřekládá…
- BigCharlie
- Člen | 283
Podle mých zkušeností to funguje trochu jinak. Pokud chceš překládat
řetězce, extractor projde příslušné soubory a hledá přeložitelné
řetězce, označené uzavřením do funkce _()
– z těch si
vytvoří seznam (říkejme tomu třeba index), podle kterého pak
překládá.
Při překladu pak translator narazí třeba na
_('Text k překladu')
, hledá tedy v indexu řetězec „Text
k překladu“. Když k němu najde překlad, vrátí překlad. V opačném
případě vrátí zpět ten samý řetězec.
Ty mu v uvedeném příkladu předhazuješ k překladu proměnou. Jenže v době, kdy extractor prochází ty soubory, aplikace neběží a v těch proměnných (tj. flash messages) nic není. Tak co se má vyextrahovat/přeložit?
Někde v kódu ale určitě máš kus, který ty zprávy plní – a tam je místo, kde to máš označit pro extractor:
<?php
public function someMethodOfPresenter() {
...
If (cosi) {
$this->flashMessages(_('Já jsem hláška k přeložení!')); // označení pro extractor
}
...
}
?>
Potom v šabloně nemusíš nic překládat, přijde do ní už přeložená zpráva. A pokud používáš formuláře, nezapomeň jim také přiřadit Translator.
Snad to pomůže. Pro přehled ještě to, co jsem použil já.
Nastavení extractoru:
<?php
$ge = new GettextExtractor();
$ge->filters['php'] = array('PHP');
$ge->filters['phtml'] = array('PHP', 'NetteCurlyBrackets');
?>
Nejprve jsem si vytvořil adresář pro vytvořený slovník:
app
locale
cs
LC_MESSAGES
messages.mo
messages.po
messages.pot
Soubory v něm jsou pro ukázku, ty jsem získal po vygenerování Karlovým Extractorem a překladu.
Translator aktivuju v metodě startup BasePresenteru:
<?php
public function startup() {
$this->template->setTranslator($this->getTranslator());
}
public function getTranslator() {
return new Translator($this->lang, APP_DIR . '/locale');
}
?>
- maarlin
- Člen | 207
Díky, už to téměř funguje jak jsem si představoval.
Resp. fungují ty řetězce definované v šablonách přes
{!_"Nějaký text k překladu"}
.
Nefungují mi ale ty interní překlady v PHP souborech přes
_('Něco k překladu')
, totiž Laděnka řve, že nezná
funkci _.
Jinak BigCharlie, ty ve svojí ukázce používáš třídu
Translator, to je nějaká součást Nette, nebo něco vlastního?
Osobně jedu přes ten GettextTranslator:
public function getTranslator() {
return new GettextTranslator(APP_DIR.'/languages/cs.mo', 'cs');
}
Ještě mě napadlo
- musím každému formuláři zvlášť nastavovat translator přes
$form->setTranslator();
, nebo to jde nějak udělat globálně pro všechny budoucí? - Jde nějak naopak vyřadit z překladů konkrétní default value jednoho
prvku? Totiž
$form['when']->setValue(date('j.n.Y'));
způsobí, že se mi v překladovém souboru objevíj.n.Y
… Asi je to fajn, když bych chtěl třeba pro EN_US jiný formát datumu, ale nechci…
- redhead
- Člen | 1313
nemáš zapnutou extension gettext, řekl bych
není, řekl bych, že je to obecný název pro nějaký ten translator ;)
- můžeš podědit AppForm, třeba na BaseForm, a tam si to nastavit, všechny formuláře pak tvoř jako new BaseForm();
- to nevím, bude to problém extractoru (zkus se podívat, zda li na to nemá nějaká nastavení)
- maarlin
- Člen | 207
Jo, redhead … nějak jsem se překlepnul… ne záměrně :)
Ještě se mi nedaří navěsit ten GettextTranslator na formuláře…
$form->setTranslator($this->getTranslator());
způsobí u každého pole ve formuláři toto:
Parse error: parse error in ...\libs\Nette\GettextTranslator\GettextTranslator.php(59) : eval()'d code on line 1
Notice: Undefined variable: plural in ...\libs\Nette\GettextTranslator\GettextTranslator.php on line 60
Notice: Undefined index: in ...\libs\Nette\GettextTranslator\GettextTranslator.php on line 208
Notice: Undefined index: in ...\libs\Nette\GettextTranslator\GettextTranslator.php on line 217
Je to chyba samotného GettextTranslatoru, nebo mojí integrace?
- maarlin
- Člen | 207
Nevím jak je to možné, ale když se metoda `translate `z `GettextTranslatoru `volá skrz ty formuláře, tak se volá s nulovým (NULL) druhým parametrem $count:
Vyřešil jsem to zkrátka takto:
if ($count < 1) {
$count = 1;
}
Předpokládám, že to je na skloňování slov dle počtu… 1 pes, 2–4
psi, 5> psů…
Ale žádného „psa“ většinou ošetřuji zvlášť, proto myslím že
nikdy nedojde k případu, kdy bych potřeboval použít $count = 0…
Editoval maarlin (7. 2. 2010 15:48)
- Patrik Votoček
- Člen | 2221
maarlin napsal(a):
Parse error: parse error in ...\libs\Nette\GettextTranslator\GettextTranslator.php(59) : eval()'d code on line 1 Notice: Undefined variable: plural in ...\libs\Nette\GettextTranslator\GettextTranslator.php on line 60 Notice: Undefined index: in ...\libs\Nette\GettextTranslator\GettextTranslator.php on line 208 Notice: Undefined index: in ...\libs\Nette\GettextTranslator\GettextTranslator.php on line 217
Máš starou verzi GettextTranslator-u a nové Nette… tady je novější verze: https://github.com/…t-translator
- BigCharlie
- Člen | 283
maarlin napsal(a):
Jinak BigCharlie, ty ve svojí ukázce používáš třídu Translator, to je nějaká součást Nette, nebo něco vlastního?
Napsal jsem si obecný translátor podle vzoru Karla Klímy a jsem s ním spokojen.
- sebastiano19
- Člen | 3
GettextTranslator preklada dobre, ale ked volam ajaxom funkciu kde pouzivam napr.:
<?php
$this->flashMessage(_('User exists'));
?>
tak sa to vobec neprelozi… ak sa to nevola ajaxom, tak vsetko preklada…
- romansklenar
- Člen | 655
Není to Ajaxem, takto voláš nativní gettextovou extenzi. Použij:
$this->flashMessage($translator->translate('User exists'));
- pekelnik
- Člen | 462
romansklenar napsal(a):
Není to Ajaxem, takto voláš nativní gettextovou extenzi. Použij:
$this->flashMessage($translator->translate('User exists'));
Tak tak :)
případně může tu nativní extenzi nastavit podobně jako nastavuješ translator a bude to fungovat… já používám obé. Ve zdrojovém kódu _(‚…‘) a v šabloně translator…