Integrace Symfony translation do Nette – Kdyby/Translation
- enumag
- Člen | 2118
@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
@**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()
v 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
@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
@**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
@**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
@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
@**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
@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
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
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
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?
- David Matějka
- Moderator | 6445
nainstaluj si to pomoci composeru.. treba tady najdes jak na to.. composer se ti pak postara o stazeni vsech potrebnych zavislosti
- zool
- Člen | 144
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)
- akadlec
- Člen | 1326
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
Cílové locale (nebo jazyk) se dá definovat 5. parametrem metody
translate.
https://github.com/…anslator.php#L104
- MartinitCZ
- Člen | 580
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
tohle translator neresi a nevyresi. ale melo by jit vypnout translator na konkretnim controlu:
$form->addSelect(...)->setTranslator(NULL);
- David Matějka
- Moderator | 6445
@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
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
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.
- Filip Procházka
- Moderator | 4668
„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ě 10x) dokumentaci doplňku a když ti to ani pak nebude fungovat tak se můžeš zeptat znovu a konkrétně.
- zool
- Člen | 144
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
@zool: Kam se ukládají slovníky a jaký mají mít název je v dokumentaci zde
- Filip Procházka
- Moderator | 4668
Ono si to stačí přečíst od začátku do konce, zase tak dlouhé to není.
- zool
- Člen | 144
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)
- Jelen
- Člen | 18
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
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
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.
- Oggy
- Člen | 306
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
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
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
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
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á..?
- Jelen
- Člen | 18
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
@Jelen: Pokud tu proměnnou můžeš ovlivnit pomocí php, tak to lze. Hodil by se konkrétní php kód.