ZF: Bootstrap Process for I18n
# Autoloader Namespaces | |
autoloaderNamespaces[] = "My_" | |
# Custom Resource Plugins | |
pluginPaths.My_Application_Resource = APPLICATION_PATH "/../lib/My/Application/Resource/" | |
# Front Controller Params | |
resources.frontController.params.locales[] = "en" | |
resources.frontController.params.locales[] = "ja" | |
resources.frontController.params.tldLocales.jp = "ja" | |
# Front Controller Plugins | |
resources.frontController.plugins.I18n = "My_Controller_Plugin_I18n" | |
# Locale | |
resources.locale.default = "en" | |
# Router/Routes | |
resources.router.locale.enabled = true | |
resources.router.routes.action_index.route = ":action/*" | |
resources.router.routes.action_index.defaults.controller = "index" | |
resources.router.routes.action_index.defaults.action = "index" | |
#resources.router.routes.action_index.type = "Zend_Controller_Router_Route_Regex" | |
#resources.router.routes.action_index.route = "(\w+)\/*" | |
#resources.router.routes.action_index.defaults.controller = "index" | |
#resources.router.routes.action_index.defaults.action = "index" | |
#resources.router.routes.action_index.map.1 = "action" |
<?php | |
class My_Controller_Plugin_I18n extends Zend_Controller_Plugin_Abstract | |
{ | |
/** | |
* Sets the application locale and translation based on the locale param, if | |
* one is not provided it defaults to english | |
* | |
* @param Zend_Controller_Request_Abstract $request | |
*/ | |
public function routeShutdown(Zend_Controller_Request_Abstract $request) | |
{ | |
$frontController = Zend_Controller_Front::getInstance(); | |
$params = $request->getParams(); | |
$registry = Zend_Registry::getInstance(); | |
// Steps setting the locale. | |
// 1. Defaults to English (Done in config) | |
// 2. TLD in host header | |
// 3. Locale params specified in request | |
$locale = $registry->get('Zend_Locale'); | |
// Check host header TLD. | |
$tld = preg_replace('/^.*\./', '', $request->getHeader('Host')); | |
// Provide a list of tld's and their corresponding default languages | |
$tldLocales = $frontController->getParam('tldLocales'); | |
if (array_key_exists($tld, $tldLocales)) { | |
// The TLD in the request matches one of our specified TLD -> Locales | |
$locale->setLocale($tldLocales[$tld]); | |
} else if (isset($params['locale'])) { | |
// There is a locale specified in the request params. | |
$locale->setLocale($params['locale']); | |
} | |
// Now that our locale is set, let's check which language has been selected | |
// and try to load a translation file for it. If the language is the default, | |
// then we do not need to load a translation. | |
$language = $locale->getLanguage(); | |
if ($language !== $locale->getDefault()) { | |
$i18nFile = APPLICATION_PATH . '/data/i18n/source-' . $language . '.mo'; | |
try { | |
$translate = | |
new Zend_Translate('gettext', $i18nFile, $locale, array('disableNotices' => true)); | |
Zend_Registry::set('Zend_Translate', $translate); | |
Zend_Form::setDefaultTranslator($translate); | |
} catch (Zend_Translate_Exception $e) { | |
// Since there was an error when trying to load the translation catalog, | |
// let's not load a translation object which essentially defaults to | |
// locale default. | |
} | |
} | |
// Now that we have our locale setup, let's check to see if we are loading | |
// a language that is not the default, and update our base URL on the front | |
// controller to the specified language. | |
$defaultLanguage = array_keys($locale->getDefault()); | |
$defaultLanguage = $defaultLanguage[0]; | |
$path = '/' . ltrim($request->getPathInfo(), '/\\'); | |
// If the language is in the path, then we will want to set the baseUrl | |
// to the specified language. | |
if (preg_match('/^\/' . $language . '\/?/', $path)) { | |
$viewRenderer = | |
Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer'); | |
$view = $viewRenderer->view; | |
$baseUrl = $frontController->getBaseUrl() . '/' . $language; | |
$frontController->setBaseUrl($baseUrl); | |
$view->getHelper('BaseUrl')->setBaseUrl($baseUrl); | |
} | |
setcookie('Zend_Locale', $language, null, '/', $request->getHttpHost()); | |
} | |
} |
<?php | |
class Default_View_Helper_LocaleSwitcher extends Zend_View_Helper_Abstract | |
{ | |
public function localeSwitcher() | |
{ | |
$output = array(); | |
$frontController = Zend_Controller_Front::getInstance(); | |
$locales = $frontController->getParam('locales'); | |
$request = $frontController->getRequest(); | |
$baseUrl = $request->getBaseUrl(); | |
$path = '/' . trim($request->getPathInfo(), '/\\'); | |
if (count($locales) > 0) { | |
$locale = Zend_Registry::get('Zend_Locale'); | |
$localeLanguage = $locale->getLanguage(); | |
$defaultLocaleLanguage = array_keys($locale->getDefault()); | |
$defaultLocaleLanguage = $defaultLocaleLanguage[0]; | |
array_push($output, '<ul id="locale_switcher">'); | |
foreach ($locales as $language) { | |
$imageSrc = 'img/i18n_'; | |
$imageSrc .= $language . '_' . ($localeLanguage == $language ? 'on' : 'off'); | |
$imageSrc .= '.gif'; | |
$urlLanguage = $defaultLocaleLanguage == $language | |
? '' | |
: '/' . $language; | |
if (strlen($baseUrl) === 0) { | |
$localeUrl = $urlLanguage . $path; | |
} else { | |
$localeUrl = preg_replace('/^' . preg_quote($baseUrl, '/') . '\/?/', | |
$urlLanguage . '/', $path); | |
} | |
array_push($output, '<li>'); | |
array_push($output, '<a href="' . $localeUrl . '">'); | |
array_push($output, '<img src="' . $this->view->assetUrl($imageSrc) . '" alt="' . $language . '" />'); | |
array_push($output, '</a>'); | |
array_push($output, '</li>'); | |
} | |
array_push($output, '</ul>'); | |
} | |
return join('', $output); | |
} | |
} |
<?php | |
class My_Application_Resource_Router extends Zend_Application_Resource_Router | |
{ | |
public $_explicitType = 'router'; | |
protected $_front; | |
protected $_locale; | |
/** | |
* Retrieve router object | |
* | |
* @return Zend_Controller_Router_Rewrite | |
*/ | |
public function getRouter() | |
{ | |
$options = $this->getOptions(); | |
if (!isset($options['locale']['enabled']) || | |
!$options['locale']['enabled']) { | |
return parent::getRouter(); | |
} | |
$bootstrap = $this->getBootstrap(); | |
if (!$this->_front) { | |
$bootstrap->bootstrap('FrontController'); | |
$this->_front = $bootstrap->getContainer()->frontcontroller; | |
} | |
if (!$this->_locale) { | |
$bootstrap->bootstrap('Locale'); | |
$this->_locale = $bootstrap->getContainer()->locale; | |
} | |
$defaultLocale = array_keys($this->_locale->getDefault()); | |
$defaultLocale = $defaultLocale[0]; | |
$locales = $this->_front->getParam('locales'); | |
$requiredLocalesRegex = '^(' . join('|', $locales) . ')$'; | |
$routes = $options['routes']; | |
foreach ($routes as $key => $value) { | |
// First let's add the default locale to this routes defaults. | |
$defaults = isset($value['defaults']) | |
? $value['defaults'] | |
: array(); | |
// Always default all routes to the Zend_Locale default | |
$value['defaults'] = array_merge(array( 'locale' => $defaultLocale ), $defaults); | |
$routes[$key] = $value; | |
// Get our route and make sure to remove the first forward slash | |
// since it's not needed. | |
$routeString = $value['route']; | |
$routeString = ltrim($routeString, '/\\'); | |
// Modify our normal route to have the locale parameter. | |
if (!isset($value['type']) || | |
$value['type'] === 'Zend_Controller_Router_Route') { | |
$value['route'] = ':locale/' . $routeString; | |
$value['reqs']['locale'] = $requiredLocalesRegex; | |
$routes['locale_' . $key] = $value; | |
} else if ($value['type'] === 'Zend_Controller_Router_Route_Regex') { | |
$value['route'] = '(' . join('|', $locales) . ')\/' . $routeString; | |
// Since we added the local regex match, we need to bump the existing | |
// match numbers plus one. | |
$map = isset($value['map']) ? $value['map'] : array(); | |
foreach ($map as $index => $word) { | |
unset($map[$index++]); | |
$map[$index] = $word; | |
} | |
// Add our locale map | |
$map[1] = 'locale'; | |
ksort($map); | |
$value['map'] = $map; | |
$routes['locale_' . $key] = $value; | |
} else if ($value['type'] === 'Zend_Controller_Router_Route_Static') { | |
foreach ($locales as $locale) { | |
$value['route'] = $locale . '/' . $routeString; | |
$value['defaults']['locale'] = $locale; | |
$routes['locale_' . $locale . '_' . $key] = $value; | |
} | |
} | |
} | |
$options['routes'] = $routes; | |
$this->setOptions($options); | |
return parent::getRouter(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This comment has been minimized.
hey @jgornick , great snippet/example , one note tho, for me the .ini comments are starting with semicolons (;), hashes (#) are not allowed.