Slide 1

Slide 1 text

Kdyby/Translation @ProchazkaFilip

Slide 2

Slide 2 text

Co si povíme? - Co to je - Něco si přeložíme - Typické úlohy s Nette - Co to neumí

Slide 3

Slide 3 text

Co je Kdyby/Translation? - Localization\ITranslator - Symfony/Translation Kdyby/Translation je implementací Nette\Localization\ITranslator pro Nette, využívající Symfony/Translator, díky kterému má podporu pro spoustu super featur.

Slide 4

Slide 4 text

Jdeme překládat!

Slide 5

Slide 5 text

Instalace $ composer install kdyby/translation A do configu s tím! extensions: translation: Kdyby\Translation\DI\TranslationExtension Instalace je jako vždy primitívní, stačí použít composer a vložit extension do configu.

Slide 6

Slide 6 text

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.

Slide 7

Slide 7 text

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.

Slide 8

Slide 8 text

Použití

Slide 9

Slide 9 text

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.

Slide 10

Slide 10 text

Použití $translator->translate( 'Hello World' ); // Ahoj světe! Jednoduchým voláním pak překládáme.

Slide 11

Slide 11 text

“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.

Slide 12

Slide 12 text

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ží.

Slide 13

Slide 13 text

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.

Slide 14

Slide 14 text

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”.

Slide 15

Slide 15 text

Parametry something: Hello %name% Samozřejmostí je i podpora pro parametrizované překlady.

Slide 16

Slide 16 text

Použití parametrů $translator->translate( 'front.something, ['name' => 'Filip'] ); Druhý argument metody translate() je volitelný.

Slide 17

Slide 17 text

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ý.

Slide 18

Slide 18 text

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.

Slide 19

Slide 19 text

Routování abstract class BasePresenter { /** @persistent */ public $locale; První z resolverů vybírá jazyk podle parametrů App\Request, který vytváří router. Pokud jej chcete využívat, je potřeba definovat persistentní parametr locale.

Slide 20

Slide 20 text

Routování new Route( '[/]/', "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.

Slide 21

Slide 21 text

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 App\Request, 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.

Slide 22

Slide 22 text

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.

Slide 23

Slide 23 text

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.

Slide 24

Slide 24 text

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.

Slide 25

Slide 25 text

Jazyk v session {link language!, cs} {link language!, en} Vygenerovat odkaz na signál s jazykem, který se má nastavit, je velice snadné.

Slide 26

Slide 26 text

Co ještě jde překládat?

Slide 27

Slide 27 text

Flash messages
{_$flash->message}
Nejsnadnější způsob jak překládat flash zprávy je použít makro na překlad v šabloně.

Slide 28

Slide 28 text

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.

Slide 29

Slide 29 text

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ě.

Slide 30

Slide 30 text

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í.

Slide 31

Slide 31 text

Formuláře $form->addText( 'name', 'name' ); Jak je vidět, použití se drasticky zkrátilo.

Slide 32

Slide 32 text

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.

Slide 33

Slide 33 text

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ží.

Slide 34

Slide 34 text

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.

Slide 35

Slide 35 text

Jak získám seznam dostupných jazyků?

Slide 36

Slide 36 text

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()

Slide 37

Slide 37 text

Co extrakce?

Slide 38

Slide 38 text

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!

Slide 39

Slide 39 text

Co to neumí? A umět nikdy nebude, protože taková feature je prasárna?

Slide 40

Slide 40 text

No content

Slide 41

Slide 41 text

Dotazy?

Slide 42

Slide 42 text

Díky za pozornost! filip-prochazka.com Follow me maybe? @ProchazkaFilip