Skip to content

Instantly share code, notes, and snippets.

@384400
Last active January 19, 2016 14:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 384400/c22bbb85448be3036a02 to your computer and use it in GitHub Desktop.
Save 384400/c22bbb85448be3036a02 to your computer and use it in GitHub Desktop.
[JavaScript] [Css] [Html] Diakritikós, méthode frugale d'internationalisation de sites Internet

Diakritikós

Diakritikós est une méthode frugale pour afficher un site en plusieurs langues grâce à JavaScript.

Diakritikós fonctionne avec les principaux navigateurs, y compris Internet Explorer à partir de la version 9. Quand le navigateur ne supporte pas les méthodes mises en œuvre ou si JavaScript n'est pas disponible, la langue par défaut s'affiche.

Diakritikós utilise deux méthodes :

  • en ligne ;
  • par bloc.

Chaque texte à traduire doit comprendre un identifiant associée à la classe translate-d10s-text pour les textes ou translate-d10s-img pour les images.

Diakritikós recourt à l'attribut data-text-[langue]langue correspond à la norme Iso 639-1 (https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes). Cet attribut peut être appelé soit en ligne, soit par bloc.

Appel en ligne

L'appel en ligne s'écrit sous la forme...

<p id="days" class="translate-d10s-text" data-text-es="Domingo, Lunes, Martes, Miércoles, Jueves, Viernes, Sábado" data-text-fr="Dimanche, Lundi, Mardi, Mercredi, Jeudi, Vendredi, Samedi">Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday</p>

Appel par bloc

L'appel par bloc s'écrit sous la forme...

<p id="days">Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday</p>
<script>
document.getElementById('days').setAttribute('data-text-es', 'Domingo, Lunes, Martes, Miércoles, Jueves, Viernes, Sábado');
document.getElementById('days').setAttribute('data-text-fr', 'Dimanche, Lundi, Mardi, Mercredi, Jeudi, Vendredi, Samedi');
</script>

Les deux méthodes peuvent être utilisées en même temps. Par exemple, la traduction dans la langue de Molière peut s'écrire en ligne et la traduction dans la langue de Cervantès par bloc.

Quand une traduction est indisponible ou incomplète, le texte par défaut, en dur, s'affiche.

Les attributs alt ou title des images sont traduits avec la méthode data-image-[langue] : la traduction doit être appelée dans le parent.

Des textes d'alertes peuvent être utilisés. fallback correspond à la langue par défaut.

Les sinogrammes et autres alphabets cyrilliques fonctionnent correctement.

Il est possible (d'essayer) de reconnaître la langue par défaut du navigateur. Ainsi, au chargement de la page, la langue de l'utilisateur s'affichera. Si la langue est incorrecte, l'utilisateur pourra la modifier d'un clic de souris. Cette reconnaissance, quelque peu hasardeuse (!), est désactivable en attribuant la valeur false à onLoadDiakritikos.

Dans le fichier d'exemple, nous proposons à l'utilisateur de choisir sa langue, uniquement si son navigateur supporte les propriétés mises en œuvre.

(Il est déconseillé de recourir à un drapeau pour symboliser une langue : par exemple, on ne parle pas le français qu'en France !)

Remarques

Il aurait été intéressant de prévoir une écriture de droite à gauche pour l'arabe, l'hébreu, l'ourdou et le pachtoune, mais nous n'avons pas (encore !) trouvé de solution satisfaisante.

<script>
var rtlLangs = ['ar', 'he', 'ps', 'ur'];
...
function d10scheckRtlLang(d10sLang) {
    for (i = 0; i < rtlLangs.length; i++) {
        if (rtlLangs[i] === d10sLang) {
            return true;
        }
    }
}
...
if (d10scheckRtlLang(d10sLang)) {
  document.getElementById(item).setAttribute('dir', 'rtl');
} else {
  document.getElementById(item).setAttribute('dir', 'ltr');
}
</script>

La méthode querySelectorAllaurait pu être préférée, mais elle semble nettement plus lente. Nous la présentons néanmoins comme deuxième exemple.

Liens utiles

Pourquoi Diakritikós et d10s ?

Diakritikós signifie en grec "qui distingue".

Onze caractères séparent le d du s.

Licence

Wtfpl

Copyright © 2016 384400 william.top@384400.com

This work is free. You can redistribute it and/or modify it under the terms of the Do What The Fuck You Want To Public License, Version 2, as published by Sam Hocevar. See http://www.wtfpl.net/ for more details.

<!DOCTYPE html>
<html class="no-js">
<head>
<meta charset="utf-8" />
<title id="title" class="translate-d10s-text" data-text-fr="Calendrier">Calendar</title>
<script>
var canvasElement = document.createElement('canvas');
if (!canvasElement.getContext) {
var shivNew = document.createElement('script');
shivNew.setAttribute('type', 'text/javascript');
/*shivNew.src = 'js/html5shiv.min.js';*/
shivNew.src = 'https://cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.2/html5shiv.min.js';
shivNew.async = true;
var shiv0 = document.getElementsByTagName('script')[0];
shiv0.parentNode.insertBefore(shivNew, shiv0);
}
</script>
<style>
.no-js .support-d10s, .js.no-d10s .support-d10s, .js .no-support-d10s {
display: none;
}
.no-js .no-support-d10s, .js.no-d10s .no-support-d10s, .js .support-d10s {
display: block;
}
</style>
</head>
<body>
<p class="no-support-d10s">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.</p>
<div id="switcher" class="support-d10s">
<button id="es" class="language-d10s">ES</button>
<button id="fr" class="language-d10s">FR</button>
<button id="en" class="language-d10s">EN</button>
</div>
<p id="days" class="translate-d10s-text" data-text-es="Domingo, Lunes, Martes, Miércoles, Jueves, Viernes, Sábado" data-text-fr="Dimanche, Lundi, Mardi, Mercredi, Jeudi, Vendredi, Samedi" >Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday</p>
<p id="monthes" class="translate-d10s-text" data-text-es="Enero, Febrero, Marzo, Abril, Mayo, Junio, Julio, Agosto, Septiembre, Octubre, Noviembre, Diciembre" data-text-fr="Janvier, février, mars, avril, mai, juin, juillet, août, septembre, octobre, novembre, décembre">January, February, March, April, May, June, July, August, September, October, November, December</p>
<p id="seasons" class="translate-d10s-text">Winter, Spring, Summer, Autumn</p>
<p id="units" class="translate-d10s-text">Second, Minute, Hour</p>
<hr>
<div id="norway" class="translate-d10s-img" data-image-fr="Mai 2009 en Norvège"><img alt="May 2009 in Norway" title="May 2009 in Norway" src="https://upload.wikimedia.org/wikipedia/commons/thumb/0/07/Lofoten_-_Vik_-_Haukland.jpg/320px-Lofoten_-_Vik_-_Haukland.jpg" /></div>
<p><small>This file is licensed under the <a href="//en.wikipedia.org/wiki/en:Creative_Commons" title="w:en:Creative Commons">Creative Commons</a> <a rel="nofollow" href="//creativecommons.org/licenses/by-sa/2.0/deed.en">Attribution-Share Alike 2.0 Generic</a> license.</small></p>
<hr>
<button id="button" class="translate-d10s-text" data-text-es="¡Haz click en mi!" data-text-fr="Cliquez-moi !" onclick="displayAlert();">Click me!</button>
<script>
var onLoadDiakritikos = true; /* Config */
var d10sLang;
document.getElementById('seasons').setAttribute('data-text-es', 'Invierno, Primavera, Verano, Otoño');
document.getElementById('seasons').setAttribute('data-text-fr', 'Hiver, Printemps, Été, Automne');
document.getElementById('units').setAttribute('data-text-fr', 'Seconde, Minute, Heure');
document.getElementById('norway').setAttribute('data-image-es', 'Mayo 2009 en Noruega');
var d10sAlertSpeak = [];
d10sAlertSpeak.es = '¿Hablas español?';
d10sAlertSpeak.fr = 'Parlez-vous français ?';
d10sAlertSpeak.fallback = 'Do you speak English?';
function supportElementById() {
if (document.getElementById) {
return true;
}
return false;
}
function supportElementsByClassName() {
if (document.getElementsByClassName) {
return true;
}
return false;
}
function supportAddEventListener() {
if (document.implementation.hasFeature('MutationEvents','2.0') || window.MutationEvent) {
return true;
}
return false;
}
function d10sSelectLang(d10sListLangs) {
d10sListLangs[i].addEventListener('click', function() {
var d10sText = 'data-text-';
d10sText += this.id;
d10sTranslateText(d10sText);
var d10sImage = 'data-image-';
d10sImage += this.id;
d10sTranslateImage(d10sImage);
d10sLang = this.id;
return d10sLang;
});
}
function d10sTranslateText(d10sText) {
var texts = document.getElementsByClassName('translate-d10s-text');
for (var i = 0; i < texts.length; ++i) {
var item = texts[i].id;
var content = document.getElementById(item).innerHTML;
if (!document.getElementById(item).hasAttribute('data-text-d10s')) {
document.getElementById(item).setAttribute('data-text-d10s', content);
}
var target;
if (document.getElementById(item).hasAttribute(d10sText)) {
target = document.getElementById(item).getAttribute(d10sText);
} else {
target = document.getElementById(item).getAttribute('data-text-d10s');
}
document.getElementById(item).innerHTML = document.getElementById(item).innerHTML.replace(content, target);
}
}
function d10sTranslateImage(d10sImage) {
var images = document.getElementsByClassName('translate-d10s-img');
for (var i = 0; i < images.length; ++i) {
var item = images[i].id;
var content = document.getElementById(item).getElementsByTagName('img')[0].title;
if (!document.getElementById(item).hasAttribute('data-image-d10s')) {
document.getElementById(item).setAttribute('data-image-d10s', content);
}
var target;
if (document.getElementById(item).hasAttribute(d10sImage)) {
target = document.getElementById(item).getAttribute(d10sImage);
} else {
target = document.getElementById(item).getAttribute('data-image-d10s');
}
document.getElementById(item).getElementsByTagName('img')[0].setAttribute('alt', target);
document.getElementById(item).getElementsByTagName('img')[0].setAttribute('title', target);
}
}
function displayAlert() {
if (d10sLang in d10sAlertSpeak) {
alert(d10sAlertSpeak[d10sLang]);
} else {
alert(d10sAlertSpeak.fallback);
}
}
document.getElementsByTagName('html')[0].className = document.getElementsByTagName('html')[0].className.replace('no-js', 'js');
if (supportElementById() && supportElementsByClassName() && supportAddEventListener()) {
if (onLoadDiakritikos) {
var langBrowserUser = navigator.language || navigator.userLanguage;
var langSplit = langBrowserUser.split('-');
d10sLang = langSplit[0];
var d10sText = 'data-text-';
d10sText += d10sLang;
d10sTranslateText(d10sText);
var d10sImage = 'data-image-';
d10sImage += d10sLang;
d10sTranslateImage(d10sImage);
}
var d10sListLangs = document.getElementsByClassName('language-d10s');
for (var i=0; i < d10sListLangs.length; i++) {
d10sSelectLang(d10sListLangs);
}
} else {
document.getElementsByTagName('html')[0].className += ' ';
document.getElementsByTagName('html')[0].className += 'no-d10s';
}
displayAlert();
</script>
</body>
</html>
<!DOCTYPE html><!-- Do not use! -->
<html>
<head>
<meta charset="utf-8" />
<title id="title" class="translate-d10s" data-text-fr="Calendrier">Calendar</title>
</head>
<body>
<button id="es" class="language-d10s">ES</button>
<button id="fr" class="language-d10s">FR</button>
<button id="en" class="language-d10s">EN</button>
<p id="days" class="translate-d10s-text" data-text-es="Domingo, Lunes, Martes, Miércoles, Jueves, Viernes, Sábado" data-text-fr="Dimanche, Lundi, Mardi, Mercredi, Jeudi, Vendredi, Samedi">Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday</p>
<p id="monthes" class="translate-d10s-text" data-text-es="Enero, Febrero, Marzo, Abril, Mayo, Junio, Julio, Agosto, Septiembre, Octubre, Noviembre, Diciembre" data-text-fr="Janvier, février, mars, avril, mai, juin, juillet, août, septembre, octobre, novembre, décembre">January, February, March, April, May, June, July, August, September, October, November, December</p>
<p id="seasons" class="translate-d10s-text">Winter, Spring, Summer, Autumn</p>
</div>
<script>
function d10sSelectLang(d10sListLangs) {
d10sListLangs[i].addEventListener('click', function() {
var d10sText = 'data-text-';
d10sText += this.id;
d10sTranslateText(d10sText);
});
}
function d10sTranslateText(d10sText) {
var texts = document.querySelectorAll('.translate-d10s-text');
for (var i = 0; i < texts.length; ++i) {
var item = texts[i].id;
/* Start deal with dataset for example */
var element = document.querySelector('#' + item);
console.log(element.dataset.textFr);
/* End deal with dataset */
var content = document.getElementById(item).innerHTML;
if (!document.getElementById(item).hasAttribute('data-text-d10s')) {
document.getElementById(item).setAttribute('data-text-d10s', content);
}
var target;
if (document.getElementById(item).hasAttribute(d10sText)) {
target = document.getElementById(item).getAttribute(d10sText);
} else {
target = document.getElementById(item).getAttribute('data-text-d10s');
}
document.getElementById(item).innerHTML = document.getElementById(item).innerHTML.replace(content, target);
}
}
var d10sListLangs = document.getElementsByClassName('language-d10s');
for (var i=0; i < d10sListLangs.length; i++) {
d10sSelectLang(d10sListLangs);
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment