Internationalization of HTML pages for my Google Chrome Extension
Building from ahmd0's answer. Use a data attribute to allow a hard-coded fallback.
<!DOCTYPE html>
<html>
<head>
<title data-localize="__MSG_app_title__">My Default Title</title>
</head>
<body>
<a href="http://example.com/" title="__MSG_prompt001__" data-localize="__MSG_link001__">Default link text</a>
<script src="localize.js"></script>
</body>
</html>
Then provide the usual translation in _locales\en\messages.json
:
{
"app_title": {
"message": "MyApp",
"description": "Name of the extension"
},
"link001": {
"message": "My link",
"description": "Link name for the page"
},
"prompt001": {
"message": "Click this link",
"description": "User prompt for the link"
}
}
And finally your localize.js
will perform the actual localization:
function replace_i18n(obj, tag) {
var msg = tag.replace(/__MSG_(\w+)__/g, function(match, v1) {
return v1 ? chrome.i18n.getMessage(v1) : '';
});
if(msg != tag) obj.innerHTML = msg;
}
function localizeHtmlPage() {
// Localize using __MSG_***__ data tags
var data = document.querySelectorAll('[data-localize]');
for (var i in data) if (data.hasOwnProperty(i)) {
var obj = data[i];
var tag = obj.getAttribute('data-localize').toString();
replace_i18n(obj, tag);
}
// Localize everything else by replacing all __MSG_***__ tags
var page = document.getElementsByTagName('html');
for (var j = 0; j < page.length; j++) {
var obj = page[j];
var tag = obj.innerHTML.toString();
replace_i18n(obj, tag);
}
}
localizeHtmlPage();
The hard-coded fallback avoids the i18n tags being visible while the JavaScript does the replacements. Hard-coding seems to negate the idea of internationalisation, but until Chrome supports i18n use directly in HTML we need to use JavaScript.
Plain an simple:
{
"exmaple_key": {
"message": "example_translation"
}
}
<sometag data-locale="example_key">fallback text</sometag>
document.querySelectorAll('[data-locale]').forEach(elem => {
elem.innerText = chrome.i18n.getMessage(elem.dataset.locale)
})
What you would do is this.
First, in your HTML use the same syntax as Chrome requires anywhere else. So your basic popup.html
will be:
<!DOCTYPE html>
<html>
<head>
<title>__MSG_app_title__</title>
</head>
<body>
<a href="http://example.com/" title="__MSG_prompt001__">__MSG_link001__</a>
<!-- Need to call our JS to do the localization -->
<script src="popup.js"></script>
</body>
</html>
Then provide the usual translation in _locales\en\messages.json
:
{
"app_title": {
"message": "MyApp",
"description": "Name of the extension"
},
"link001": {
"message": "My link",
"description": "Link name for the page"
},
"prompt001": {
"message": "Click this link",
"description": "User prompt for the link"
}
}
And finally your popup.js
will perform the actual localization:
function localizeHtmlPage()
{
//Localize by replacing __MSG_***__ meta tags
var objects = document.getElementsByTagName('html');
for (var j = 0; j < objects.length; j++)
{
var obj = objects[j];
var valStrH = obj.innerHTML.toString();
var valNewH = valStrH.replace(/__MSG_(\w+)__/g, function(match, v1)
{
return v1 ? chrome.i18n.getMessage(v1) : "";
});
if(valNewH != valStrH)
{
obj.innerHTML = valNewH;
}
}
}
localizeHtmlPage();