Skip to content

Instantly share code, notes, and snippets.

@thejenja
Created November 3, 2022 18:04
Show Gist options
  • Save thejenja/2a274431c04dd524f855431aafc00b06 to your computer and use it in GitHub Desktop.
Save thejenja/2a274431c04dd524f855431aafc00b06 to your computer and use it in GitHub Desktop.
i18n.js
<body>
<div>
<div>
<ul class="lang-picker">
<li id="portuguese">português</li>
<li id="english">english</li>
<li id="spanish">español</li>
</ul>
</div>
<h1 data-i18n="demo.title"></h1>
<p data-i18n="demo.text"></p>
<form>
<input type="text" data-i18n-placeholder="demo.form.name">
<input type="text" data-i18n-placeholder="demo.form.email">
<input type="submit" data-i18n-value="demo.form.submit">
</form>
</div>
</body>
/*
* I18n.js
* =======
*
* Simple localization util.
* 1. Store your localized labels in json format: `localized-content.json`
* 2. Write your markup with key references using `data-i18n` attributes.
* 3. Explicitly invoke a traverse key resolver: `i18n.localize()`
* OR
* Change the language, and the contents will be refreshed: `i18n.lang('en')`
*
* This util relies on jQuery to work. I would recommend using the latest version
* available (1.12.x or 2.1.4+), although this will probably run with any older
* version since it is only taking advantage of `$.getJSON()` and the jQuery
* selector function `$()`.
*
* © 2016 Diogo Simões - diogosimoes.com
*
*/
var demoJson = {
"demo": {
"title": {
"pt": "Exemplo de uso do i18n.js",
"en": "Simple demo for i18n.js",
"es": "¡Una cerveza por favor!"
},
"text": {
"pt": "Este exemplo serve apenas para ilustrar os diferentes tipos de atributos de texto que podem ser localizados no cliente com a ajuda do i18n.js",
"en": "This demo's only purpose is to show the different text attributes that can be localized with the help of i18n.js",
"es": "Si i18n.js era español entonces sería de puta madre. Ahora así, la han cagado!"
},
"form": {
"name": {
"pt": "Zé dos Anzóis",
"en": "John Doe",
"es": "Fulano de Tal"
},
"email": {
"pt": "zeanzois@email.org",
"en": "johndoe@email.org",
"es": "fulanotal@email.org"
},
"submit": {
"pt": "Enviar",
"en": "Send",
"es": "¡Tío!"
}
}
}
};
(function () {
this.I18n = function (defaultLang) {
var lang = defaultLang || 'en';
this.language = lang;
(function (i18n) {
i18n.contents = demoJson;
i18n.contents.prop = function (key) {
var result = this;
var keyArr = key.split('.');
for (var index = 0; index < keyArr.length; index++) {
var prop = keyArr[index];
result = result[prop];
}
return result;
};
i18n.localize();
})(this);
};
this.I18n.prototype.hasCachedContents = function () {
return this.contents !== undefined;
};
this.I18n.prototype.lang = function (lang) {
if (typeof lang === 'string') {
this.language = lang;
}
this.localize();
return this.language;
};
this.I18n.prototype.localize = function () {
var contents = this.contents;
if (!this.hasCachedContents()) {
return;
}
var dfs = function (node, keys, results) {
var isLeaf = function (node) {
for (var prop in node) {
if (node.hasOwnProperty(prop)) {
if (typeof node[prop] === 'string') {
return true;
}
}
}
}
for (var prop in node) {
if (node.hasOwnProperty(prop) && typeof node[prop] === 'object') {
var myKey = keys.slice();
myKey.push(prop);
if (isLeaf(node[prop])) {
//results.push(myKey.reduce((prev, current) => prev + '.' + current)); //not supported in older mobile broweser
results.push(myKey.reduce( function (previousValue, currentValue, currentIndex, array) {
return previousValue + '.' + currentValue;
}));
} else {
dfs(node[prop], myKey, results);
}
}
}
return results;
};
var keys = dfs(contents, [], []);
for (var index = 0; index < keys.length; index++) {
var key = keys[index];
if (contents.prop(key).hasOwnProperty(this.language)) {
$('[data-i18n="'+key+'"]').text(contents.prop(key)[this.language]);
$('[data-i18n-placeholder="'+key+'"]').attr('placeholder', contents.prop(key)[this.language]);
$('[data-i18n-value="'+key+'"]').attr('value', contents.prop(key)[this.language]);
} else {
$('[data-i18n="'+key+'"]').text(contents.prop(key)['en']);
$('[data-i18n-placeholder="'+key+'"]').attr('placeholder', contents.prop(key)['en']);
$('[data-i18n-value="'+key+'"]').attr('value', contents.prop(key)['en']);
}
}
};
}).apply(window);
$( document ).ready( function () {
var i18n = new I18n();
i18n.localize();
$('.lang-picker #english').addClass('selected');
$('.lang-picker #portuguese').on('click', function () {
i18n.lang('pt');
selectLang($(this));
})
$('.lang-picker #english').on('click', function () {
i18n.lang('en');
selectLang($(this));
})
$('.lang-picker #spanish').on('click', function () {
i18n.lang('es');
selectLang($(this));
})
function selectLang (picker) {
$('.lang-picker li').removeClass('selected');
picker.addClass('selected');
}
});
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
html {
background-color: #2f2f2f;
}
body {
width: 35rem;
margin: 10rem auto 0 auto;
background-color: #f0f0f0;
border-radius: 10px;
}
body > div:first-of-type {
width: 25rem;
margin: 0 auto;
}
.lang-picker {
padding: 2rem 0 0 0;
text-align: center;
}
.lang-picker li {
list-style: none;
display: inline-block;
font: 400 14px/20px sans-serif;
color: #393939;
cursor: pointer;
}
.lang-picker li.selected {
font-weight: 900;
color: #496992;
}
h1 {
font: 400 28px/48px sans-serif;
color: #393939;
}
p {
font: 400 18px/22px sans-serif;
color: #393939;
}
form {
padding-bottom: 2rem;
}
form input{
display: block;
margin: 8px 0;
font: 400 13px sans-serif;
}
form input[type="text"] {
padding: 4px 8px;
width: 15rem;
}
form input[type="submit"] {
font: 100 15px sans-serif;
padding: 8px 16px;
color: #f0f0f0;
background-color: #496992;
border: none;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment