A JavaScript tool for browser extensions and normal websites that want to use the i18n API (or the emulation) with HTML.
- Usage
- Translation information
- Functionality for normal websites
To load this tool in your HTML page:
...
<head>
<script src="/path/to/html-i18n.min.js"></script>
<!-- Or via CDN:
<script src="https://cdn.jsdelivr.net/gh/nd1012/HTML-i18n/src/html-i18n.min.js"></script>-->
</head>
...
NOTE: Please read the Mozilla i18n reference and be sure to understand which folders and files, and which modifications in the manifest file of your browser extension are required in order to use the i18n API. You'll see that you can do many things already - but there's no support for HTML. This is where this JavaScript library comes into play.
In case you don't use this library within a browser extension, but with a normal website, you need to initialize first:
<script type="application/javascript">
window.addEventListener('load',async ()=>await i18n_init());
</script>
The i18n_init
method takes these optional arguments:
uri
: The base URI to the locales (without trailing slash) (default:/_locales
)hasLocalesInfo
: If the locales URI serves an array of available locales in the filelocales.json
warn
: Write a warning to the JavaScript console, if translations are missing?
Example for a locales.json
file within the locales base URI:
[
"en",
"en_AU",
"en_CA",
"en_EN",
"en_US",
"de",
"de_AT",
"de_CH",
"fr",
"fr_CA",
"fr_CH",
"es",
"pt",
"it",
"it_CH",
"zh",
"hi_IN"
]
NOTE: The default locale is en
!
See the Online demonstration for a live example.
A simple sample HTML:
<p data-i18ntext="sample1" title="This title will be translated">This is text to be translated</p>
<p data-i18nhtml="sample2">This is <strong>HTML</strong> to be translated</p>
The required messages.json
:
{
"sample1": {
"message": "This is text to be translated",
"description": "The inner text of the HTML node"
},
"sample1Title": {
"message": "This title will be translated",
"description": "The title of the HTML node"
},
"sample2": {
"message": "This is <strong>HTML</strong> to be translated",
"description": "The inner HTML of the HTML node"
}
}
To apply a translation to the current DOM:
i18n_translate();
To get a warning in the JavaScript console on missing translations:
i18n_translate(false,false,true);
NOTE: In case the i18n API returned an empty string, the current text will stay unchanged.
Use the data-i18ntext
attribute to specify the i18n ID of the message that's going to be set to the innerText
property of the HTML element.
Use the data-i18nhtml
attribute to specify the i18n ID of the message that's going to be set to the innerHTML
property of the HTML element. The message
in the messages.json
should contain valid HTML in this case.
If a HTML element has the data-i18n*
attribute, and it has title
, alt
or value
attributes, too, the i18n_translate
function will translate their contents, if the messages.js
contains a message ID having the ID from the data-i18n*
attribute as prefix, and the capitalized attribute name (Title
, Alt
or Value
) as postfix.
In case you want to translate the attribute values only, simply omit the message for the ID defined in the data-i18n*
attribute.
Just text:
const text = i18n_text('messageId');
With variables:
const text = i18n_text('messageId','value1','value2',...);
Example messages.json
for variables:
{
"messageId": {
"message": "Resulting text with $value1$ and $value2$",
"placeholders": {
"value1": {
"content": "$1",
"example": "Any value"
},
"value2": {
"content": "$2",
"example": "Any value"
}
}
},
...
}
See the Mozilla reference for details.
const translated = i18n_translate('messageId');
Or with warning and stack trace on missing translation:
const translated = i18n_translate('messageId',true);
const translated = i18n_translate(['messageId',...]);
Or with warning and stack trace on missing translations:
const translated = i18n_translate(['messageId',...],true);
i18n_translate(document.querySelector('#element'));
Or with warning on missing translations:
i18n_translate(document.querySelector('#element'),true);
When translating the DOM or a single HTML element, the i18n_translate
function returns an object with the collected translation information, which may look like this:
{
"messageId": {
"message": "<strong>Message</strong> to translate",
"description": null,
"html": true,
"attr": null,
"missing": false
},
"messageIdTitle": {
"message": "Title to translate",
"description": null,
"html": false,
"attr": "title",
"missing": true
},
...
}
This object would be generated from this HTML element:
<p data-i18nhtml="messageId" title="Title to translate"><strong>Message</strong> to translate</p>
If you want to get this object only (without applying the translation), use the i18n_translate
function like this:
const translationMessages = i18n_translate(true);// Only FIND translations
If you want to include only missing translations in the returned object:
const missingTranslation = i18n_translate(true,true);// Only find MISSING translations
You can use this object for merging existing messages.json
files with an updated version of your HTML, for example. The missing
property is false
, when the i18n ID was found in the existing messages.json
file, and true
, when the translation is missing (the i18n API returned an empty string for the message ID).
In order to specify a value for the description
property, use the data-i18ninfo
attribute:
<p
data-i18nhtml="messageId"
data-i18ninfo="Any usage description"
title="Title to translate"
><strong>Message</strong> to translate</p>
The resulting JSON object for this example:
{
"messageId": {
"message": "<strong>Message</strong> to translate",
"description": "Any usage description",
"html": true,
"attr": null,
"missing": false
},
"messageIdTitle": {
"message": "Title to translate",
"description": "Any usage description (title)",
"html": false,
"attr": "title",
"missing": true
},
...
}
Within a browser extension the i18n browser API method getMessage
will be used, only. But if you use this library in a normal website context, you can do more:
await i18n_setLocale('de');
This call will set the new current locale, load messages and translate the DOM.
const locale = await i18n_determineLocale();
The returned locale may be a full locale string like en_US
, or the language only (like en
).
const messages = await i18n_loadMessages('de',true);
This will load the messages of the given locale.
Both arguments are optional:
locale
: The locale to use (default: the current or determined locale)fallBack
: Use the default locale as fallback?
If no messages for the used default locale were found on the server, the messages will be set from the DOM.
Give the message ID and a number as parameters (and optional add variables as required):
const text = i18n_plural('messageId',3);
Example messages.json
for plural:
{
"messageId": {
"message": "Resulting singular text",
"plural": "Resulting text for a number greater than one"
},
...
}
Example messages.json
for multiple plural:
{
"messageId": {
"message": "Resulting singular text",
"plural": {
"2": "Resulting text for a number of a maximum of 2",
"3": "Resulting text for a number of a maximum of 3",
"": "Resulting text for a number greater than 3"
}
},
...
}
Multiple plural forms may be required in some languages.
In case you have a string and its message ID, the string contains variables, and you want to replace them with values:
const text = i18n_var('messageId','Text with $placeholder$','placeholder value');
You may add any number of variables required.
i18n_defaultLocale
: Default locale (en
)i18n_messages
: Loaded messagesi18n_locale
: Current localei18n_localeUri
: Base URI to the localesi18n_localeInfo
: If having locales information, or the loaded locales information