# i18n ## Introduction The i18n class (short for "internationalization") in SilverStripe enables you to display templates and PHP code in different languages based on your global settings and the preferences of your website users. This process is also known as l10n (short for "localization"). For translating any content managed through the CMS or stored in the database, please use the "[translatable](http://github.com/silverstripe/silverstripe-translatable)" module. This page aims to describe the low-level functionality of the i18n-API. It targets developers who: * are involved in creating templates in different languages * want to build their own modules with i18n capabilities * want to make their PHP-code (e.g. form labels) i18n-ready Please note that this project scope currently **doesn't include full support for format conversion in dates or currencies**. Check our [roadmap](http://open.silverstripe.com/roadmap). ## Usage ### Enabling i18n The i18n class is enabled by default. ### Setting the locale To set the locale you just need to call `[api:i18n::set_locale()]` passing, as a parameter, the name of the locale that you want to set. :::php //Example 1: setting the locale i18n::set_locale('de_DE'); //Setting the locale to German (Germany) i18n::set_locale('ca_AD'); //Setting to Catalan (Andorra) Once we set a locale, all the calls to the translator function will return strings according to the set locale value, if these translations are available. See [unicode.org](http://unicode.org/cldr/data/diff/supplemental/languages_and_territories.html) for a complete listing of available locales. ### Getting the locale As you set the locale you can also get the current value, just by calling `[api:i18n::get_locale()]`. ### Declaring the content language in HTML {#declaring_the_content_language_in_html} To let browsers know which language they're displaying a document in, you can declare a language in your template. :::html //'Page.ss' (HTML) //'Page.ss' (XHTML) Setting the '' attribute is the most commonly used technique. There are other ways to specify content languages (meta tags, HTTP headers), explained in this [w3.org article](http://www.w3.org/International/tutorials/language-decl/). ### Date and time formats Formats can be set globally in the i18n class. These settings are currently only picked up by the CMS, you'll need to write your own logic for any frontend output. :::php i18n::set_date_format('dd.MM.YYYY'); i18n::set_time_format('HH:mm'); Most localization routines in SilverStripe use the [Zend_Date API](http://framework.zend.com/manual/en/zend.date.html). This means all formats are defined in [ISO date format](http://framework.zend.com/manual/en/zend.date.constants.html#zend.date.constants.selfdefinedformats), not PHP's built-in [date()](http://nz.php.net/manual/en/function.date.php). ### i18n in URLs By default, URLs for pages in SilverStripe (the `SiteTree->URLSegment` property) are automatically reduced to the allowed allowed subset of ASCII characters. If characters outside this subset are added, they are either removed or (if possible) "transliterated". This describes the process of converting from one character set to another while keeping characters recognizeable. For example, vowels with french accents are replaced with their base characters, `pâté` becomes `pate`. In order to allow for so called "multibyte" characters outside of the ASCII subset, limit the character filtering in the underlying configuration setting, by setting `URLSegmentFilter.default_use_transliterator` to `false` in your YAML configuration. Please refer to [W3C: Introduction to IDN and IRI](http://www.w3.org/International/articles/idn-and-iri/) for more details. ### i18n in Form Fields Date- and time related form fields support i18n ([api:DateField], [api:TimeField], [api:DatetimeField]). :::php i18n::set_locale('ca_AD'); $field = new DateField(); // will automatically set date format defaults for 'ca_AD' $field->setLocale('de_DE'); // will not update the date formats $field->setConfig('dateformat', 'dd. MMMM YYYY'); // sets typical 'de_DE' date format, shows as "23. Juni 1982" Defaults can be applied globally for all field instances through the `DateField.default_config` and `TimeField.default_config` [configuration arrays](/topics/configuration). If no 'locale' default is set on the field, [api:i18n::get_locale()] will be used. **Important:** Form fields in the CMS are automatically configured according to the profile settings for the logged-in user (`Member->Locale`, `Member->DateFormat` and `Member->TimeFormat`). This means that in most cases, fields created through [api:DataObject::getCMSFields()] will get their i18n settings from a specific member The [api:DateField] API can be enhanced by JavaScript, and comes with [jQuery UI datepicker](http://jqueryui.com/demos/datepicker/) capabilities built-in. The field tries to translate the date formats and locales into a format compatible with jQuery UI (see [api:DateField_View_JQuery::$locale_map_] and [api:DateField_View_JQuery::convert_iso_to_jquery_format()]). :::php $field = new DateField(); $field->setLocale('de_AT'); // set Austrian/German locale $field->setConfig('showcalendar', true); $field->setConfig('jslocale', 'de'); // jQuery UI only has a generic German localization $field->setConfig('dateformat', 'dd. MMMM YYYY'); // will be transformed to 'dd. MM yy' for jQuery ## Translating text Adapting a module to make it localizable is easy with SilverStripe. You just need to avoid hardcoding strings that are language-dependent and use a translator function call instead. :::php // without i18n echo "This is a string"; // with i18n echo _t("Namespace.Entity","This is a string"); All strings passed through the `_t()` function will be collected in a separate language table (see [Collecting text](#collecting-text)), which is the starting point for translations. ### The _t() function The `_t()` function is the main gateway to localized text, and takes four parameters, all but the first being optional. It can be used to translate strings in both PHP files and template files. The usage for each case is described below. * **$entity:** Unique identifier, composed by a namespace and an entity name, with a dot separating them. Both are arbitrary names, although by convention we use the name of the containing class or template. Use this identifier to reference the same translation elsewhere in your code. * **$string:** (optional) The original language string to be translated. Only needs to be declared once, and gets picked up the [text collector](#collecting-text). * **$string:** (optional) Natural language comment (particularly short phrases and individual words) are very context dependent. This parameter allows the developer to convey this information to the translator. * **$array::** (optional) An array of injecting variables into the second parameter #### Usage in PHP Files :::php // Simple string translation _t('LeftAndMain.FILESIMAGES','Files & Images'); // Using the natural languate comment parameter to supply additional context information to translators _t('LeftAndMain.HELLO','Site content','Menu title'); // Using injection to add variables into the translated strings. _t('CMSMain.RESTORED', "Restored {value} successfully", 'This is a message when restoring a broken part of the CMS', array('value' => $itemRestored) ); #### Usage in Template Files