I've trying to use Zend_Translate from Zend Framework
I am using "POEdit" to generate "gettext" translation files.
My files are under /www/mysite.com/webapps/includes/locale (this path is in my include path).
I have:
pictures.en.mo
pictures.en.po
(I plan on having pictures.es.mo soon)
It all works fine if I manually do addTranslation() for each file. However I want to use the automatic file scanning method.
I tried both of those:
<?php
/*Localization*/
require_once 'Zend/Translate.php';
require_once 'Zend/Locale.php';
define('LOCALE','/www/mysite.com/webapps/includes/locale');
if(!empty($_GET['locale'])){
$locale = new Zend_Locale($_GET['locale']);
}
else{
$locale = new Zend_Locale();
}
$translate = new Zend_Translate('gettext', LOCALE, null, array('scan' => Zend_Translate::LOCALE_FILENAME));
if ( $translate->isAvailable( $locale->getLanguage() ) ){
$translate->setLocale($locale);
}
else{
$translate->setLocale('en');
}
And this:
<?php
/*Localization*/
require_once 'Zend/Translate.php';
require_once 'Zend/Locale.php';
define('LOCALE','/www/mysite.com/webapps/includes/locale');
if(!empty($_GET['locale'])){
$locale = new Zend_Locale($_GET['locale']);
}
else{
$locale = new Zend_Locale();
}
$translate = new Zend_Translate('gettext', LOCALE);
if ( $translate->isAvailable( $locale->getLanguage() ) ){
$translate->setLocale($locale);
}
else{
$translate->setLocale('en');
}
In both cases, I get a Notice: No translation for the language 'en' available. in /www/mysite.com/webapps/includes/Zend/Translate/Adapter.php on line 411
It also worked if I tried to do directory scanning.
i think there is just one little "bug".
$translate = new Zend_Translate(
'gettext',
LOCALE,
null,
array('scan' => Zend_Translate::LOCALE_DIRECTORY) // <--
);
If you use LOCALE_FILENAME, is ZF searching inside this FILE for your Translation.
Related
I use ZF 2.4 and I would like to change form validation messages to German, so I used code compatible with doc - https://framework.zend.com/manual/2.4/en/modules/zend.validator.messages.html
$translator = new \Zend\Mvc\I18n\Translator();
$translator->addTranslationFile(
'phpArray',
'./vendor/zendframework/zendframework/resources/languages/en/Zend_Validate.php', //or Zend_Captcha
'default',
'de_DE'
);
\Zend\Validator\AbstractValidator::setDefaultTranslator($translator);
Unfortunatelly EN is used still.. For example message "Value is required and can't be empty" is displayed from vendor/zendframework/zendframework/library/Zend/Validator/NotEmpty.php and isn't translated from vendor/zendframework/zendframework/resources/languages/de/Zend_Validate.php
No errors are there...
Could somebody help me, please? This is very important for me...
The translator is still pointing to the Locale of EN. What you want to do is set the translator Locale based on the user settings or maybe even a route parameter. To do that use the setLocale($locale) on your Translator.
So you could do this within your Application\Module.php:
$language = $event->getRouteMatch()->getParam('language', 'en_US');
$serviceManager = $event->getApplication()->getServiceManager();
$translator = $serviceManager->get('translator');
$translator
->setLocale($language)
->setFallbackLocale('en_US')
->addTranslationFilePattern(
'phpArray',
\Zend\I18n\Translator\Resources::getBasePath(),
\Zend\I18n\Translator\Resources::getPatternForValidator()
);
AbstractValidator::setDefaultTranslator($translator);
It is up to you to where you get the language locale from. If you don't have a route param defined for the language but want to use the user settings for example:
$language = 'en_US';
$authService = $auth = $serviceManager->get('zfcuser_auth_service');
if ($authService->hasIdentity()) {
$language = $authService->getIdentity()->getUserSettings()->getLanguage();
}
Haa, it works when I used below code:
public function onBootstrap(MvcEvent $e)
{
$eventManager = $e->getApplication()->getEventManager();
$moduleRouteListener = new ModuleRouteListener();
$moduleRouteListener->attach($eventManager);
$serviceManager = $e->getApplication()->getServiceManager();
$translator = $serviceManager->get('translator');
//$locale = $_SERVER['HTTP_ACCEPT_LANGUAGE'];
$locale = 'de_DE';
//$locale = 'en_US';
$translator->setLocale(\Locale::acceptFromHttp($locale));
$translator->addTranslationFile(
'phpArray',
'./vendor/zendframework/zendframework/resources/languages/de/Zend_Validate.php',
'default',
'de_DE'
);
\Zend\Validator\AbstractValidator::setDefaultTranslator($translator);
}
I don't understand why it wasn't working before..
i'm trying to make the translation of a website in zend framework, but, given that is the first time i use this framework, i'm having some problems. The last one is the one that gives me the error you're seeing as a title here.
I've set two important methods in the Bootstrap file:
protected function _initLocale()
{
$session = new Zend_Session_Namespace('ttb.l10n');
if ($session->locale)
{
$locale = new Zend_Locale($session->locale);
}
if ($locale === null)
{
try
{
$locale = new Zend_Locale('browser');
}
catch (Zend_Locale_Exception $e)
{
$locale = new Zend_Locale('en');
}
}
$registry = Zend_Registry::getInstance();
$registry->set('Zend_Locale', $locale);
}
protected function _initTranslate()
{
$translate = new Zend_Translate('array',
APPLICATION_PATH . '/../languages/',
'null',
array('scan' => Zend_Translate::LOCALE_FILENAME,
'disableNotices' => 0));
$registry = Zend_Registry::getInstance();
$registry->set('Zend_Translate', $translate);
return $translate;
}
The problem is that if I want the right translation in my pages i have to set the locale to the $translate variable and set it for every view I'll show to the user. The website has only one page, so i assumed the variable $translate would be avaliable in every action, and i changed the init method of the indexController.php:
public function init()
{
/* Initialize action controller here */
$registry = Zend_Registry::getInstance();
//The following is for the links that set the local language manually
$this->view->locale = $this->_getParam('locale');
if(!$this->view->locale){
$this->view->locale = $registry->get('Zend_Locale');
}
$translate->setLocale($locale);
}
The error i'm getting is the following (from zend server):
Function Name Zend_Application::bootstrap
Error Type E_ERROR
Source File /usr/local/zend/apache2/htdocs/project/public/index.php
Error String Uncaught exception 'Zend_Locale_Exception' with message 'The locale '' is no known locale'
If someone could help it would be much appreciated.
Thanks
SP
I am trying to create a connection between the Zend_Locale and the Zend_Currency using the browser language preferences.
BROWSER: en
$locale = new Zend_Locale(Zend_Locale::BROWSER);
Zend_Debug::Dump($locale->getLanguage());
Zend_Debug::Dump($locale->getRegion());
die;
Result:
string(2) "en"
bool(false)
BROWSER: en_US
$locale = new Zend_Locale(Zend_Locale::BROWSER);
Zend_Debug::Dump($locale->getLanguage());
Zend_Debug::Dump($locale->getRegion());
die;
Result:
string(2) "en"
string(2) "US"
Ho have I to solve this problem?
This is my plugin controller:
class MyProject_Controller_Plugin_Language extends Zend_Controller_Plugin_Abstract {
public function routeShutdown(Zend_Controller_Request_Abstract $request) {
$locale = new Zend_Locale(Zend_Locale::BROWSER);
$registry = Zend_Registry::getInstance();
// Check if the config file has been created
$isReady = MyProject_Main::isReady();
$module = $request->getModuleName ();
if($module == "default"){ // set the right session namespace per module
$ns = new Zend_Session_Namespace ( 'Default' );
}elseif($module == "admin"){
$ns = new Zend_Session_Namespace ( 'Admin' );
}else{
$ns = new Zend_Session_Namespace ( 'Default' );
}
// check the user request if it is not set, please get the old prefereces
$lang = $request->getParam ( 'lang', $ns->lang );
if(empty($lang)){ // Get the user preference
if(strlen($locale) == 2){ // Check if the Browser locale is formed with 2 chars
$lang = $locale;
}elseif (strlen($locale) > 4){ // Check if the Browser locale is formed with > 4 chars
$lang = substr($locale, 0, 2); // Get the language code from the browser preference
}
}
// Get the translate language or the default language: en
if(file_exists(PUBLIC_PATH . "/languages/$lang/$lang.mo")){
$translate = new Zend_Translate(array('adapter' => "MyProject_Translate_Adapter_Gettext", 'content' => PUBLIC_PATH . "/languages/$lang/$lang.mo", 'locale' => $lang, 'disableNotices' => true));
}else{
$translate = new Zend_Translate(array('adapter' => "MyProject_Translate_Adapter_Gettext", 'locale' => $lang, 'disableNotices' => true));
}
$registry->set('Zend_Translate', $translate);
$registry->set('Zend_Locale', $locale);
if($isReady){
$ns->langid = Languages::get_language_id_by_code($lang);
}else{
$ns->langid = 1;
}
$ns->lang = $lang;
}
}
Thanks
Obviously, the client's language preferences are a good first step, but won't help you in all cases. Even if they return a value, I would not use it to determine the appropriate currency as you described - users may set their preferred language/region to a foreign setting. Examples are expats and language learners. Though this may be an edge case, don't trust it to detect currency.
The most robust solution would be to use a geolocation service which also returns the currency for the location found, e.g. http://www.geoplugin.com/webservices/php.
The combination of both methods may also be a good solution. If they return conflicting values, offer the user a possibility to choose from the two found currencies (or from any other).
i am trying to add to my language file, the zend form errors language file, which can be found in
ZendFramework-1.11.2.zip\ZendFramework-1.11.2\resources\languages
in order to have localized form validators erorrs. This blog http://www.thomasweidner.com/flatpress/2010/03/25/working-with-multiple-translation-sources/comments/ explains what i try to do, but it fails :( it only translates from my .ini file, the .php is not included
Here is what i did:
this is my application.ini
resources.translate.adapter = "ini"
resources.translate.default.locale = "it_IT"
resources.translate.default.locale = "en_US"
resources.translate.default.file = APPLICATION_PATH "/lang/source-it.ini"
resources.translate.translation.en = APPLICATION_PATH "/lang/source-en.ini"
;resources.translate.data.directory = APPLICATION_PATH "/lang"
resources.translate.data = APPLICATION_PATH "/lang"
and then i have this
<?php
class Gestionale_Application_Resource_Translate extends Zend_Application_Resource_ResourceAbstract
{
public function init ()
{
$options = $this->getOptions();
$adapter = $options['adapter'];
$defaultTranslation = $options['default']['file'];
$defaultLocale = $options['default']['locale'];
$translate = new Zend_Translate($adapter, $defaultTranslation, $defaultLocale);
$translation_addme = new Zend_Translate(
'array',
APPLICATION_PATH."/resources/languages/it/Zend_Validate.php"
'it',
array('scan' => Zend_Translate::LOCALE_DIRECTORY)
);
$translate->addTranslation($translation_addme);
foreach ($options['translation'] as $locale => $translation) {
$translate->addTranslation($translation, $locale);
}
Zend_Registry::set('Zend_Translate', $translate);
return $translate;
}
}
and this is my dir
c:\www\www\gestionale\application>dir /w /aD
Il volume nell'unità C è OS
Numero di serie del volume: 6A5E-FD9B
Directory di c:\www\www\gestionale\application
[.] [..] [.svn] [configs] [controllers]
[forms] [lang] [layouts] [models] [resources]
[views]
0 File 0 byte
11 Directory 447.780.282.368 byte disponibili
Just by looking at your code I cannot tell you much. I suspect that your problems might be because you create your own resource plugin, which is unnessesry for this purpose, somethings are not being bootstrap properly, or there are some conflicts with your application.ini. Any way, I will post my translation setup and maybe it will give you some clues.
application.ini
Nothing here about translation or locale since I setup them in Bootstrap.php.
Bootstrap.php
protected function _initLocale() {
// define locale
$locale = new Zend_Locale('en');
// register it so that it can be used all over the website
Zend_Registry::set('Zend_Locale', $locale);
}
protected function _initTranslate() {
// Get Locale
$locale = Zend_Registry::get('Zend_Locale');
// Set up and load the translations (there are my custom translations for my app)
$translate = new Zend_Translate(
array(
'adapter' => 'array',
'content' => APPLICATION_PATH . '/languages/' . $locale . '.php',
'locale' => $locale)
);
// Set up ZF's translations for validation messages.
$translate_msg = new Zend_Translate(
array(
'adapter' => 'array',
'content' => APPLICATION_PATH .
'/resources/languages/' . $locale . '/Zend_Validate.php',
'locale' => $locale)
);
// Add translation of validation messages
$translate->addTranslation($translate_msg);
Zend_Form::setDefaultTranslator($translate);
// Save it for later
Zend_Registry::set('Zend_Translate', $translate);
}
I have implemented Zend_Navigation, Zend_Translate in my application.
The routing is setup in Bootstrap.php like below.
$fc = Zend_Controller_Front::getInstance();
$zl=new Zend_Locale();
Zend_Registry::set('Zend_Locale',$zl);
$lang=$zl->getLanguage().'_'.$zl->getRegion();
$router = $fc->getRouter();
$route = new Zend_Controller_Router_Route(':lang/:module/:controller/:action/*',
array(
'lang'=>$lang, 'module'=>'default', 'controller'=>'index', 'action'=>'index'
));
$router->addRoute('default', $route);
$fc->setRouter($router);
$fc->registerPlugin( new Plugin_LanguageSetup());
in LaunguageSetup Plugin i have defined the dispatchLoopStartup method to do the checking of the language param
public function dispatchLoopStartup(Zend_Controller_Request_Abstract $request) {
$this->createLangUrl($request);
$this->_language = $request->getParam('lang');
if ((!isset($this->_language)) || !in_array($this->_language, $this->_languagesArray)) {
$this->_language = 'en_US';
$request->setParam('lang', 'en_US');
}
$file = APPLICATION_PATH.$this->_directory.$this->_language.'.csv';
$translate = new Zend_Translate('csv', $file, $this->_language);
Zend_Registry::set('Zend_Translate', $translate);
$zl = Zend_Registry::get('Zend_Locale');
$zl->setLocale($this->_language);
Zend_Registry::set('Zend_Locale', $zl);
// $fc = Zend_Controller_Front::getInstance();
// $router = $fc->getRouter();
// $route = new Zend_Controller_Router_Route(':lang/:module/:controller/:action/*', array(
// 'lang'=>$this->_language, 'module'=>'default', 'controller'=>'index', 'action'=>'index'
// ));
// $router->addRoute('default', $route);
// $fc->setRouter($router);
}
What happen is the language always have the default value, the 'lang' param never default lang value in route, even if i type it in the address bar manually i.e /en_US/module/controller/action/ It always get revert back to the default Zend_locale();
Only way i can fix it is to setup the route again in the plugin and inject a correct language value as default. Any Idea why?
try and do a var_dump of the 2 vars ( _language, _languagesArray ) before this line
if ((!isset($this->_language)) || !in_array($this->_language, $this->_languagesArray)) {
I suspect that there it should be the problem, because you put yor plugin on dispatchLoopStartup, and then the params might not be populated, i put my plugin on routeShutdown see my implementation of the languange plugin.
Sort of a partial solution.
in dispatchLoopStartup
add
$fc = Zend_Controller_Front::getInstance();
$router = $fc->getRouter();
$router->setGlobalParam('lang',$this->_language);
better than redefine and overwrite the route again and 'fake' the language param by changing the default 'lang' value.
it's just less than perfect. Zend_router suppose to pick up the 'lang' param and have them placed in Zend_navigation->menu();