Zend Framework and multilingualism

I had the need to create a multilingual site using ZF. Created. Under the cut will tell you how.

So, we have a conditional mysite.com, which is translated in three languages: Ukrainian (uk), Russian (ru) and English (en). And here comes to the website user. What do we usually do? Or just show him the website on the default language, or first try to determine which language will be best for him. That's the second option I would like to talk more.

Modern browsers (I can't say about the old one) passed to the server parameter HTTP_ACCEPT_LANGUAGE. I have it equal "uk,ru;q=0.8,en-us;q=0.5,en;q=0.3". Ie is best, I see the Ukrainian or Russian language, and then English, in this case I prefer "American".

In ZF in order to determine what language would be most appropriate, you can use Zend_Locale. For example:

$locale = new Zend_Locale('auto');
$lang = $locale- > getLanguage();


But what if our website does not support this language? Need to do the test. To do this in the config file (I use Zend_Config_Ini) save the set of locales supported by the site (with them then you can pull the language).

; allowed locales (first locale - default)
locales.uk = uk_UA
locales.ru = it_it
locales.en = en_GB


And write the check (in bootstrap file).

$locales = $config->locales->toArray();
$locale = new Zend_Locale('auto');

$lang = array_key_exists($locale- > getLanguage(), $locales)
? $locale- > getLanguage() : $config->locales->key();


OK. It works. But now how to make mysite.com/uk/user/auth displayed in Ukrainian, mysite.com/ru/user/auth — in Russian mysite.com/user/auth — in the language that suits the user (or default)? For this you need to override the main router (for it to be passed to the "lang" parameter) and create another one which will pull the language from the url (if available):

// change default router
$frontController- > getRouter()->addRoute('default',
new Zend_Controller_Router_Route(
':module/:controller/:action/*',
array(
'module' => 'default'
'controller' => 'index'
'action' => 'index'
'lang' = > $lang
)
)
);

// add multilingual route
$frontController- > getRouter()->addRoute('default_multilingual',
new Zend_Controller_Router_Route(
':lang/:module/:controller/:action/*',
array(
'module' => 'default'
'controller' => 'index'
'action' => 'index'
'lang' = > $lang
)
array(
'lang' = > '\w{2}'
)
)
);


But that's not all. The user may try to access the page mysite.com/de/user/auth, and our website nicht shprehen ze Deutsch... That's an ambush. What should I do? In General, in order to finally decide what language to display a website, create a special helper (inspired by the book "Zend Framework in Action").

<?php

class Site_Controller_Action_Helper_Language extends Zend_Controller_Action_Helper_Abstract {

protected $_sDefaultLanguage;
protected $_aLocales;
protected $_sLanguagesDirectoryPath;

/**
* @param array $aLocales - Available locales
* @param string $sLanguagesDirectoryPath
*/
public function __construct(array $aLocales, $sLanguagesDirectoryPath) {
$this->_sLanguagesDirectoryPath = $sLanguagesDirectoryPath;
$this->_aLocales = $aLocales;
$this->_sDefaultLanguage = key($aLocales); // get first language
}

public function init() {
// try to get current language from the url
$sLang = $this->getRequest()->getParam('lang');

if(! array_key_exists($sLang, $this->_aLocales)) {
$sLang = $this->_sDefaultLanguage;
}

// generate path to the gettext language file.
$sLanguageFilePath = $this->_sLanguagesDirectoryPath . '/'. $sLang . '/LC_MESSAGES/' . $sLang . '.mo';
if(! file_exists($sLanguageFilePath)) {
$sLanguageFilePath = $this->_sLanguagesDirectoryPath . '/' . $this->_sDefaultLanguage . '/LC_MESSAGES/' . $this->_sDefaultLanguage . '.mo';
$sLang = $this->_sDefaultLanguage;
}

// get current locale by current language
$sLocale = $this->_aLocales[$sLang];

// setup translate object
$oTranslate = new Zend_Translate('gettext', $sLanguageFilePath, $sLang);
Zend_Form::setDefaultTranslator($oTranslate); // Zend_Form translated

$this->_actionController- > _locale = $sLocale;
$this->_actionController->_lang = $sLang;
$this->_actionController- > _translate = $oTranslate;

$viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer');
$viewRenderer->view->locale = $sLocale;
$viewRenderer->view->lang = $sLang;
$viewRenderer- > view- > translate = $oTranslate;
}
}


This helper makes a final check and tries to load the desired language file. At mysite.com/de/user/auth will show the Ukrainian version of the site. Well, to make this helper earned, it is sufficient to add two lines in our bootstrap file.
$languageHelper = new Site_Controller_Action_Helper_Language($locales, APPLICATION_PATH . '/languages');
Zend_Controller_Action_HelperBroker::addHelper($languageHelper);


In principle, all. Thank you for your attention. The following topic will be devoted to Zend_Translate.
Article based on information from habrahabr.ru

Комментарии

Популярные сообщения из этого блога

mSearch: search + filter for MODX Revolution

Emulator data from GNSS receiver NMEA

The game Let's Twist: the Path into the unknown