Yii framework: I18n ako naučiť aplikáciu po slovensky (2)
V dnešnom pokračovaní seriálu tutoriálov o Yii frameworku je tu exkluzívna možnosť dozvedieť sa ako spraviť funkčné a efektívne prehadzovanie jazykov.
V predchádzajúcej časti sme si popísali 2 spôsoby akými sa dá v Yii prekladať obsah multijazyčných stránok a tiež sme si ukázali ako internacionalizovať komponenty ako je datepicker. Podporu prekladov má síce Yii dosť fajn, ale autori akosi zabudli na to, že podstatou internacionalizácie je, aby sa dali jazyky aj meniť. Možno preto sú záležitosti okolo prepínania jazykov zdokumentované najbiednejšie zo všetkého, čo som o Yii čítal. Na zajtra.sk máte exkluzívnu:) možnosť sa dozvedieť ako jednoducho spraviť funkčné a efektívne prehadzovanie jazykov. Až mi je ľúto, že nepíšeme po anglicky, aby som ušetril nervy viacerým nešťastníkom.
V prvom rade musíme zobrať do úvahy dosť dôležitú otázku ako si budeme pamätať vybraný jazyk. Zvolil som (podľa mňa) najschodnejšiu cestu, kedy budeme mať jazyk v URL, čiže adresy by vyzerali ako http://drist.sk/sk/bla/tisic
. Mať jazyk v adrese je dobré jednak kvôli SEO - ak by sme si pamätali jazyk napríklad len v cookie, crawlery by sa neboli schopné dostať na viac ako jednu jazykovú mutáciu (čo by bolo fakt zlé) a jednak z dôvodu, že keď niekomu posielate link na takú stránku, bude ju vidieť rovnako ako vy.
Dropdown
Najskôr vytvoríme dropdown s jazykmi dostupný po celej stránke. Predvolený v ňom bude aktuálny jazyk a pri jeho zmene (onchange) chceme, aby sa načítala tá istá stránka len v inej reči. SEO poznámka: crawlery sa nedostanú ani cez takýto dropdown, takže treba buď vytvoriť sitemap alebo niekde (do footera?) podávať linky na všetky jazyky!
HTML pre dropdown doplníme do hlavného templejtu (protected/views/layouts/main.php
):
<div id="logo"> <?php echo CHtml::encode(Yii::app()->name) ?> <?php echo CHtml::beginForm(array('site/changelang'), 'post', array('style'=> 'float: right; font-size: 50%;')) ?> <?php echo Yii::t('nin', 'Language') ?>: <?php echo CHtml::dropDownList('lang', Yii::app()->getLanguage(), array('en' => 'English', 'sk' => 'Slovenčina'), array('onchange'=>'this.form.submit()')); ?> <?php echo CHtml::hiddenField('return', Yii::app()->request->url) ?> <?php echo CHtml::endForm() ?> </div>
Tu by malo byť viac menej všetko zrejmé. Pre istotu ale spomeniem, že Yii::app()->getLanguage()
vracia aktuálny jazyk (komplementárnou metódou setLanguage() sa dá zase jazyk hocikedy zmeniť), v štýle je 50%-ná veľkosť preto, že nadradený kontainer (s nadpisom) nastaví veľkosť na 200%, v hidden políčku je URL pre návrat na aktuálnu stránku a CHtml::beginForm()
používam namiesto klasického HTML markupu z dôvodu, že mi sám vygeneruje vhodnú URL pre akciu formulára.
SiteController
Akciu, na ktorú sa odošle formulár, musíme doplniť aj do controllera (protected/controllers/SiteController.php
). Pri tej príležitosti pridáme autodetekciu jazyka na hlavnú stránku a SEO optimalizáciu v jednom (hlavná stránka je vlastne akcia index v controlleri SiteController).
public function actionChangelang() { if ($_POST['return'] == '/' || preg_match('/^\/[a-z]{2}\/?$/', $_POST['return']) ) $this->redirect("/" . $_POST['lang']); else $this->redirect("/" . $_POST['lang'] . substr($_POST['return'], 3)); }Nahradíme aktuálny jazyk v URL novým jazykom. Ak je v návratovej ceste len nejaký kýpeť™ ;) typu "/", "/sk" alebo "/en/", rovno redirectneme na "/[nový jazyk]", pri plných cestách odstránime prvé 3 znaky (t.j. lomítko + pre každý jazyk budeme vždy používať len 2 písmená) a dáme namiesto nich do cesty "/[nový jazyk]".public function actionIndex() { if ($_SERVER['REQUEST_URI'] == '/') { if (substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2) == 'sk') $this->redirect('/sk'); else $this->redirect('/en'); }Pokiaľ používateľ príde na hlavnú stránku$this->render('index', array('users'=> CHtml::listData(User::model()->with('role')->findAll(), 'email', 'role.name'))); }/
, pokúsime sa zistiť akým jazykom by sme na neho mali vybehnúť a následne ho presmerujeme na adresu/[zistený jazyk]
. Jazyk sa dá determinovať na základe HTTP hlavičky "HTTP_ACCEPT_LANGUAGE", ktorá má cca. takýto formát:sk-SK,sk;q=0.9,en;q=0.8
. Každý browser ju však generuje inak a napríklad Opera mi zistila ako primárny jazyk slovenčinu, kým Firefox angličtinu.. so yeah. Za každých okolností nám ale stačí prečítať prvé 2 písmená a zariadiť sa podľa nich. Z hľadiska SEO je toto presmerovanie tiež dôležité. Ak by sme ho neuskutočnili, bol by na dvoch rôznych adresách ("/" a "/sk") rovnaký obsah a potom by nás Google nemal rád. :)
Konfigurácia UrlManagera
URL manažér zabezpečí, že Yii rozpoznáva a generuje adresy podľa určených pravidiel. Nastavenia pravidiel URL manažéra (rules) sú v hlavnom configu (protected/config/main.php
) a je to jedna z najčudnejších vecí v Yii. Fungujú natoľko zamotane, že sa nimi v podstate ani nemusíte zaoberať a ušetriť si zatiaľ nervy. :)
'urlManager'=>array( 'urlFormat'=>'path', 'showScriptName'=>false,Tieto 2 riadky nastavujú generovanie "čistých" URL. Presnejšie urlFormat = path odstráni GET parameter (/index.php?r=bla/drist -> /index.php/bla/drist) a showScriptName = false z cesty odstráni aj index.php, takže generované adresy budú mať v konečom dôsledku tvar /bla/drist'rules'=>array( '<language:[a-z]{2}>'=>'site/index', '<language:[a-z]{2}>/<controller:\w+>/<id:\d+>'=>'<controller>/view', '<language:[a-z]{2}>/<controller:\w+>/<action:\w+>/<id:\d+>'=>'<controller>/<action>', '<language:[a-z]{2}>/<controller>' => '<controller>', '<language:[a-z]{2}>/<controller>/<action>' => '<controller>/<action>', '<language:[a-z]{2}>/<module>/<controller>/<action>*' => '<module>/<controller>/<action>',Pravidlá pre cesty.. uf.. tak na toto treba pár odstavcov, čítajte nižšie :)), 'class' => 'I18nUrlManager',I18UrlManager je naša trieda, ktorou sa má nahradiť pôvodný UrlManager.),
O nastaveniach ciest v Yii by sa dal napísať aj celý tutoriál, ale v skratke - na ľavej strane je adresa akú vidí používateľ a na pravej controller a akcia (prípadne aj modul). Ostatné parametre ako "language", "id" alebo čokoľvek, čo v ľavej časti definujete, sú potom v controlleri prístupné z _GETu.
Pre lepšiu predstavu - napríklad druhé pravidlo zabezpečuje, že pri ceste v tvare /sk/user/1
sa zavolá controller a akcia user/view
a ako parameter bude predané idčko (a jazyk). Keďže jednotlivé časti cesty ako <controller> sú čisto len stringy bez významu, 5. pravidlo zachytáva okrem adries v tvare /sk/controller/akcia
aj adresy /sk/modul/controller
. Obdobne funguje aj 4. a 6. pravidlo. Adresa /sk/gii/crud
by sa vyhodnotila ako controller gii a akcia crud, ktoré neexistujú, takže by bola ďalej posunutá na spracovanie modulom a tam by ju modul gii odchytil.
Parameter language musí mať zrovna 2 písmená (regexp [a-z]{2}
) preto, aby sme vedeli, že naozaj ide o jazyk a nie je to napríklad meno modulu (gii). Je to celé mätúce, kľudne môžete pravidlá UrlManagera preskočiť a vrátiť sa k nim až keď budete potrebovať ťažko customizovať cesty. :)
UrlManager
Nasleduje spomínaný vlastný UrlManager, ktorého funkcia je generovať adresy obsahujúce v sebe jazyk a nastaviť správny jazyk podľa URL, na ktorej sa používateľ nachádza.
protected/components/I18nUrlManager.php
class I18nUrlManager extends CUrlManager { public function createUrl ($route, $params=array(), $ampersand='&') { if (!isset($params['language'])) $params['language'] = Yii::app()->getLanguage(); return parent::createUrl($route, $params, $ampersand);Metóda createUrl() sa volá vždy keď treba generovať link. Celá jej činnosť spočíva v tom, že nastaví parameter 'language' podľa aktuálne zvoleného jazyka a zavolá pôvodnú metódu createUrl().} public function parsePathInfo($pathInfo) { parent::parsePathInfo($pathInfo); $lang = Yii::app()->getRequest()->getParam('language'); if ( in_array($lang, array('en', 'sk')) ) Yii::app()->setLanguage($lang);ParsePathInfo rozbíja URL na jej jednotlivé časti, čiže controller, akciu a parametre. Na základe pravidiel sa do parametra 'language' zapíše obsah prvého segmentu adresy a podľa neho nastavíme jazyk. Táto metóda sa volá v momente keď sa zisťuje aký controller sa má vôbec použiť, takže kým začnete chcieť niečo prekladať, jazyk by už mal byť správne nastavený.} }
Na úplný záver hodíme do rootu (t.j. tam kde je index.php) Apachovský súbor .htaccess určený na generovanie pekných adries (clean URLs). Je kopec návodov zaoberajúcich sa peknými URL a modulom mod_rewrite, takže kód nebudem nejak veľmi rozpitvávať.
Asi len toľko, že vďaka RewriteCond sa otvorí súbor na danej adrese namiesto generovania stránky, v prípade že súbor exisuje (napr. /images/haluz.png
), inak RewriteRule prilepí celú adresu (od lomítka po koniec) za index.php (/bla/drist -> index.php/bla/drist
) a ten sa postará o zvyšok.
Options +FollowSymLinks IndexIgnore */* RewriteEngine on RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . index.php
Pro tip + download aplikácie
Po prečítaní tohoto návodu by ste mali byť vyzbrojení všetkým čo treba na kompletnú i18n. Na záver už len malý tip: ako som spomenul v prvej časti tutoriálu, písať Yii::t('kategoria', 'string')
je strašne zdĺhavé a pokiaľ sa chcete ušetriť od sústavného opakovania, priamo v index.php si môžete vytvoriť takúto užitočnú funkciu:
function t($string, $params = array()) { return Yii::t('kategoria', $string, $params); }
Možno sa to na prvý pohľad nezdá, ale písať len t('niečo')
dramaticky pridáva na pohodlnosti. Ak hrozí, že budete mať veľa stringov na preklad, nezabudnite využívať kategórie a vytvorte si aj viac pomocných funkcií.
Kompletné funkčné zdrojáky si môžete stiahnuť tu: Yii I18n demo [rar].

Momentálne robím internety a keď budem veľký, snáď sa dostanem aj k hrám alebo niečomu zmysluplnému. :) Mám rád minimalizmus, obskúrnu hudbu, všetko geeky a rýpanie sa v detailoch. Ďalšie kecy odo mňa nájdeš na brm.sk a na Twitteri @blade_sk.
1 komentár k článku:
Komentovať môžu iba prihlásení
Zaregistruj sa cez bezplatnú registráciu alebo použi login cez Facebook (FB Connect)
Prihlás sa tu, ak už máš profil na Zajtra.sk:
Novinky
2 rokmi
Aprílové vtípky: Výběr toho nejlepšího kolem počítačů, internetu a techniky
Výběr nejlepších aprílových vtípků 2019
2 rokmi
Fotky Google sa učia lepšie pracovať s dokumentmi
Spoločnosť Google prostredníctvom svojho účtu na sociálnej sieti Twitter oficiálne predstavila novú funkciu svojej aplikácie Fotky Google.
2 rokmi
Gmail dovoľuje naplánovať poslanie emailu neskôr
Spoločnosť Google dnes oznámila pridanie funkčnej novinky do svojej populárnej webmailovej služby Gmail, možnosť naplánovať poslanie emailu na neskôr.
3 rokmi
Používatelia Chrome začali prechádzať na nový rýchlejší Firefox, avizujú dáta Mozilly
Nový lepší a rýchlejší prehliadač Firefox 57 Quantum vyúsťuje zrejme do viac používateľov prechádzajúcich respektíve vracajúcich sa na tento prehliadač z iných prehliadačov, na osobných počítačoch aj smartfónoch.
3 rokmi
Briti dokončili kúpu SK-NIC-u. Nové .sk domény nechávajú za 8.4 eur
Predaj správcu slovenskej domény .sk, SK-NIC, bol dokončený a novým majiteľom po telekomunikačnej skupine Danubiatel, do ktorej patrí napríklad Swan a 4ka, je britská spoločnosť CentralNic.
Staršie novinky »TOP dlhšie
- 01 Farbičky v HTML a CSS, alebo? (1041x)
- 02 Tiché COMBO Logitech MK295 (916x)
- 03 Kingston uvádza 128GB verziu šifrovaného USB (879x)
- 04 Pochopte, ako vytvoriť virtuálny obchod v 6 krokoch (765x)
- Aj ty môžeš byť najčítanejší. Napíš článok »
TOP tento mesiac
- Aj ty môžeš byť najčítanejší. Napíš článok »
Nové články:
- 14.Kingston uvádza 128GB verziu šifrovaného USB
sep - 10.Tiché COMBO Logitech MK295
sep - 24.Farbičky v HTML a CSS, alebo?
aug - 23.Pochopte, ako vytvoriť virtuálny obchod v 6 krokoch
aug - 29.Kamery, cloud a bezpečnosť
jul - Viac »
- Aj ty môžeš byť najčítanejší. Napíš článok »
Pekné veci
Pekné veci
Pekné veci
Pekné veci
Posledné komentáre
- Pokiaľ používaš nejaký lepší bitmapový editor, napr. Photoshop, a chceš robiť retuše, ed...
- Veľmi dobrý článok a pre začiatočníka úplne odrazový mostík. https://ludwaismania1.blogs...
- Nova international a prima lus majú vysporiadané pravs ale aj CNN prima News
- Tv Joj nijako neobmedzuje šírenie médii, ktoré majú vysporiadané licenčné práva pre Slov...
- Nech televizie vrátia naspäť originál verzie a tie internationali nech zrušia. Každý si ...
Kritika
Vieš ako robiť veci lepšie? Pomôž našim odvážnejším členom a skritizuj im projekty!
Reklama
Slovenská IT komunita
Seriály zo Zajtra.sk
· Ako písať blog
· Ako sa stať PHP ninja s Yii Frameworkom
· Aplikácie pre Facebook
· CSS triky
· iOS vývojára príhody a skúsenosti
· Jednoduché programy, ktoré vám ušetria čas
· Modelovanie webového sídla
· Nauč sa CodeIgniter [HD]
· Nauč sa jQuery [HD]
· Nette PHP framework
· OOP v Javascripte
· Programujeme v Jave
· Programujeme v Lazaruse
· Programujeme v Pythone
· Robíme Eshop v ASP.NET Web Pages
· Slovenskí iOS developeri
· Webdizajn krok po kroku
· Yablkov TurboTip [HD]
Mohol by mi niekto poradiť ako sa správne prekladá slovo "scenario"? Napr. pri spustení validácie za behu. "Validation is performed in a scenario basis. The scenario property specifies which scenario the model is being used in and which set of validation rules should be used." Díky moc