SlideShare una empresa de Scribd logo
1 de 42
Descargar para leer sin conexión
Kdyby/Translation 
@ProchazkaFilip
Co si povíme? 
- Co to je 
- Něco si přeložíme 
- Typické úlohy s Nette 
- Co to neumí
Co je Kdyby/Translation? 
- LocalizationITranslator 
- Symfony/Translation 
Kdyby/Translation je implementací NetteLocalizationITranslator pro Nette, využívající Symfony/Translator, díky 
kterému má podporu pro spoustu super featur.
Jdeme překládat!
Instalace 
$ composer install kdyby/translation 
A do configu s tím! 
extensions: 
translation: KdybyTranslationDITranslationExtension 
Instalace je jako vždy primitívní, stačí použít composer a vložit extension do configu.
Základní nastavení 
translation: 
default: cs 
fallback: [cs_CZ, cs] 
$translator->getDefaultLocale() 
Základní nastavení jsou také jednoduchá. Je nutné nastavit pouze výchozí jazyk, který pak jde získat metodou 
getDefaultLocale(). Fallback umožňuje načíst překlady z “náhradního” slovníku - tedy například když není 
překlady dostupný v němčině a máte nastavený fallback na angličtinu, načte se z anglického slovníku.
Odkud se berou překlady 
- slovníky v aplikaci 
- neon 
- po / mo 
- xlf 
- csv 
- ts 
- ... 
Rozšíření umožňuje díky Symfony načítat slovníky v hromadě formátů, z nichž nejzajímavější jsou asi po/mo, díky 
kterým můžete translator použít jako drop-in replacement vašeho současného gettext translatoru. Kdyby pak 
přidává ještě navíc podporu pro neon slovníky.
Použití
Slovník v neonu 
app/locale/messages.cs_CZ.neon 
"Hello World": Ahoj světe! 
Vytvoříme si slovník ve formátu neon pro češtinu a do něj vložíme nějaký překlad.
Použití 
$translator->translate( 
'Hello World' 
); // Ahoj světe! 
Jednoduchým voláním pak překládáme.
“Lepší” slovník v neonu 
app/locale/front.cs_CZ.neon 
hello: 
world: Ahoj světe! 
A nebo si vytvoříme lepší slovník, kde nebudeme mít jako klíče stringy, ale identifikátory, které pak máme unikátní 
napříč aplikací. Je možné pak mít více slovníků, kde název souboru se bere vždy jako první část identifikátoru, 
což je v tomto případě slovo front.
Použití s identifikátory 
$translator->translate( 
'front.hello.world' 
); // Ahoj světe! 
Translatoru řekneme že chceme překládat nějaký identifikátor a on nám ho přeloží.
Plurály 
orderForm: 
useCredits: Použít %count% 
kredit|Použít %count% kredity|Použít 
%count% kreditů 
Díky Symfony má translator podporu pluralizačních pravidel pro 95 různých jazyku a sám ví, který z výrazů v 
překladu použít, pokud se mění počet v předmětu daného překladu.
Použití plurálů 
$translator->translate( 
'front.orderForm.useCredits', 
3 
); 
Tady translator sám pozná, že má vybrat druhý výraz a správně vrátí “Použít 3 kredity”.
Parametry 
something: Hello %name% 
Samozřejmostí je i podpora pro parametrizované překlady.
Použití parametrů 
$translator->translate( 
'front.something, 
['name' => 'Filip'] 
); 
Druhý argument metody translate() je volitelný.
Použití v šablonách 
{_front.orderForm.useCredits} 
{_front.orderForm.useCredits, 3} 
{_}front.hello.world{/_} 
{!_front.hello.world} 
Kdyby řeší i překlady v šablonách a přidává vlastní makra. Samozřejmostí je opět podpora plurálů a parametrů. 
Druhý argument s počtem je opět volitelný.
Jak nastavím jazyk? 
Kdyby obsahuje plně automatickou detekci jazyka, už žádné Environment::getService(translator) a setLocale() 
podle parametru v každém BasePresenteru. Při každém requestu se volají resolvery, které samy rozhodnou jaký 
jazyk použít.
Routování 
abstract class BasePresenter 
{ 
/** @persistent */ 
public $locale; 
První z resolverů vybírá jazyk podle parametrů AppRequest, který vytváří router. Pokud jej chcete využívat, je 
potřeba definovat persistentní parametr locale.
Routování 
new Route( 
'[<locale=cs cs|en>/]<presenter>/<action>', 
"Homepage:default" 
); 
Parametr je potřeba taky definovat v routeru na vhodném místě, aby se předával do requestu a translator si ho 
mohl načíst.
Accept-Language hlavička 
Accept-Language: 
cs,en;q=0.8,en-US;q=0.6 
Pokud translator není schopný si přečíst locale z AppRequest, tak zkouší zpracovat hlavičku s požadovaným 
jazykem, kterou posílá prohlížeč. Jazyk vybírá na základě dostupných slovníků s překlady.
Jazyk v session 
translation: 
resolvers: 
session: on 
Protože ukládat jazyk stránky do session není zrovna best practise, je potřeba toto chování explicitně zapnout.
Jazyk v session 
abstract class BasePresenter 
{ 
/** 
* @var SessionResolver 
* @inject 
*/ 
public $localeSession; 
Je potom možné si do presenteru injectnout třídu SessionResolver, kterou budeme potřebovat abychom do ní 
mohli nastavit jazyk, když si ho uživatel změní. Třída si ho pamatuje díky uložení do session.
Jazyk v session 
abstract class BasePresenter 
{ 
public function handleLanguage($locale) 
{ 
$this->localeSession 
->setLocale($locale); 
$this->redirect('this'); 
Jazyk je pak možné měnit například vlastním signálem.
Jazyk v session 
{link language!, cs} 
{link language!, en} 
Vygenerovat odkaz na signál s jazykem, který se má nastavit, je velice snadné.
Co ještě jde překládat?
Flash messages 
<div n:foreach='$flashes as $flash' 
n:class='flash, $flash->type'> 
{_$flash->message} 
</div> 
Nejsnadnější způsob jak překládat flash zprávy je použít makro na překlad v šabloně.
Formuláře 
$form->setTranslator( 
$translator 
); 
Překládat formuláře je také snadné, stačí jim předat translator. Nejlépe nějak globálně, pomocí DI Containeru.
Formuláře 
$form->addText( 
'name', 
'front.registrationForm.name' 
); 
Formulář pak své texty pro label nejprve předá translatoru, než je vykresluje. Samozřejmě je ale lepší vůbec 
titulek nenastavovat, vykreslovat formulář ručně a tedy mu i předat tento text k překladu až v šabloně.
Formuláře 
$form->setTranslator( 
$translator->domain( 
'front.registrationForm' 
) 
); 
Do formuláře si pomocí metody domain() můžu předat “prefixovaný translator”, což je šikovná zkratka, která vám 
umožní zbavit se opakování společné části identifikátoru v daném formuláři (nebo komponentě či konkrétní 
šabloně) a psát jen to co je v něm skutečně unikátní.
Formuláře 
$form->addText( 
'name', 
'name' 
); 
Jak je vidět, použití se drasticky zkrátilo.
Formuláře 
$control->setTranslator(NULL); 
Občas se hodí vypnutí překladů pro jeden konkrétní prvek, to jde udělat snadno jedním voláním. Je pak ale 
potřeba ručně přeložit například titulek prvku. Hodí se to když máme například dynamické hodnoty v selectu.
Parametry ve formulářích 
$form->addText( 
'name', 
new Phrase( 
'front.registrationForm.name', 
['name' => $name] 
Ve formulářích není prostor pro nějaké parametrizované překlady nebo plurály, zajímá ho prostě titulek pro label a 
jak mu ho předáte je mu jedno. Jenže tento titulek vždy předává translatoru. Je tedy možné využít objekt Phrase, 
který dokáže propašovat parametry i počet až do translatoru, kde se správně očasuje a přeloží.
Parametry ve validačních hláškách 
$control->addRule( 
Form::FILLED, 
new Phrase( 
'front.orderForm.useCredits', 
$credits = 10 
) 
Stejný fígl funguje i ve validačních pravidlech.
Jak získám seznam 
dostupných jazyků?
Whitelisting 
translation: 
whitelist: [cs, en, de] 
$translator->getAvailableLocales() 
Pokud máte univerzální komponenty typu Symfony/Validator, které přidávají překlady pro 25 různých jazyků, tak 
nechcete, aby translator procházel a zpracovával slovníky pro jazyky které nepoužíváte. Od toho je whitelist, který 
odfiltruje nepotřebné jazyky. Dostupné jazyky je pak možné získat metodou getAvailableLocales()
Co extrakce?
Extrakci umí, ale.. 
- latte je implementováno 
- PHP extraktor stále není 
- _() & __() jsou prasárny 
- Kdyby/Console command 
Kdyby/Translation obsahuje extractor ve formě Kdyby/Console commandu, který umí extrahovat Latte soubory. 
Neumí ovšem extrahovat přehlady z presenterů, komponent a dalších php souborů. Komunito, zapoj se prosím!
Co to neumí? 
A umět nikdy nebude, protože taková feature je prasárna?
Dotazy?
Díky za pozornost! 
filip-prochazka.com 
Follow me maybe? @ProchazkaFilip

Más contenido relacionado

Similar a Kdyby/Translation

Představení Ruby on Rails
Představení Ruby on RailsPředstavení Ruby on Rails
Představení Ruby on Railsigloonet
 
WP Frameworky - WordCamp Praha 2018
WP Frameworky - WordCamp Praha 2018WP Frameworky - WordCamp Praha 2018
WP Frameworky - WordCamp Praha 2018Brilo Team
 
Optimalizace Symfony na devu
 Optimalizace Symfony na devu Optimalizace Symfony na devu
Optimalizace Symfony na devuVašek Purchart
 
Vašek Purchart - Optimalizace Symfony na devu (2. sraz přátel Symfony v Praze)
Vašek Purchart - Optimalizace Symfony na devu (2. sraz přátel Symfony v Praze)Vašek Purchart - Optimalizace Symfony na devu (2. sraz přátel Symfony v Praze)
Vašek Purchart - Optimalizace Symfony na devu (2. sraz přátel Symfony v Praze)Péhápkaři
 
Využití chemie v procesu testování webových aplikací vytvořených pomocí techn...
Využití chemie v procesu testování webových aplikací vytvořených pomocí techn...Využití chemie v procesu testování webových aplikací vytvořených pomocí techn...
Využití chemie v procesu testování webových aplikací vytvořených pomocí techn...Michal Špaček
 
06 prez10(tvorba webu)
06 prez10(tvorba webu)06 prez10(tvorba webu)
06 prez10(tvorba webu)olc_user
 

Similar a Kdyby/Translation (6)

Představení Ruby on Rails
Představení Ruby on RailsPředstavení Ruby on Rails
Představení Ruby on Rails
 
WP Frameworky - WordCamp Praha 2018
WP Frameworky - WordCamp Praha 2018WP Frameworky - WordCamp Praha 2018
WP Frameworky - WordCamp Praha 2018
 
Optimalizace Symfony na devu
 Optimalizace Symfony na devu Optimalizace Symfony na devu
Optimalizace Symfony na devu
 
Vašek Purchart - Optimalizace Symfony na devu (2. sraz přátel Symfony v Praze)
Vašek Purchart - Optimalizace Symfony na devu (2. sraz přátel Symfony v Praze)Vašek Purchart - Optimalizace Symfony na devu (2. sraz přátel Symfony v Praze)
Vašek Purchart - Optimalizace Symfony na devu (2. sraz přátel Symfony v Praze)
 
Využití chemie v procesu testování webových aplikací vytvořených pomocí techn...
Využití chemie v procesu testování webových aplikací vytvořených pomocí techn...Využití chemie v procesu testování webových aplikací vytvořených pomocí techn...
Využití chemie v procesu testování webových aplikací vytvořených pomocí techn...
 
06 prez10(tvorba webu)
06 prez10(tvorba webu)06 prez10(tvorba webu)
06 prez10(tvorba webu)
 

Más de Filip Procházka

Před čím vás Nette ani Symfony neochrání
Před čím vás Nette ani Symfony neochráníPřed čím vás Nette ani Symfony neochrání
Před čím vás Nette ani Symfony neochráníFilip Procházka
 
Doctrine: co dělat, když entity nestačí
Doctrine: co dělat, když entity nestačíDoctrine: co dělat, když entity nestačí
Doctrine: co dělat, když entity nestačíFilip Procházka
 
Nejlepší cache je žádná cache
Nejlepší cache je žádná cacheNejlepší cache je žádná cache
Nejlepší cache je žádná cacheFilip Procházka
 
Nette framework - How to compile an extensible di container
Nette framework - How to compile an extensible di containerNette framework - How to compile an extensible di container
Nette framework - How to compile an extensible di containerFilip Procházka
 
Dependency injection v Nette 2.1 prakticky
Dependency injection v Nette 2.1 praktickyDependency injection v Nette 2.1 prakticky
Dependency injection v Nette 2.1 praktickyFilip Procházka
 
Usnadněte si soužití s Doctrine
Usnadněte si soužití s DoctrineUsnadněte si soužití s Doctrine
Usnadněte si soužití s DoctrineFilip Procházka
 

Más de Filip Procházka (14)

4 roky remote
4 roky remote4 roky remote
4 roky remote
 
Před čím vás Nette ani Symfony neochrání
Před čím vás Nette ani Symfony neochráníPřed čím vás Nette ani Symfony neochrání
Před čím vás Nette ani Symfony neochrání
 
Doctrine: co dělat, když entity nestačí
Doctrine: co dělat, když entity nestačíDoctrine: co dělat, když entity nestačí
Doctrine: co dělat, když entity nestačí
 
Nejlepší cache je žádná cache
Nejlepší cache je žádná cacheNejlepší cache je žádná cache
Nejlepší cache je žádná cache
 
Testování prakticky
Testování praktickyTestování prakticky
Testování prakticky
 
Doctrine ORM & model
Doctrine ORM & modelDoctrine ORM & model
Doctrine ORM & model
 
CQRS v rohlik.cz
CQRS v rohlik.czCQRS v rohlik.cz
CQRS v rohlik.cz
 
Nette framework - How to compile an extensible di container
Nette framework - How to compile an extensible di containerNette framework - How to compile an extensible di container
Nette framework - How to compile an extensible di container
 
Kdyby/Events #posobota
Kdyby/Events #posobotaKdyby/Events #posobota
Kdyby/Events #posobota
 
Kdyby/Events
Kdyby/EventsKdyby/Events
Kdyby/Events
 
Kdyby/Redis
Kdyby/RedisKdyby/Redis
Kdyby/Redis
 
Dependency injection v Nette 2.1 prakticky
Dependency injection v Nette 2.1 praktickyDependency injection v Nette 2.1 prakticky
Dependency injection v Nette 2.1 prakticky
 
Usnadněte si soužití s Doctrine
Usnadněte si soužití s DoctrineUsnadněte si soužití s Doctrine
Usnadněte si soužití s Doctrine
 
Composer / Posobota
Composer / PosobotaComposer / Posobota
Composer / Posobota
 

Kdyby/Translation

  • 2. Co si povíme? - Co to je - Něco si přeložíme - Typické úlohy s Nette - Co to neumí
  • 3. Co je Kdyby/Translation? - LocalizationITranslator - Symfony/Translation Kdyby/Translation je implementací NetteLocalizationITranslator pro Nette, využívající Symfony/Translator, díky kterému má podporu pro spoustu super featur.
  • 5. Instalace $ composer install kdyby/translation A do configu s tím! extensions: translation: KdybyTranslationDITranslationExtension Instalace je jako vždy primitívní, stačí použít composer a vložit extension do configu.
  • 6. Základní nastavení translation: default: cs fallback: [cs_CZ, cs] $translator->getDefaultLocale() Základní nastavení jsou také jednoduchá. Je nutné nastavit pouze výchozí jazyk, který pak jde získat metodou getDefaultLocale(). Fallback umožňuje načíst překlady z “náhradního” slovníku - tedy například když není překlady dostupný v němčině a máte nastavený fallback na angličtinu, načte se z anglického slovníku.
  • 7. Odkud se berou překlady - slovníky v aplikaci - neon - po / mo - xlf - csv - ts - ... Rozšíření umožňuje díky Symfony načítat slovníky v hromadě formátů, z nichž nejzajímavější jsou asi po/mo, díky kterým můžete translator použít jako drop-in replacement vašeho současného gettext translatoru. Kdyby pak přidává ještě navíc podporu pro neon slovníky.
  • 9. Slovník v neonu app/locale/messages.cs_CZ.neon "Hello World": Ahoj světe! Vytvoříme si slovník ve formátu neon pro češtinu a do něj vložíme nějaký překlad.
  • 10. Použití $translator->translate( 'Hello World' ); // Ahoj světe! Jednoduchým voláním pak překládáme.
  • 11. “Lepší” slovník v neonu app/locale/front.cs_CZ.neon hello: world: Ahoj světe! A nebo si vytvoříme lepší slovník, kde nebudeme mít jako klíče stringy, ale identifikátory, které pak máme unikátní napříč aplikací. Je možné pak mít více slovníků, kde název souboru se bere vždy jako první část identifikátoru, což je v tomto případě slovo front.
  • 12. Použití s identifikátory $translator->translate( 'front.hello.world' ); // Ahoj světe! Translatoru řekneme že chceme překládat nějaký identifikátor a on nám ho přeloží.
  • 13. Plurály orderForm: useCredits: Použít %count% kredit|Použít %count% kredity|Použít %count% kreditů Díky Symfony má translator podporu pluralizačních pravidel pro 95 různých jazyku a sám ví, který z výrazů v překladu použít, pokud se mění počet v předmětu daného překladu.
  • 14. Použití plurálů $translator->translate( 'front.orderForm.useCredits', 3 ); Tady translator sám pozná, že má vybrat druhý výraz a správně vrátí “Použít 3 kredity”.
  • 15. Parametry something: Hello %name% Samozřejmostí je i podpora pro parametrizované překlady.
  • 16. Použití parametrů $translator->translate( 'front.something, ['name' => 'Filip'] ); Druhý argument metody translate() je volitelný.
  • 17. Použití v šablonách {_front.orderForm.useCredits} {_front.orderForm.useCredits, 3} {_}front.hello.world{/_} {!_front.hello.world} Kdyby řeší i překlady v šablonách a přidává vlastní makra. Samozřejmostí je opět podpora plurálů a parametrů. Druhý argument s počtem je opět volitelný.
  • 18. Jak nastavím jazyk? Kdyby obsahuje plně automatickou detekci jazyka, už žádné Environment::getService(translator) a setLocale() podle parametru v každém BasePresenteru. Při každém requestu se volají resolvery, které samy rozhodnou jaký jazyk použít.
  • 19. Routování abstract class BasePresenter { /** @persistent */ public $locale; První z resolverů vybírá jazyk podle parametrů AppRequest, který vytváří router. Pokud jej chcete využívat, je potřeba definovat persistentní parametr locale.
  • 20. Routování new Route( '[<locale=cs cs|en>/]<presenter>/<action>', "Homepage:default" ); Parametr je potřeba taky definovat v routeru na vhodném místě, aby se předával do requestu a translator si ho mohl načíst.
  • 21. Accept-Language hlavička Accept-Language: cs,en;q=0.8,en-US;q=0.6 Pokud translator není schopný si přečíst locale z AppRequest, tak zkouší zpracovat hlavičku s požadovaným jazykem, kterou posílá prohlížeč. Jazyk vybírá na základě dostupných slovníků s překlady.
  • 22. Jazyk v session translation: resolvers: session: on Protože ukládat jazyk stránky do session není zrovna best practise, je potřeba toto chování explicitně zapnout.
  • 23. Jazyk v session abstract class BasePresenter { /** * @var SessionResolver * @inject */ public $localeSession; Je potom možné si do presenteru injectnout třídu SessionResolver, kterou budeme potřebovat abychom do ní mohli nastavit jazyk, když si ho uživatel změní. Třída si ho pamatuje díky uložení do session.
  • 24. Jazyk v session abstract class BasePresenter { public function handleLanguage($locale) { $this->localeSession ->setLocale($locale); $this->redirect('this'); Jazyk je pak možné měnit například vlastním signálem.
  • 25. Jazyk v session {link language!, cs} {link language!, en} Vygenerovat odkaz na signál s jazykem, který se má nastavit, je velice snadné.
  • 26. Co ještě jde překládat?
  • 27. Flash messages <div n:foreach='$flashes as $flash' n:class='flash, $flash->type'> {_$flash->message} </div> Nejsnadnější způsob jak překládat flash zprávy je použít makro na překlad v šabloně.
  • 28. Formuláře $form->setTranslator( $translator ); Překládat formuláře je také snadné, stačí jim předat translator. Nejlépe nějak globálně, pomocí DI Containeru.
  • 29. Formuláře $form->addText( 'name', 'front.registrationForm.name' ); Formulář pak své texty pro label nejprve předá translatoru, než je vykresluje. Samozřejmě je ale lepší vůbec titulek nenastavovat, vykreslovat formulář ručně a tedy mu i předat tento text k překladu až v šabloně.
  • 30. Formuláře $form->setTranslator( $translator->domain( 'front.registrationForm' ) ); Do formuláře si pomocí metody domain() můžu předat “prefixovaný translator”, což je šikovná zkratka, která vám umožní zbavit se opakování společné části identifikátoru v daném formuláři (nebo komponentě či konkrétní šabloně) a psát jen to co je v něm skutečně unikátní.
  • 31. Formuláře $form->addText( 'name', 'name' ); Jak je vidět, použití se drasticky zkrátilo.
  • 32. Formuláře $control->setTranslator(NULL); Občas se hodí vypnutí překladů pro jeden konkrétní prvek, to jde udělat snadno jedním voláním. Je pak ale potřeba ručně přeložit například titulek prvku. Hodí se to když máme například dynamické hodnoty v selectu.
  • 33. Parametry ve formulářích $form->addText( 'name', new Phrase( 'front.registrationForm.name', ['name' => $name] Ve formulářích není prostor pro nějaké parametrizované překlady nebo plurály, zajímá ho prostě titulek pro label a jak mu ho předáte je mu jedno. Jenže tento titulek vždy předává translatoru. Je tedy možné využít objekt Phrase, který dokáže propašovat parametry i počet až do translatoru, kde se správně očasuje a přeloží.
  • 34. Parametry ve validačních hláškách $control->addRule( Form::FILLED, new Phrase( 'front.orderForm.useCredits', $credits = 10 ) Stejný fígl funguje i ve validačních pravidlech.
  • 35. Jak získám seznam dostupných jazyků?
  • 36. Whitelisting translation: whitelist: [cs, en, de] $translator->getAvailableLocales() Pokud máte univerzální komponenty typu Symfony/Validator, které přidávají překlady pro 25 různých jazyků, tak nechcete, aby translator procházel a zpracovával slovníky pro jazyky které nepoužíváte. Od toho je whitelist, který odfiltruje nepotřebné jazyky. Dostupné jazyky je pak možné získat metodou getAvailableLocales()
  • 38. Extrakci umí, ale.. - latte je implementováno - PHP extraktor stále není - _() & __() jsou prasárny - Kdyby/Console command Kdyby/Translation obsahuje extractor ve formě Kdyby/Console commandu, který umí extrahovat Latte soubory. Neumí ovšem extrahovat přehlady z presenterů, komponent a dalších php souborů. Komunito, zapoj se prosím!
  • 39. Co to neumí? A umět nikdy nebude, protože taková feature je prasárna?
  • 40.
  • 42. Díky za pozornost! filip-prochazka.com Follow me maybe? @ProchazkaFilip