Localization
The Fliplet.Locale
JS API and Fliplet’s localization framework allow you to customize your component to different languages and regions.
There are 3 key aspects of a component that can be localized to the device or browser language/region settings.
- String translation
- Date format
- Number format
String translation
Components can now define a translation.json
file in their root to list out all keys and default English translation value.
- Keys can be nested
- Plurals and placeholders are expected to use the i18n notation
{
"widgets": {
"form": {
"submitButton": {
"label": "Submit"
},
"required": {
"label": "apple"
},
"errors": {
"required": "There are fields that need to be filled in",
"offline": "You need to be online to submit this form."
},
"success": {
"message": ""
}
}
}
}
A new JS API and global functions wrapping i18next will be made available to JavaScript and client-side Handlebars.
JS API
Fliplet.Locale.translate("widgets.form.required.label");
Fliplet.Locale.translate("widgets.form.errors.required", { n: 3 });
// Use the T() shorthand function instead
T("widgets.form.success.message", { msg: "<img..>" });
Handlebars
{{ T "widgets.form.success.message" }}
Please note that the T
function is only available after the Fliplet()
promise has resolved, so you may need to wrap your code as necessary to make use of translations:
Fliplet().then(function () {
// Compile Handlebars templates only when translations have been initialized
const myTemplate = Handlebars.compile(Fliplet.Widget.Templates['templates.foo']());
Fliplet.Widget.instance('my-component', function() {
// Use the "T" function only when translations have been initialized
const translatedText = T('widgets.myComponent.pleaseWait');
const translatedTemplate = myTemplate({ foo: 'bar' });
});
});
Localization helper libraries and frameworks
jQuery
Components can use $(this).translate()
(e.g. in Fliplet.Widget.instance()
) after having initialized their template to automatically bind data-translate="key"
properties in the target element.
When a DOM element is added to the page with translation keys assigned using data-translate
, the translations are not automatically applied. $.fn.translate()
must be applied on the rendered DOM to apply the translations.
Please note that the $(this).translate()
function is only available after the Fliplet()
promise has resolved, so you may need to wrap your code as necessary to make use of translations:
Fliplet().then(function () {
$('form').translate();
});
More docs on https://github.com/i18next/jquery-i18next.
Handlebars
Client-side Handlebars templates can use the {{ T }}
helper to print translations.
Handlebars.compile('{{ T "widgets.form.errors.required" n=3 }}')()
More docs on https://github.com/UUDigitalHumanitieslab/handlebars-i18next
Vue.js
Vue can optionally bind the i18n helper for Vue (returned by Fliplet.Locale.plugins.vue()
) on initialization:
var $form = new Vue({ i18n: Fliplet.Locale.plugins.vue() });
Then, strings can be translated using the $t helper in vue templates in build.html or Vue templates in general:
{{ $t("widgets.form.required.label") }}
Please note that the Fliplet.Locale.plugins.vue()
function is only available after the Fliplet()
promise has resolved, so you may need to wrap your code as necessary to make use of translations:
Fliplet().then(function () {
Fliplet.Widget.instance('my-component', function(data) {
var $form = new Vue({ i18n: Fliplet.Locale.plugins.vue() });
});
});
If you need to configure the plugin before translations inizialization, you can refer to it via the window.VueI18Next
variable:
var $form = new Vue({ i18n: window.VueI18Next });
Fliplet().then(function () {
// some other code
});
More docs on https://panter.github.io/vue-i18next/guide/component-interpolation.html
Date format
Powered by Moment.js, the number localization API can help you localize numbers to the language/regional preference.
JS API
Fliplet.Locale.date(value, options)
TD(value, options)
Handlebars helpers
{{ TD value [options] }}
Parameters
value
{*} The date or time value to be used for formatting. The input type can be aMoment
object,Date
object or a string. Strings must be formatted asYYYY-MM-DD
for dates andHH:mm
(24-hour time) for times.options
{Object} A map of optionsoptions.format
{String} The formatting to be used. You can use one of the supported formats in the table below, e.g.LL
for long form localized dates orLT
for localized time without seconds, or one of the following options for relative time:fromNow
,from
,toNow
andto
.options.from
{*} (Optional) Ifoptions.format
isfrom
, use this parameter to set the reference date.options.to
{*} (Optional) Ifoptions.format
isto
, use this parameter to set the reference date.options.locale
{String} (Optional) Use a specific locale for the formatting. Default: device/browser language settings oren
when that’s not found or valid.
Supported formats
Description | Format | Example |
---|---|---|
Time | LT | 8:30 PM |
Time with seconds | LTS | 8:30:25 PM |
Month numeral, day of month, year | L | 09/04/1986 |
l | 9/4/1986 | |
Month name, day of month, year | LL | September 4, 1986 |
ll | Sep 4, 1986 | |
Month name, day of month, year, time | LLL | September 4, 1986 8:30 PM |
lll | Sep 4, 1986 8:30 PM | |
Month name, day of month, day of week, year, time | LLLL | Thursday, September 4, 1986 8:30 PM |
llll | Thu, Sep 4, 1986 8:30 PM |
Examples
Fliplet.Locale.date('2022-03-04', { format: 'LL' }) // 4 March 2022 (UK) 4 marzo 2022 (IT) or 4 mars 2022 (FR)
Fliplet.Locale.date('2022-03-04', { format: 'LL', locale: 'en-US' }) // March 4, 2022
Fliplet.Locale.date('14:23', { format: 'LT' }) // 14:23 (UK) 2:23 PM (US) 下午2點23分 (ZH-TW)
Fliplet.Locale.date('14:23', { format: 'LT', locale: 'en-US' }) // 2:23 PM
Handlebars.compile('{{ TD foo format="LL" }}')({ foo: '2022-03-04' }) // 4 March 2022 (UK) 4 marzo 2022 (IT) or 4 mars 2022 (FR)
Handlebars.compile('{{ TD foo format="LL" locale="en-US" }}')({ foo: '2022-03-04' }) // March 4, 2022
Handlebars.compile('{{ TD foo format="LT" }}')({ foo: '14:23' }) // 14:23 (UK) 2:23 PM (US) 下午2點23分 (ZH-TW)
Handlebars.compile('{{ TD foo format="LT" locale="en-US" }}')({ foo: '14:23' }) // 2:23 PM
// For US locale
Fliplet.Locale.date('2022-01-03', { format: 'fromNow' }) // 9 months ago as of October 2022
Fliplet.Locale.date('2022-01-03', { format: 'from', from: '2022-01-05' }) // 2 days ago
Handlebars.compile('{{ TD foo format="fromNow" }}')({ foo: '2022-01-03' }) // 9 months ago as of October 2022
Handlebars.compile('{{ TD foo format="from" from="2022-01-05" }}')({ foo: '2022-01-03' }) // 2 days ago
Number format
Powered by Intl.NumberFormat()
, the number localization API can help you localize numbers to the language/regional preference.
JS API
Fliplet.Locale.number(value, options)
TN(value, options)
Handlebars helpers
{{ TN value [options] }}
Parameters
value
{*} The value to be used for formatting. Numbers are preferred. Other types of input will be parsed to determine its numerical value.options
{Object} A map of options. SeeIntl.NumberFormat()
documentation for the supported options.
Long decimal places: by default, numbers are localized and rendered with a minimum and maximum of 0–3 decimal places. This is due to the JavaScript's precision issues with floating points. If your data contains more decimal places, see documentation for Intl.NumberFormat()
to learn how to display more decimal places.
Large numbers: if you have large numbers that you want to display, you may want to consider using the notation
and compactDisplay
parameters as supported by Intl.NumberFormat()
to display large numbers. Also, numbers in JavaScript by default start to lose precision beyond positive or negative 9,007,199,254,740,991 (Number.MAX_SAFE_INTEGER
) and cannot go beyond the value of Number.MAX_VALUE
, which is around 10308 and would be displayed as "∞" where appropriate.
Examples
Fliplet.Locale.number(1234) // 1,234 (UK) 1.234 (IT) or 1 234 (FR)
Fliplet.Locale.number(1234, { locale: 'en-US' }) // 1,234
Fliplet.Locale.number(1234, { minimumFractionDigits: 2 }) // 1,234.00 (UK) 1.234,00 (IT) or 1 234,00 (FR)
Fliplet.Locale.number(1234, { minimumFractionDigits: 2, useGrouping: false }) // 1234.00 (UK) 1234,00 (IT) or 1234,00 (FR)
Fliplet.Locale.number(1234000000, { notation: 'compact', compactDisplay: 'long' }) // 1.2 billion (UK) 1,2 miliardi (IT) 1,2 milliard (FR)
Handlebars.compile('{{ TN foo }}')({ foo: 1234 }) // 1,234 (UK) 1.234 (IT) or 1 234 (FR)
Handlebars.compile('{{ TN foo locale="en-US" }}')({ foo: 1234 }) // 1,234
Handlebars.compile('{{ TN foo minimumFractionDigits=2 }}')({ foo: 1234 }) // 1,234.00 (UK) 1.234,00 (IT) or 1 234,00 (FR)
Handlebars.compile('{{ TN foo minimumFractionDigits=2 useGrouping=false }}')({ foo: 1234 }) // 1234.00 (UK) 1234,00 (IT) or 1234,00 (FR)
Handlebars.compile('{{ TN foo notation="compact" compactDisplay="long" }}')({ foo: 1234000000 }) // 1.2 billion (UK) 1,2 miliardi (IT) 1,2 milliard (FR)