GettextTranslator a GettextExtractor

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
maarlin
Člen | 207
+
0
-

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
+
0
-

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');
}
?>
iguana007
Člen | 970
+
0
-

Pokud by si chtěl do template přeci jen vkládat texty, které se mají následně přeložit, tak syntaxe je následující:

{!_"Nějaký text k překladu"}

Pokud ti jde jen o ty flash messages, musíš je vychytat v php souborech pomocí _(), jak už psal BigCharlie.

BigCharlie
Člen | 283
+
0
-

Dík za doplnění, na to jsem úplně zapomněl :-)

maarlin
Člen | 207
+
0
-

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

  1. 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í?
  2. 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
+
0
-

nemáš zapnutou extension gettext, řekl bych

není, řekl bych, že je to obecný název pro nějaký ten translator ;)

  1. můžeš podědit AppForm, třeba na BaseForm, a tam si to nastavit, všechny formuláře pak tvoř jako new BaseForm();
  2. to nevím, bude to problém extractoru (zkus se podívat, zda li na to nemá nějaká nastavení)
maarlin
Člen | 207
+
0
-

readhead: Ano, bylo vypnutou gettext extension… :) Dík.

redhead
Člen | 1313
+
0
-

redhead, ne readhead ;)

maarlin
Člen | 207
+
0
-

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
+
0
-

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)

redhead
Člen | 1313
+
0
-

j, posílal sem to už tady:
https://forum.nette.org/…r-translator?…

Patrik Votoček
Člen | 2221
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

Není to Ajaxem, takto voláš nativní gettextovou extenzi. Použij:

$this->flashMessage($translator->translate('User exists'));
pekelnik
Člen | 462
+
0
-

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…