Supposons que vous ayez un périphérique Internet Of Things (IoT) et que vous ayez besoin de fabriquer un produit professionnel. La première interface que l'utilisateur final verra sera la page de configuration WIFI ou l'application associée.

Comment servez-vous une telle page web pour qu'elle soit aussi petite que possible encore professionnelle ?

Site web à page unique

Comme la taille de la flash dans le microcontrôleur est limitée et que vous voulez probablement utiliser les mises à jour Over-The-Air (OTA), les binaires doivent être très petits. Il n'est pas réaliste d'utiliser jQuery ou toute autre grande bibliothèque de javascript (que vous ne pouvez pas servir de l'extérieur de votre microcontrôleur parce qu'il n'est pas encore connecté à Internet).

Donc, vous êtes limité au HTML et CSS et probablement à un javascript super minimal. Typiquement, vous voudrez peut-être un site web fonctionnel sans javascript car cela pourrait être désactivé sur le navigateur (les pages de connection type "Captive Portal" tourne sans javascript).

Comment gérer plusieurs langues pour votre page web ?

Vous pourriez avoir autant de pages web que vous supportez de langues différentes et utiliser l'en-tête du HTTP Accept-Language pour décider laquelle peut être utilisée, mais cela signifie que la page de votre site web est dupliqué pour toutes les langues. Ceci n'est pas acceptable pour un microcontrôleur à mémoire limitée.

Il existe des solutions basées sur Javascript, comme Polyglot qui nécessite de stocker un JSON avec toutes les traductions et AJAX pour charger et appliquer les modifications. Ces solutions sont, AMHA, moches puisque vous obtiendriez une page qui se chargera avec une langue et clignotera dans une autre langue.

C'est un peu comme le FOUC que nous avons eu avec le CSS. Elles échouent également si l'utilisateur ne permet pas le javascript.

La technique que je montre ici est basée uniquement sur le CSS (moins susceptible d'être désactivée).

Le balisage HTML

L'idée de base de cette technique est de stocker tout texte à traduire dans des éléments <var></var>. Ces éléments sont peu utilisés sur la toile mais font partie de la spécification HTML depuis la version 4.

Il est peu probable qu'ils apparaissent quelque part, de sorte que les consacrer à la traduction semble être une bonne idée.

Veuillez noter que vous aurez besoin d'ajouter var { font-style: normal } à votre CSS principal.

Vous marquerez les éléments avec soit un id (comme <var id="title"> Titre ici en anglais</var>) s'ils sont uniques, soit une classe si ce n'est pas le cas.

Ainsi, par exemple, votre balisage HTML ressemblera à :

<body>
<h1><var id='title'>My wonderful project</var></h1>
<ul>
<li><var id='MenuItem1'>Setup</var></li>
<li><var id='MenuItem2'>Firmware download</var></li>
</ul>
<div><a href='aboutUs'><var class='aboutUs'>About us</var></a>
[etc...]

Le CSS

C'est ici que toute l'astuce opère: Il n'y a pas de façon - non javascript - de déclencher la sélection de la langue du document automatiquement.

Cela signifie que soit vous fixez <html lang='fr'> pour l'élément racine et ensuite vous pouvez filtrer cet attribut dans le CSS, mais vous ne pouvez pas supprimer l'attribut et avoir différent sélecteur type :lang(fr) dans votre CSS. Toutefois, le navigateur enverra un en-tête Accept-Language lors de la requête HTTP, de sorte que nous pouvons toujours résoudre le côté serveur en renvoyant un contenu différent basé sur le langage demandé.

Typiquement, dans le CSS intégré de votre page web, vous ajouterez un @import 'trans.css'; en tête (ou utiliser le header<link> dans l'HTML), mais puisque nous voulons économiser de l'espace, le premier est plus petit - donc mieux.

Ensuite, votre serveur web dans le microcontrôleur enverra un fichier spécifique trans.css basé sur la langue acceptée du navigateur.

Typiquement, il n'enverra rien pour l'anglais (puisque c'est la langue par défaut), mais pour une autre langue, il enverra quelque chose comme:

@charset 'utf-8';
var { visibility: hidden; } var:before { visibility: visible; } // Or any other content substitution technique
#title:before { content:'Titre attendu'; }
#MenuItem1:before { content:'Installation';  }
#MenuItem2:before { content:'Téléchargement du firmware';  }
var.aboutUs:before { content:'À propos'; }

Le navigateur téléchargera automatiquement ce CSS et remplacera les éléments. Cette méthode ne fonctionne pas avec les lecteurs d'écran qui liront toujours le texte en anglais, mais la version javascript non plus.

Surcoût

Cette méthode ne nécessite pas de Javascript. Parce que vous utilisez une seule page web, et que la plupart des navigateurs émettent 2 requêtes en parallèle, il devrait télécharger la traduction avant la page web principale, donc pas de FOUC à attendre.

Cette méthode nécessite une table de traduction qui est écrite en CSS, donc le surcoût est légèrement plus grand qu'un dictionnaire en JSON (mais probablement moins que la taille d'un script Javascript qui ferait la substitution).

Typiquement, pour chaque clé à traduire, vous aurez un surcoût de 18 octets (ou 17 si vous utilisez :after), avant compression. Étant donné que ces surcoûts sont identiques pour toutes les traductions, puisqu'ils sont principalement dus aux mêmes mots clés du CSS :before et content:, ils vont bien se compresser par gzip et vous pouvez les servir directement compressés.

Inconvénients

  • Les éléments qui ne peuvent pas contenir d'autres éléments (inline) ne peuvent pas contenir <var>. Vous devrez donc en tenir compte lors de la conception de votre site web.
  • Le contenu initial est toujours là (mais invisible) donc il sera utilisé par les lecteurs d'écran, et l'indexeur de recherche. Comme la page web est peu susceptible d'être diffusée sur Internet, je ne suis pas sûr qu'il s'agisse d'une perte importante.
  • Tout le monde dit que CSS n'est pas fait pour définir le contenu, mais honnêtement, pourquoi ont-ils ajouté la règle content alors?

Article précédent

Articles en relation