The i18n and l10n support in Agavi provides you with tools which help you to easily make your application available to different cultures. When internationalizing your application there are many things to take care of. The I18N page at Wikipedia contains a list of what needs to be taken care about. Agavi provides you an easy to use solution to most[1] of these points. Agavi can support these features because we are bundling the Unicode Common Locale Data Repository (CLDR) and the "Olson" timezone database and making it available to applications. Agavi additionally includes a port of the calendar functionality from the ICU project which allows you to handle and calculate with date and time in millisecond precision from about 50000 BC to 50000 AD.
To distinguish between the different settings for each culture
Agavi uses the notion of locales. Each locale is uniquely defined by a
locale identifier (as defined in the LDML
definition). You can only access these locales which are defined as
being available to your application. Before using any of the
translation
related methods of the
AgaviTranslationManager you need to specify the currently
active locale and at least one translation domain defining your
message translator and optionally a different number/currency/date
formatter or options to them. Currently Agavi only supports the
definition of translation strings by using gettext as message
translator (This doesn't use the gettext functionaly of PHP tho, but a
custom parser for the .mo format used by gettext) but you can easily
write
your own custom message translators.
Translation domains allow you to define different translators or different formats for the formatters. This allows you to define one domain which would read the translation messages from the database and another to read it from gettext. Or you can define different formats which you want to use when formatting or parsing dates.
This should not be confused with gettexts text domains!
To use the translation you have to enable
use_translation in your settings.xml
and set up your translation.xml.
Example 3.1. translation.xml
<configurations>
<configuration>
<available_locales default_locale="en_US" default_timezone="Europe/London">
<!-- English, United States -->
<available_locale identifier="en_US" />
<!-- German, Germany and set the default currency to US Dollar -->
<available_locale identifier="de_DE@currency=USD" />
</available_locales>
<translators default_domain="frontend">
<translator domain="frontend">
<message_translator class="AgaviGettextTranslator">
<!-- This would look for the gettext domain files in gettext compatible way -->
<parameter name="text_domain_pattern">%core.app_dir%/locales/frontend/${locale}/LC_MESSAGES/${domain}.mo</parameter>
</message_translator>
</translator>
<translator domain="backend">
<message_translator class="AgaviGettextTranslator">
<parameter name="text_domain_pattern">%core.app_dir%/locales/backend/${locale}/LC_MESSAGES/${domain}.mo</parameter>
</message_translator>
<date_formatter>
<parameter name="format">full</parameter>
</date_formatter>
</translator>
</translators>
</configuration>
</configurations>That this example defines 2 locales as being available and "en_US" being the default locale should be obvious. The not so ovious part is the "@currency=USD": you can specify default options which will be used when the locale was requested and the option was not set when the locale was requested. You can also give parameters to the locales to set extended information which can be queried without loading the locale or overwrite the cldr data (not shown here).
The slightly larger block of the file defines 2 translation domains: frontend (the default one) and backend. Both translators are using the gettext implementation. The parameters differ for each message translator implementation. To use the formatters with the default format of each locale you don't have to configure anything.
When everything is configured you can start using the the
_*() methods of the AgaviTranslationManager.
For the examples assume $tm is the
AgaviTranslationManager instance and
de_DE the current locale.
Example 3.2. Translation message strings
$tm->_('Your Message');
#> Deine Nachricht (default translation domain)
$tm->_('%s said: I am your father %s!', 'backend', null, array('Darth Vader', 'Luke'));
#> Darth Vader sagte: Ich bin dein Vater Luke!
$tm->_('Your Message', null, 'en_US');
#> Your Message
$tm->__('%d registered user', '%d registered users', 3, 'backend', 'en_US', array(3));
#> 3 registered usersExample 3.3. Formatting currencies and numbers
$tm->_c(5000);
#> 5.000,00 $
$tm->_c(5000.12345);
#> 5.000,12 $
$tm->_c('12345678901234567890.98765');
#> 12.345.678.901.234.567.890,99 $
$tm->_c(5000.12345, null, 'en_US@currency=EUR');
#> €5,000.12
$tm->_n(5000.00);
#> 5.000
$tm->_n(5000.12345);
#> 5.000,12345
$tm->_n("12345678901234567890.98765", 'backend', 'en_US');
#> 12,345,678,901,234,567,890.98765Example 3.4. Formatting dates
$tm->_d(time()); #> 08.12.2006 07:42:43 $tm->_d(time(), null, 'en_US'); #> Dec 8, 2006 7:42:43 AM $tm->_d(time(), 'backend'); #> Freitag, 8. Dezember 2006 7:42 Uhr MEZ $tm->_d(time(), 'backend', '@timezone=Europe/London'); #> Freitag, 8. Dezember 2006 6:42 Uhr GMT+00:00 $tm->_d(time(), 'backend', 'en_US@timezone=Europe/London'); ># Friday, December 8, 2006 6:42:43 AM Europe/London
[1] Agavi currently helps you with the following items:
Language translation (text strings, entire templates)
Formatting date and time
Formatting of numbers and currencies
Time zone support
Localized territory, country, language and currency names