Bonjour, habravchane!
Dans cet article, je parlerai d'une solution simple au problème de la gestion du texte et de la localisation dans une application Web, que vous pouvez implémenter vous-même ou utiliser une application prête à l'emploi.

Je souhaite depuis longtemps partager mes propres pensées et expériences ... et, bien sûr, parler pour la vie.
ContexteÉvidemment, des solutions pour gérer le texte et la localisation existent déjà, mais elles ne me convenaient pas pour diverses raisons: encombrantes, peu pratiques à utiliser, non adaptées, ne correspondent pas à ma vision de résoudre ce problème, manquent de fonctionnalités.
De plus, je n'aime pas vraiment les bibliothèques tierces en raison de leur tendance à croître (c'est quand nous n'avons besoin que d'une petite partie de toutes les fonctionnalités).
L'entreprise dans laquelle je travaille a sa propre solution, mais, à mon avis, elle est également loin d'être idéale. Et la nécessité d'une rétrocompatibilité avec les anciennes versions complique inutilement les choses.
À un moment donné, je voulais quelque chose de simple, facile, compréhensible et extensible à l'infini pour différentes tâches.
Énoncé du problème
Tout semble clair ici. Ou pas? Pensons à ce que nous aimerions.
Nous devons en quelque sorte obtenir des textes localisés. Les textes peuvent contenir des variables. Les variables peuvent-elles également être localisées?! En théorie, oui. Et si la variable est une date ou un nombre?! Plus le support de démarque. Et enfin, une solution au cas où le texte ne serait pas trouvé.
Implémentation
La base sera un objet simple, où la clé est le code texte, et la valeur est le texte réel dont vous avez besoin, rien de compliqué:
const textsBundle = { 'button.open': 'Open', 'button.save': 'Save', }; function TextManager(texts) { this.getText = function(code) { return texts[code]; }; } const textManager = new TextManager(textsBundle); textManager.getText('button.open');
Un peu sur le nom des clésLe nom des clés est un sujet distinct. Il vaut mieux se mettre immédiatement d’accord sur une seule option, sinon des touches différentes «remueront» :). Il n'y a pas de solution unique, choisissez ce que vous pensez être plus pratique et plus cohérent avec le projet. Personnellement, j'aime le premier:
'button.open.label'
'button.open.help_text'
ou
'button.label.open'
'button.help_text.open'
ou
'label.button.open'
'help_text.button.open'
Ensuite, nous avons besoin d'un mécanisme qui serait capable d'effectuer une sorte de manipulation du texte avant qu'il ne donne le résultat final, par exemple, insérer des paramètres. Et puis j'ai eu une idée intéressante - et si nous utilisons un middleware pour manipuler du texte? Après tout, je n'ai pas vu de telles décisions ... eh bien, ou j'ai mal regardé :)
Nous décidons des exigences pour le middleware: à l'entrée, le middleware acceptera le texte et les paramètres, et donnera le texte résultant, après les manipulations nécessaires.
Le premier middleware recevra le texte d'origine et les suivants recevront le texte du middleware précédent. Ajoutons le code manquant:
function TextManager(texts, middleware) { function applyMiddleware(text, parameters, code) { if (!middleware) return text; return middleware.reduce((prevText, middlewareItem) => middlewareItem(prevText, parameters, code), text); } this.getText = function(code, parameters) { return applyMiddleware(texts[code], parameters, code); }; }
TextManager peut sortir du texte par son code. Il peut également être étendu à l'aide d'un middleware, ce qui ouvre de nombreuses possibilités, par exemple:
- gérer le cas où le texte est introuvable
- utilisation de paramètres dans le texte
- localisation des paramètres
- utiliser la démarque
- blindage de texte, etc.
Pratique
Nous allons écrire quelques middleware nécessaires. Vous en aurez besoin à 100%.
InsertParams
Permet l'utilisation de paramètres dans les textes. Par exemple, nous devons afficher le texte "Bonjour {{nom d'utilisateur}}". Le middleware suivant fournira ceci:
function InsertParams(text, parameters) { if (!text) return text; if (!parameters) return text; let nextText = text; for (let key in parameters) { if (parameters.hasOwnProperty(key)) { nextText = text.replace('{{' + key + '}}', parameters[key]); } } return nextText; }
UseCodeIfNoText
Vous permet de renvoyer le code texte, au lieu de undefined
, si le texte est introuvable:
function UseCodeIfNoText(text, parameters, code) { return text ? text : code; }
Au total, nous recevons environ l'utilisation suivante:
const textsBundle = { 'text.hello': 'Hello', 'text.hello_with_numeric_parameter': 'Hello {{0}}', 'text.hello_with_named_parameter': 'Hello {{username}}', }; const textManager = new TextManager(textsBundle, [InsertParams, UseCodeIfNoText]); textManager.getText('nonexistent.code')
Exemple d'application React
Tout d'abord, initialisez au niveau supérieur TextManager
et ajoutez des textes.
À mon avis, il est préférable d'extraire des textes du serveur, mais pour plus de simplicité, je ne le ferai pas.
const textsBundle = { 'text.hello': 'Hello {{username}}' } function TextManagerProvider({ children }) { const textManager = new TextManager(textsBundle, [InsertParams, UseCodeIfNoText]); return ( <TextManagerContext.Provider value={textManager}> {children} </TextManagerContext.Provider> ) }
Ensuite, dans le composant, textManager
utilisons textManager
, par exemple, en utilisant un crochet, et nous obtenons le texte souhaité par code.
function SayHello({ username }) { const textManager = useContext(TextManagerContext); return ( <div> {textManager.getText('text.hello', { username })} </div> ) }
Localisation
Vous demandez: "Qu'est-ce que la localisation a à voir avec cela?".
Tout est très simple - lors du changement de langue, créez une nouvelle instance de TextManager
, ajoutez des textes et obtenez immédiatement le résultat.
L'avant-dernier chapitre :)
Comme vous pouvez le voir dans les exemples, l'utilisation est extrêmement simple et grâce au middleware, vous pouvez étendre la fonctionnalité indéfiniment.
J'ai posté mon implémentation sur github et j'ai l'intention de développer davantage le gestionnaire de texte . Utilisez, offrez des améliorations et, comme on dit, vous êtes les bienvenus! :)
En conclusion
J'ai donc réalisé mon désir de daaaaavnee - a écrit un article sur Habr. J'espère vraiment que cet article sera utile et plaira à la communauté.
Merci de votre attention.