Zend_Locale 2.0
- Posted by thomasw at 22:57:59 // //
- Zend Framework, Announcements, I18N, Locale
Hy fellows,
first I want to wish you all a good start into this new decade.
Then I wanted to inform you about some news for Zend Framework.
Within the last days I began a complete rework of the I18n core for ZF.
The first class which will be reworked is Zend_Locale as it’s the base class for I18n within ZF.
The following changes will be done for Zend Locale 2.0:
CLDR update to 1.9
This integrates the most actual locale database within ZF
Usage of a fallback locale
This locale can be set and used as fallback when the wished locale is not supported
Usage of a fixed locale
This locale can be set and will be used regardless of any other locale which the accessing user wants
This removes the workaround from Zend_Application
Add locale providers as base
This allows to use other locale providers than CLDR
This will remove Zend_Locale_Format and integrate it into the used provider
Rework CLDR to be a provider
Add INTL as new provider
This allows to use INTL when available alone or in combination with CLDR because the INTL extension does not provide all informations like CLDR
Add a way to upgrade a locale
This would allow to provide informations for language locales when no region was given (f.e. when a user gives ‘en’ and wants to have informations from a region (f.e. currency))
Add script support
This allows to use locales which provide several scripts within the same language like Azerbaijani, English or Hausa.
That’s the actual plan for Zend_Locale 2.0 and will be the base for all other reworks.
Please note that all spoken will be done within Zend Framework 2.0 and not be migrated to 1.x.
Greetings
Thomas Weidner
I18N Team Leader, Zend Framework
Zend Framework Advisory Board Member
Zend Certified Engineer for Zend Framework
How to add missing translations
Hy interested ones.
Today I want to get you informed about translation logging.
A site is always a living place. Existing content is changed, new content is available.
But when you have a multilingual site then this can create problems. You have to keep the translations up to date, otherwise your visitors will not see what you want them to see. So how can this be archived?
Zend_Translate contains all to handle this situation. First let’s create the wished translation adapter.
$translate = new Zend_Translate(array( 'adapter' => Zend_Translate::AN_CSV, 'content' => 'C:\www\translations\', 'locale' => 'en', 'scan' => Zend_Translate::LOCALE_DIRECTORY, ));
Our translation file for en should contain the following content:
Untranslated message;Untranslated message (EN)
Translation itself works from this point on.
Next we need to keep aware of untranslated messages. This is done by using a log. So let’s create a log to write to.
$writer = new Zend_Log_Writer_Stream('C:\www\translations\untranslated.txt');
$logger = new Zend_Log($writer);
Now let’s attach the log to the translation adapter.
$translate->setOptions(array( 'log' => $logger; ));
All messages which are untranslated will now be written into the file untranslated.txt as soon as the translation should occur. Of course this is only the simplest example. You can do much more things.
When someone wants to get a translation for our message in a language which is not translated you will have a new entry within the log file. Let’s expect someone wants to have a translation for german. He will get Untranslated message in return, which is the source message… this is correct behaviour from the users point of view. But our log file will now look like this:
2010-07-30T12:10:18+02:00 NOTICE (5): Untranslated message within 'de': Untranslated message
The message looks confusing? Then let’s change the output for our log:
$translate->setOptions(array( 'logMessage' => '%locale%;%message%'; ));
Now our log will like like this:
2010-07-30T12:10:18+02:00 NOTICE (5): de;Untranslated message
Ok… but this is still no proper csv file. We want to have locale and message, and nothing more. Well, then let’s change the log formatter. Because timestamp and severity are created by Zend_Log. To change this you need to attach a formatter to your log.
$formatter = new Zend_Log_Formatter_Simple('%message%' . PHP_EOL);
$writer = new Zend_Log_Writer_Stream('C:\www\translations\untranslated.txt');
$writer->setFormatter($formatter);
$logger = new Zend_Log($writer);
Ok… that’s it. Now your log will look like this:
de;Untranslated message
Our full example looks like this:
$formatter = new Zend_Log_Formatter_Simple('%message%' . PHP_EOL);
$writer = new Zend_Log_Writer_Stream('C:\www\translations\untranslated.txt');
$writer->setFormatter($formatter);
$logger = new Zend_Log($writer);
$translate = new Zend_Translate(array(
'adapter' => Zend_Translate::AN_CSV,
'content' => 'C:\www\translations\',
'locale' => 'en',
'log' => $logger,
'logMessage' => '%locale%;%message%',
'scan' => Zend_Translate::LOCALE_DIRECTORY,
));
Zend_Log can also be used to add those “log” messages into a database. There is just one thing which can not be done this way.
It is not possible to recognise if a message has already been written or not. This means in the worst case that many messages will be duplicated into our log. On the other hand can you see which translations are requested many times and should be translated sooner than others. Anyhow… the above described features can be very usefull when your site is bigger or contains more than one translation file.
Have a nice frameworking
Greetings
Thomas Weidner
I18N Team Leader, Zend Framework
Zend Framework Advisory Board Member
Zend Certified Engineer for Zend Framework
Routing translations
Hy fellows,
sometimes a message can not be translated. In this case the original message id will be returned.
But it could be useful to return the translation for another language instead of the message id.
This is called “translation routing” and supported with the next minor release.
Let’s see an example:
$translate = new Zend_Translate(array(
'adapter' => Zend_Translate::AN_ARRAY,
'content' => $mytranslations,
'route' => array('de' => 'en')
));
Now we have a message id of “HEAD”… a user requesting german would expect to get “Meine Überschrift”.
But when there is no translation for this message id he would see “HEAD”.
With the set routing Zend_Translate will internally change the language to the new route and try to translate the message id with the other language.
So he would get “My Header” instead “HEAD”.
This feature seems to solve all problems for those who have no complete translations. But there are also some negs which should be thought of:
1.) You can not route a language to two others.
2.) When Zend_Translate is routing you will still get an “untranslated notice” for every message id and language which can not be translated
3.) When you route users to a language which they don’t understand you are irritating them
You can also build a translation chain by routing from several languages in a sort of priority:
Let’s see an example:
$translate = new Zend_Translate(array(
'adapter' => Zend_Translate::AN_ARRAY,
'content' => $mytranslations,
'route' => array('de' => 'en', 'en' => 'fr')
));
This creates the following chain:
GERMAN => ENGLISH => FRENCH
So german could return english when there is no translation. And when there is no translation for english it would even return french.
Now you could say: Let’s break translation and add a circle routing, something like this:
$translate = new Zend_Translate(array(
'adapter' => Zend_Translate::AN_ARRAY,
'content' => $mytranslations,
'route' => array('de' => 'en', 'en' => 'de')
));
GERMAN => ENGLISH => GERMAN
What now happens is that german returns english, and english returns german when there is no translation. But when there is no english translation it does not try to return german again, instead it returns the message id itself.
So you will always have a translation.
Further informations can be retrieved within the official mailing lists and within IRC.
I hope you find this feature useful. More to come soon…
Greetings
Thomas Weidner
I18N Team Leader, Zend Framework
Zend Framework Advisory Board Member
Zend Certified Engineer for Zend Framework
