W20 provides an extensive culture support through the jQuery Globalize library. It provides the developer tools to internationalize a W20 application which can then be localized via fragment manifests. As AngularJS also provides internalization support, W20 attempts to convert the active Globalize culture definition to an AngularJS locale, on a best-effort basis. This automatic conversion has limits, so it is recommended to stick to the W20 functions and services for internationalization.
Cultures
Cultures are defined as a combination of the language and the country speaking it. Each culture is given a unique code that is a combination of an ISO 639 two-letter lowercase culture code for the language, and a two-letter uppercase code for the country or region. For example, «en-US» is the culture code for English in the United States. Only one culture can be active at a time in the application but you can format values in any culture supported by the application, without switching the active one. This module handles:
- Textual internationalization,
- Date and time formatting,
- Currency formatting,
- Number formatting.
W20 supports about 350 cultures but can also be extended to custom-defined ones. Here is the list of out-of-the-box supported cultures:
Supported cultures
af-ZA, af, am-ET, am, ar-AE, ar-BH, ar-DZ, ar-EG, ar-IQ, ar-JO, ar-KW, ar-LB, ar-LY, ar-MA, ar-OM, ar-QA, ar-SA, ar-SY, ar-TN, ar-YE, ar, arn-CL, arn, as-IN, as, az-Cyrl-AZ, az-Cyrl, az-Latn-AZ, az-Latn, az, ba-RU, ba, be-BY, be, bg-BG, bg, bn-BD, bn-IN, bn, bo-CN, bo, br-FR, br, bs-Cyrl-BA, bs-Cyrl, bs-Latn-BA, bs-Latn, bs, ca-ES, ca, co-FR, co, cs-CZ, cs, cy-GB, cy, da-DK, da, de-AT, de-CH, de-DE, de-LI, de-LU, de, dsb-DE, dsb, dv-MV, dv, el-GR, el, en-029, en-AU, en-BZ, en-CA, en-GB, en-IE, en-IN, en-JM, en-MY, en-NZ, en-PH, en-SG, en-TT, en-US, en-ZA, en-ZW, es-AR, es-BO, es-CL, es-CO, es-CR, es-DO, es-EC, es-ES, es-GT, es-HN, es-MX, es-NI, es-PA, es-PE, es-PR, es-PY, es-SV, es-US, es-UY, es-VE, es, et-EE, et, eu-ES, eu, fa-IR, fa, fi-FI, fi, fil-PH, fil, fo-FO, fo, fr-BE, fr-CA, fr-CH, fr-FR, fr-LU, fr-MC, fr, fy-NL, fy, ga-IE, ga, gd-GB, gd, gl-ES, gl, gsw-FR, gsw, gu-IN, gu, ha-Latn-NG, ha-Latn, ha, he-IL, he, hi-IN, hi, hr-BA, hr-HR, hr, hsb-DE, hsb, hu-HU, hu, hy-AM, hy, id-ID, id, ig-NG, ig, ii-CN, ii, is-IS, is, it-CH, it-IT, it, iu-Cans-CA, iu-Cans, iu-Latn-CA, iu-Latn, iu, ja-JP, ja, ka-GE, ka, kk-KZ, kk, kl-GL, kl, km-KH, km, kn-IN, kn, ko-KR, ko, kok-IN, kok, ky-KG, ky, lb-LU, lb, lo-LA, lo, lt-LT, lt, lv-LV, lv, mi-NZ, mi, mk-MK, mk, ml-IN, ml, mn-Cyrl, mn-MN, mn-Mong-CN, mn-Mong, mn, moh-CA, moh, mr-IN, mr, ms-BN, ms-MY, ms, mt-MT, mt, nb-NO, nb, ne-NP, ne, nl-BE, nl-NL, nl, nn-NO, nn, no, nso-ZA, nso, oc-FR, oc, or-IN, or, pa-IN, pa, pl-PL, pl, prs-AF, prs, ps-AF, ps, pt-BR, pt-PT, pt, qut-GT, qut, quz-BO, quz-EC, quz-PE, quz, rm-CH, rm, ro-RO, ro, ru-RU, ru, rw-RW, rw, sa-IN, sa, sah-RU, sah, se-FI, se-NO, se-SE, se, si-LK, si, sk-SK, sk, sl-SI, sl, sma-NO, sma-SE, sma, smj-NO, smj-SE, smj, smn-FI, smn, sms-FI, sms, sq-AL, sq, sr-Cyrl-BA, sr-Cyrl-CS, sr-Cyrl-ME, sr-Cyrl-RS, sr-Cyrl, sr-Latn-BA, sr-Latn-CS, sr-Latn-ME, sr-Latn-RS, sr-Latn, sr, sv-FI, sv-SE, sv, sw-KE, sw, syr-SY, syr, ta-IN, ta, te-IN, te, tg-Cyrl-TJ, tg-Cyrl, tg, th-TH, th, tk-TM, tk, tn-ZA, tn, tr-TR, tr, tt-RU, tt, tzm-Latn-DZ, tzm-Latn, tzm, ug-CN, ug, uk-UA, uk, ur-PK, ur, uz-Cyrl-UZ, uz-Cyrl, uz-Latn-UZ, uz-Latn, uz, vi-VN, vi, wo-SN, wo, xh-ZA, xh, yo-NG, yo, zh-CHS, zh-CHT, zh-CN, zh-Hans, zh-Hant, zh-HK, zh-MO, zh-SG, zh-TW, zh, zu-ZA, zu.
Configuration
The culture module of w20 core can be configured with the following attribute:
available
(array of string) which list the available culture in the applicationdefault
(string) which is the culture name of the default culture. It defaults to «en».
Example
"path/w20-core.w20.json": {
"culture": {
"available": ["en", "fr"],
"default": "en"
}
}
Fragment declaration
The «i18n» section of a fragment manifest allows to declare culture localization bundles:
"i18n" : {
"" : [ "rest/i18n/bundle/:language" ]
"en" : [ "i18n/en-bundle-1.json", "i18n/en-bundle-2.json", ... ],
"fr-FR" : [ "i18n/fr-FR-bundle-1.json", "i18n/fr-FR-bundle-1.json", ... ]
}
Bundles modules will be loaded as a text dependency and parsed as JSON. The empty string culture code can be used to point to remote bundle. In that case, two placeholders can be used in the URL:
- The
:language
placeholder will be replaced by the actual language code, - The
:culture
placeholder will be replaced by the actual culture code.
Dynamic bundles will always be loaded for any language. If no keys are available for a particular language an empty object can be returned.
Usage
As an example if our bundle for en-EN culture contains the following entry:
{
"application.key": "my translation"
}
Inside an html template use the localize filter.
<p> {{ 'application.key' | localize }} </p>
You can also apply the localization programmatically by calling the CultureService.
Formatting
Numbers and dates can be formatted in various ways by using formatting patterns.
Number formatting
When formatting a number, the main purpose is to convert the number into a human readable string using the culture’s standard grouping and decimal rules. The rules between cultures can vary a lot. For example, in some cultures, the grouping of numbers is done unevenly. In the «te-IN» culture (Telugu in India), groups have 3 digits and then 2 digits. The number 1000000 (one million) is written as «10,00,000». Some cultures do not group numbers at all. There are four main types of number formatting:
- n for number
- d for decimal digits
- p for percentage
- c for currency
Even within the same culture, the formatting rules can vary between these four types of numbers. For example, the expected number of decimal places may differ from the number format to the currency format. Each format token may also be followed by a number. The number determines how many decimal places to display for all the format types except decimal, for which it means the minimum number of digits to display, zero padding it if necessary. Also note that the way negative numbers are represented in each culture can vary, such as what the negative sign is, and whether the negative sign appears before or after the number. This is especially apparent with currency formatting, where many cultures use parentheses instead of a negative sign. For instance in the «en-US» culture:
- 123.45 formatted with «n» will give 123.45
- 123.45 formatted with «n0» will give 123
- 123.45 formatted with «n1» will give 123.5
- 123.45 formatted with «d» will give 123
- 12 formatted with «d3» will give 012
- 123.45 formatted with «c» will give $123.45
- 123.45 formatted with «c0» will give $123
- 123.45 formatted with «c1» will give $123.5
- -123.45 formatted with «c» will give ($123.45)
- 0.12345 formatted with «p» will give 12.35 %
- 0.12345 formatted with «p0» will give 12 %
- 0.12345 formatted with «p4» will give 12.3450 %
Parsing also accepts any of these formats.
Date formatting
Date formatting varies wildly by culture, not just in the spelling of month and day names, and the date separator, but by the expected order of the various date components, whether to use a 12 or 24 hour clock, and how months and days are abbreviated. Many cultures even include «genitive» month names, which are different from the typical names and are used only in certain cases. Also, each culture has a set of «standard» or «typical» formats. For example, in «en-US», when displaying a date in its fullest form, it looks like «Saturday, November 05, 1955». Note the non-abbreviated day and month name, the zero padded date, and four digit year.
Format | Meaning | "en-US" |
---|---|---|
f | Long Date, Short Time | dddd, MMMM dd, yyyy h:mm tt |
F | Long Date, Long Time | dddd, MMMM dd, yyyy h:mm:ss tt |
t | Short Time | h:mm tt |
T | Long Time | h:mm:ss tt |
d | Short Date | M/d/yyyy |
D | Long Date | dddd, MMMM dd, yyyy |
Y | Month/Year | MMMM, yyyy |
M | Month/Day | MMMM dd |
Token | Meaning | Example |
---|---|---|
d | Day of month (no leading zero) | 5 |
dd | Day of month (leading zero) | 05 |
ddd | Day name (abbreviated) | Sat |
dddd | Day name (full) | Saturday |
M | Month of year (no leading zero) | 9 |
MM | Month of year (leading zero) | 09 |
MMM | Month name (abbreviated) | Sep |
MMMM | Month name (full) | September |
yy | Year (two digits) | 55 |
yyyy | Year (four digits) | 1955 |
'literal' | Literal Text | 'of the clock' |
\' | Single Quote | 'o'\''clock' |
m | Minutes (no leading zero) | 9 |
mm | Minutes (leading zero) | 09 |
h | Hours (12 hour time, no leading zero) | 6 |
hh | Hours (12 hour time, leading zero) | 06 |
H | Hours (24 hour time, no leading zero) | 5 (5am) 15 (3pm) |
HH | Hours (24 hour time, leading zero) | 05 (5am) 15 (3pm) |
s | Seconds (no leading zero) | 9 |
ss | Seconds (leading zero) | 09 |
f | Deciseconds | 1 |
ff | Centiseconds | 11 |
fff | Milliseconds | 111 |
t | AM/PM indicator (first letter) | A or P |
tt | AM/PM indicator (full) | AM or PM |
z | Timezone offset (hours only, no leading zero) | -8 |
zz | Timezone offset (hours only, leading zero) | -08 |
zzz | Timezone offset (full hours/minutes) | -08:00 |
g or gg | Era name | A.D. |