Integrace Symfony translation do Nette – Kdyby/Translation

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

@martinit: Pokud do session nic neukládáš tak problém bude asi jinde. Ale něco se session to bude. Zkus si zapnout session debug panel a podívej se co tam je před a po redirectu.

nette:
	session:
		debugger: on

EDIT: Koukám že session panel obsahuje až Nette 2.1. Pro Nette 2.0 můžeš zkusit tohle: https://github.com/…ion-DebugBar (jen pozor abys nainstaloval správnou verzi – pro nette 2.0 je samostatná větev)

Editoval enumag (10. 12. 2013 20:36)

MartinitCZ
Člen | 580
+
0
-

@**enumag**: Už dlouho jedu na 2.1 ;) Jak už jsem psal zde ohledně redirectu .. Tak když kouknu na session v debugu, tak v obou případech vidím:

"Kdyby\Translation\LocaleResolver\SessionResolver" => array (1)
locale => "cs"

Když kliknu na en, tak tam bude en atd…

Ale zjistil jsem, že funkce $translator->getAvailableLocales()SessionResolver.php#L71 vrací vždy prázdný array a tim pádem to vždy vrátí NULL. Pokud zakomentuji řídek #73-#75, tak se změna jazyka provede.

Editoval martinit (10. 12. 2013 20:44)

Filip Procházka
Moderator | 4668
+
0
-

@martinit a nebude to tím že translator nenašel tvoje překlady? Jinak by to tím filtrem prošlo. Jen ještě upozorním, že nedávno byl přidán whitelisting (aby ta metoda správně fungovala i když si do aplikace dáte knihovnu co má resources i na jazyky co nepoužíváte).

MartinitCZ
Člen | 580
+
0
-

@**Filip Procházka**: Díky všem za pomoc. Sice jsem důvod chyby nenalezel, ale nové stažení z gitu + composer install to vyřešilo.

MartinitCZ
Člen | 580
+
0
-

@**Filip Procházka**: Bylo by možné do doc#pluralization přihodit informaci o rozdílnosti plurarizací?
Myslím tím toto:

cs:

days: den|dny|dnů

{_messages.days, 0} // dnů
{_messages.days, 1} // den
{_messages.days, 3} // dny
{_messages.days, 10} // dnů

en:

days: day|days

{_messages.days, 0} // days
{_messages.days, 1} // days
{_messages.days, 3} // days
{_messages.days, 10} // days

Jak vidíš, tak u en to stále vrací špatnou hodnotu a v baru mám days označen jako nepřeložený (ikdyž v souboru je).

Přijde mi, jak když to má alergii na slovo ‚days‘ jakmile ho změním např. na ‚deys‘, tak to funguje. :D

Editoval martinit (11. 12. 2013 13:15)

Filip Procházka
Moderator | 4668
+
0
-

@martinit já tam mám dost naivní způsob zjišťování, že se to přeložilo.

Založil jsem issue https://github.com/…on/issues/20

MartinitCZ
Člen | 580
+
0
-

@**Filip Procházka**: Super.

Našel jsem další bug :)

Config:
days: day|days

Šablona:
{_messages.days, 0} // days
{_messages.days, 1} // days
{_messages.days, 3} // days
{_messages.days, 10} // days

Když ale config upravim na toto:

Config:
days: day|deys // Typo

Šablona:
{_messages.days, 0} // deys
{_messages.days, 1} // day
{_messages.days, 3} // deys
{_messages.days, 10} // deys

Tak jak vidíš, překládá to v pořádků.

Problém je v tom, když se string pro překlad rovná jeho hodnotě.

car: car // nefunguje
car: car|cars // nefunguje
car: cer // OK
car: cer|cars // OK

Snad to nedělá jen mě a tobě to pomůže :)

Editoval martinit (11. 12. 2013 18:06)

thorewi
Člen | 84
+
0
-

@Filip Procházka: A jak vypadá https://github.com/…ion/issues/5 Bude z toho něco? :)

Editoval thorewi (17. 12. 2013 2:17)

fabian
Člen | 20
+
0
-

Ahoj,

pouzival jsem GettextTranslator, kde mi take vadily problemy, ktere nastanou, kdyz se v sablone zmeni text, ktery slouzi jako klic ve zdrojovem jazyce pro preklad.

Chci tedy prejit na Kdyby/Translation a v projektu to prekopavam. Dost me nebavi v kazde sablone psat porad dokola stejny prefix v klici prekladu:

<h1>{_messages.homepage.title}</h1>
<h2>{_messages.homepage.subtitle}</h2>
<p>{_messages.homepage.some_text}</p>

Porad se opakuje „messages.homepage.“, ktere je nutne vzdy napsat/okopirovat. Kdyz nahrazujete vsechny texty v projektu, neni to uplne prijemna prace.

Napadlo me, ze by se to dalo vyresit takhle:

{translatePrefix 'messages.homepage.'}
    <h1>{_title}</h1>
    <h2>{_subtitle}</h2>
    <p>{_some_text}</p>
{/translatePrefix}

Obnaselo by to malou upravu kdyby/Translation, kterou jsem poslal jako pull-request: https://github.com/…tion/pull/21

Co vy na to?

Eda
Backer | 220
+
0
-

fabian: Tohle je přesně jedna z věcí, kterou jsem chtěl nějak řešit, než přejdu na Kdyby\Translation úplně. Psát dokola ty prefixy je pro mne docela zásadní. A takto nějak jsem to chtěl řešit (to stejné jako u šablon platí také u formulářů). Byť souhlasím s připomínkami k implementaci, které u toho pullu ostatní mají. Nápad je to dobrý a už se těším, až se to v nějaké podobě dostane do repa, ať to nemusím řešit sám :-)

Editoval Eda (17. 12. 2013 17:44)

zool
Člen | 144
+
-1
-

Ahoj nedaří se mi ten translator nějak rozjet, stáhl jsem si odtud knihovnu https://github.com/…/Translation
ale chybí mi tam tento soubor Symfony\Component\Config\Resource\FileResource, který požaduje Kdyby\Translation\Loader\NeonFileLoader.php nevíte, kde jej sehnat?

akadlec
Člen | 1326
+
-1
-

@zool: A koukal si se jaké to má závislosti?

  • Nette Framework 2.0.x
  • Symfony Translation 2.2.x
  • Symfony Config 2.2.x
zool
Člen | 144
+
-1
-

Jak to myslíš? Používám nette 2.1.0 RC4

David Matějka
Moderator | 6445
+
-1
-

nainstaluj si to pomoci composeru.. treba tady najdes jak na to.. composer se ti pak postara o stazeni vsech potrebnych zavislosti

akadlec
Člen | 1326
+
-1
-

@zool: zřejmě ti chybí nějaké části Symphony. Buď si tam nahrej všechny knihovny a nebo lépe jak ti radí matej21 použij composer.

zool
Člen | 144
+
-1
-

Oki pokusím se ještě jsem s ním nepracoval, jen taková hloupá otázka, kam se píší ty příkazy „$ composer update“? Ve windows? Do cmd asi ne že?

Quinix
Člen | 108
+
-1
-

Ano, do cmd. Bez toho dolaru na začátku teda :-)

Editoval Quinix (19. 12. 2013 22:13)

zool
Člen | 144
+
-1
-

Tak to nějak nefunguje. V kořenovém adresáři mám composer.json v tom mám

{
	"require": {
    		"nette/nette": "@dev",
    		"kdyby/translation": "@dev"
	}
}

Dále tam mám složku vendor, po zadání příkazu composer update
se ve složce vendor vytvoří složky (vendor\symfony\filesystem\Symfony\Component\Filesystem\ ), které jsou prázdné. Dělám něco špatně?
Jo a napíše to chybu You must enable the openssl extension to download files via https

Editoval zool (19. 12. 2013 22:38)

zool
Člen | 144
+
-1
-

Tak jsem na to přišel, musel jsem v php.ini odkomentovat

extension=php_openssl.dll

akadlec
Člen | 1326
+
0
-

Další jeden dotaz. Je možné nějak řešit dvojjazyčnost jedné stránky? Standardně se stránka zobrazí třeba v EN (menu, komponenty, patička, atd.) ale pak mám v obsahu kus v jiném jazyce. Většina je toho řešena přes překlady v DB ale nádpisy bych potřeboval přes překladač. Takže kdyby se dalo nějak do $translator->tranlsate(‚string‘, ‚sk‘); zadefinovat jaký jazykový slovník použít?

Quinix
Člen | 108
+
0
-

Cílové locale (nebo jazyk) se dá definovat 5. parametrem metody translate.
https://github.com/…anslator.php#L104

MartinitCZ
Člen | 580
+
0
-

Filipe měl bych prosbu. Šlo by nějak pořešit to, že translator chce překládat i hodnoty ze selecboxu? Vypnout, zrušit, zakázat ..... ;)

David Matějka
Moderator | 6445
+
0
-

tohle translator neresi a nevyresi. ale melo by jit vypnout translator na konkretnim controlu:

$form->addSelect(...)->setTranslator(NULL);
MartinitCZ
Člen | 580
+
0
-

@**matej21**: To ale zakáže překlad i labelu.

David Matějka
Moderator | 6445
+
0
-

@martinit: vim, muzes ho ale porad prelozit manualne (respektive nastavovat rovnou prelozenej).. mozna by se hodil PR na vypnuti prekladu v select boxu

zool
Člen | 144
+
0
-

Ahoj, podařilo se mi to nějak rozjet, ale mám menší problém.

když napíšu v presenteru

echo $this->translator->translate('messages.homepage.hello');

tak se to přeloží, ale když to takhle zapíšu do šablony
{_messages.homepage.hello}
tak to vypise messageshomepagehello . A nevím kde může být problém.
Do createtemplate jsem zapsal

$template->registerHelperLoader([$this->translator->createTemplateHelpers(), 'loader']);

a do configu
latte:
macros:
- Kdyby\Translation\Latte\TranslateMacros::install

A pořád nejde. Nevíte kde může být problém??

Filip Procházka
Moderator | 4668
+
0
-

A máš načtené nějaké slovníky do translatoru? Poznáš to tak, že v panelu máš tu tvoji zprávu jako nepřeloženou.

zool
Člen | 144
+
0
-

No v panelu mám ten červený slovník s en (mám tam ted ang) a píše to tam

Missing translations: 1
Message
messageshomepagehello

Filip Procházka
Moderator | 4668
+
0
-

„Missing translations“ znamená nepřeloženo, takže nemáš načtené/vytvořené slovníky.

Přečti si prosím ještě jednou (nebo klidně 10×) dokumentaci doplňku a když ti to ani pak nebude fungovat tak se můžeš zeptat znovu a konkrétně.

zool
Člen | 144
+
0
-

No já nevím, ale v té dokumentaci, jsem o slovnících nic nenašel (možná jsem to jen nevidím). Co se tam píše, je aby to fungovalo v šablonách, tak se musí zaregistrovat makro (to jsem udělal), a zaregistrovat helper, to tam taky mám.
Jak tedy prosím načtu ty slovníky?

Editoval zool (16. 1. 2014 6:11)

Tomáš Votruba
Moderator | 1114
+
0
-

@zool: Kam se ukládají slovníky a jaký mají mít název je v dokumentaci zde

Filip Procházka
Moderator | 4668
+
0
-

Ono si to stačí přečíst od začátku do konce, zase tak dlouhé to není.

zool
Člen | 144
+
0
-

No ale já to tak mám
jsem psal, že když zadám v presenteru
echo $this->translator->translate(‚messages.homepage.hello‘);
Tak mi to vypíše Hello World(ale v šablonách mi to vypise messageshomepagehello). To znamená, že se načetl slovník messages.en_US.neon. Nebo se pletu?

Filip Procházka napsal(a):

Ono si to stačí přečíst od začátku do konce, zase tak dlouhé to není.

To máš pravdu, pročítám to pořád dokola, ale stále nevím proč to nejde.

Editoval zool (16. 1. 2014 16:33)

zool
Člen | 144
+
0
-

Tak už mi to jede, v dokumentaci je napsané, že se to do šablon píše takto

<p>{_messages.homepage.hello}</p>

tímto způsobem to něšlo tak jsem do dal do uvozovek

<p>{_"messages.homepage.hello"}</p>

a už to jede. Tak díky za trpělivost. Ale na mou obranu ten slovník byl načtený.

Majkl578
Moderator | 1364
+
0
-

První způsob funguje samozřejmě také, mám tak udělanou celou aplikaci… :) Spíš jsi měl špatně něco jiného.

zool
Člen | 144
+
0
-

Zkusil jsem znovu odstranit ty uvozovky a nejde to, tak asi blbá karma :-), s uvozovkama mi to jeda, tak aspon tak.

Jelen
Člen | 18
+
0
-

Zdravim, díky za rozšíření.
Měl bych dotazy ohledně překladu formulářů:

  • Chápu dobře, že metoda $form->setTranslator() je u tohoto řešení minulostí? Má tedy překlad vypadat následovně?
protected function createComponentSignInForm()
{
	$form = new Form;
	// $form->setTranslator($this->translator);
	$form->addText('username', $this->translator->translate('messages.homepage.login'))
		->setRequired($this->translator->translate('messages.homepage.loginRequired'));

	$form->addPassword('password', $this->translator->translate('messages.homepage.password'))
		->setRequired($this->translator->translate('messages.homepage.passwordRequired'))
		->addRule(Form::RANGE, $this->translator->translate("messages.homepage.passwordRange"), array(6, NULL));

	$form->addSelect('select', $this->translator->translate('messages.homepage.select'), array('Jedna', 'Dvě', 'Tři'));

	$form->addCheckbox('remember', $this->translator->translate('messages.homepage.remember'));

	$form->addSubmit('send', $this->translator->translate('messages.homepage.loginButton'));

	// call method signInFormSucceeded() on success
	$form->onSuccess[] = $this->signInFormSucceeded;
	return $form;
}
  • Jak přeložím položky select boxu?
array(
	$this->translator->translate('messages.homepage.item1'),
	$this->translator->translate('messages.homepage.item2'),
	$this->translator->translate('messages.homepage.item3')
)

Je toto správný přístup? Zdá se mi to poněkdu kostrbaté…

A nakonec, jak to vypadá s #5?

Editoval Jelen (28. 1. 2014 17:37)

Majkl578
Moderator | 1364
+
0
-

Chápu dobře, že metoda $form->setTranslator() je u tohoto řešení minulostí?

Funguje obojí, já naopak používám $form->setTranslator() a hlášky píšu ve formátu messages.*, tedy např. $form->addSubmit('send', 'messages.homepage.loginButton');.

Jak přeložím položky select boxu?

Při použití setTranslator se přeloží automaticky.

Filip Procházka
Moderator | 4668
+
0
-

Proč by to bylo řešení minulosti? Funguje to dobře, tak jak píše @Majk578. To co píšeš je potřeba udělat jenom když chceš překlad parametrizovat. Bohužel tohle Nette úplně dobře nemá podchycené, budu na to dělat RFC aby se to drobátko vylepšilo a pak to půjde čistě pomocí message ids ve formuláři.

Jelen
Člen | 18
+
0
-

Díky, to je přesně to co jsem potřeboval. Teď už jenom vygrepovat ty ‚překlady‘ -_-

Oggy
Člen | 306
+
0
-

Prvně chci zmínit, že je to skvělá implementace Translatoru.

Chtěl bych se zeptat, jak je rozpoznán defaultní jazyk? Mám překlad v šabloně Error presenteru. Text se vždy překládá do druhého jazyka, přestože defaultně je nastaven jiný jazyk. Nejsem si jist, zda jde vůbec předávat Error presenteru jazykovou mutaci ..

config.neon

nette:
	application:
		catchExceptions: true
		errorPresenter: Front:Error
		mapping:
			*: App\*Module\*Presenter

extensions:
	translation: Kdyby\Translation\DI\TranslationExtension

translation:
	default: en
	fallback: [en_GB, en]

Jak vlastně defaultní jazyk a fallback funguje?

Filip Procházka
Moderator | 4668
+
0
-

Jazyk rozpoznává systém resolverů, které se řadí do řetězu a postupně volají.

  • nejvyšší prioritu má SessionResolver pomocí kterého můžeš vynutit jazyk pro uživatele (například tlačítkem s vlaječkou kterou si uživatel vynutí že chce jiný jazyk).
  • po něm je LocaleParamResolver, který kouká na Request co zpracoval router.
  • AcceptHeaderResolver kouká na http hlavičky co posílá browser
  • poslední je DefaultLocale, který je předpokládám jasný

Když si to tak projdu od začátku do konce, vypadá to že tvůj prohlížeč posílá http hlavičky s češtinou (tím druhým jazykem).

Oggy
Člen | 306
+
0
-

Díky, paráda.

Takže nejlepší cesta jak si jazyk rozpoznaný AcceptHeaderResolverem uložit do persistentního parametru k tvorbě odkazů bude asi tato?

<?php
class ErrorPresenter extends \App\ErrorPresenter
{
	public function startup() {
		parent::startup();

		$this->locale = $this->translator->getLocale();
	}
}
?>

Samozřejmě předek má definovaný persistentní parametr locale.

Filip Procházka
Moderator | 4668
+
0
-

Ono by to mělo být spíš naopak, nevím jestli je dobrý nápad nechat si resolvovat jazyk a pak ho nastavovat do parametru ze kterého se to mělo resolvovat :) Ale pokud to funguje… :)

Jelen
Člen | 18
+
0
-

Jde nějakým způsobem přeložit v javascriptu např.:

console.log(this.error);

Používám uploader který má svoje hlášky, když je přepíšu stylem text.fileupload.tooBig ap., tak je musím přeložit už na straně serveru, ne JS. Nepletuli se… čili nastavím tříde Uploader setTransaltor($this->translator) a pak už jen $this->translator->translate($this->error), ale tohle nefunguje, něco mi uniká..?

akadlec
Člen | 1326
+
0
-

Zřejmě proto že JS je zpracován na straně klienta a PHP na straně serveru?

Jelen
Člen | 18
+
0
-

No pochopitelně. {_}this.error{/_} je blbost a this.error by díky $this->translator->translate($this->error) mělo již obsahovat přeloženou hlášku. Nicméně to zřejmě není všechno, co je třeba pro překlad udělat. Nemůžu říct, že jsi offtopic ale docela bez předmětné…

Editoval Jelen (19. 2. 2014 23:28)

Tomáš Votruba
Moderator | 1114
+
0
-

@Jelen: Zřejmě budeš opravdu potřeboval nějaký js translator

Jelen
Člen | 18
+
0
-

@Tomáš: tak toho jsem se bál nejvíc, ok dík. Ono by „stačilo“ nějaké makro co by dokázalo vypsat tu proměnou v JS a přeložit, ale netroufnu si říct na kolik to je realné a je-li to vůbec možné.

Editoval Jelen (20. 2. 2014 8:55)

Tomáš Votruba
Moderator | 1114
+
0
-

@Jelen: Pokud tu proměnnou můžeš ovlivnit pomocí php, tak to lze. Hodil by se konkrétní php kód.