📜 ⬆️ ⬇️

Zend Framework and Multilingual

I needed to create a multilingual website using ZF. Created. Under the cut I will tell you how.

So, we have a conditional website mysite.com , which is translated in three languages: Ukrainian (uk), Russian (ru) and English (en). And here comes the user site. What do we usually do? Either we immediately show him the site in the default language, or first we try to determine which language will be the best for it. Here I would like to tell about the second option in more detail.

Modern browsers (I don’t bother to talk about old ones) pass the HTTP_ACCEPT_LANGUAGE parameter to the server. In my case it is equal to “uk, ru; q = 0.8, en-us; q = 0.5, en; q = 0.3 ″. Those. I prefer the sites in Ukrainian or Russian, and then in English, while preferring the “American”.

In ZF, in order to determine which language is most appropriate, you can use Zend_Locale. For example:
')
$locale = new Zend_Locale('auto');
$lang = $locale->getLanguage();


But what if our site does not support this language? Need to do a check. To do this, in the configuration file (I use Zend_Config_Ini), save the set of locales that are supported by the site (you can then pull out the language later).

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


And we write a check (in the 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. And how now to make mysite.com/uk/user/auth displayed in Ukrainian, mysite.com/ru/user/auth in Russian, and mysite.com/user/auth in the language that is most suitable for the user (or on default)? To do this, override the main router (in order for it to pass the lang parameter) and create another one that will pull the language out of the url (if there is one):

// 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. A user can try to open the page mysite.com/de/user/auth , and our site is nicht sprechen z doych ... Here is an ambush. What to do? In general, in order to finally determine in what language to show the site, create a special helper (peeped in 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 get current language from 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); // translated Zend_Form

$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 the last check and tries to load the desired language file. The Ukrainian version of the site will be shown to mysite.com/de/user/auth . Well, in order for this helper to work, just add two lines to our bootstrap file.

$languageHelper = new Site_Controller_Action_Helper_Language($locales, APPLICATION_PATH . '/languages');
Zend_Controller_Action_HelperBroker::addHelper($languageHelper);


In principle, everything. Thank you for attention. The following topic will be devoted to Zend_Translate.

Source: https://habr.com/ru/post/42495/


All Articles