Localisez les applications de relance à l'aide d'I18Next
Dans mon article précédent, j'ai présenté Stimulus - un framework JavaScript simple créé par Basecamp. Aujourd'hui, je vais discuter de l'internationalisation des applications Stimulus, car le framework ne fournit aucun outil d'internationalisation prêt à l'emploi. L'internationalisation est une étape importante, en particulier lorsque votre application est utilisée par des personnes du monde entier. Une compréhension de base de la manière de procéder à l'internationalisation peut donc s'avérer très utile.
Bien sûr, c'est à vous de décider quelle solution d'internationalisation mettre en œuvre, que ce soit jQuery.I18n, Polyglot ou autre chose. Dans ce didacticiel, je souhaite vous montrer un framework I18n populaire appelé I18next, qui possède de nombreuses fonctionnalités intéressantes et fournit de nombreux plugins tiers supplémentaires pour simplifier davantage le processus de développement. Même avec toutes ces fonctionnalités, I18next n’est pas un outil complexe et vous n’avez pas besoin d’étudier une tonne de documentation pour commencer.
Dans cet article, vous apprendrez comment activer la prise en charge I18n dans votre application Stimulus à l'aide de la bibliothèque I18next. Plus précisément, nous aborderons :
- Prochaine configuration I18
- Traduisez les fichiers et chargez-les de manière asynchrone
- Effectuez la traduction et traduisez la page entière en une seule fois
- Gérer les informations sur le pluriel et le genre
- Basculez entre les paramètres régionaux et conservez les paramètres régionaux sélectionnés dans les paramètres GET
- Définissez les paramètres régionaux en fonction des préférences de l'utilisateur
Le code source est disponible dans le référentiel GitHub du didacticiel.
Application de stimulation guidée
Tout d'abord, clonons le projet Stimulus Starter et installons toutes les dépendances à l'aide du gestionnaire de packages Yarn :
git clone https://github.com/stimulusjs/stimulus-starter.git cd stimulus-starter yarn install
Nous allons créer une application Web simple pour charger des informations sur les utilisateurs enregistrés. Pour chaque utilisateur, nous afficherons son nom de connexion et le nombre de photos qu'il a téléchargées jusqu'à présent (peu importe quelles sont ces photos).
De plus, nous fournirons un sélecteur de langue en haut de la page. Une fois que vous avez sélectionné une langue, l'interface doit être traduite immédiatement sans qu'il soit nécessaire de recharger la page. De plus, l'URL doit être ajoutée avec un paramètre ?locale
GET spécifiant les paramètres régionaux actuellement utilisés. Bien entendu, si ce paramètre est fourni lors du chargement de la page, la langue correcte doit être définie automatiquement.
D'accord, allons-y et restituons notre utilisateur. Ajoutez les lignes de code suivantes au fichier public/index.html :
<div data-controller="users" data-users-url="/api/users/index.json"></div>
Ici, nous utilisons le contrôleur users
et fournissons une URL pour charger l'utilisateur. Dans une application réelle, nous pourrions avoir un script côté serveur qui récupère l'utilisateur de la base de données et répond avec JSON. Cependant, pour ce tutoriel nous mettrons simplement toutes les données nécessaires dans le fichier public/api/users/index.json :
[ { "login": "johndoe", "photos_count": "15", "gender": "male" }, { "login": "annsmith", "photos_count": "20", "gender": "female" } ]
Créez maintenant un nouveau fichier src/controllers/users_controller.js :
import { Controller } from "stimulus" export default class extends Controller { connect() { this.loadUsers() } }
Une fois le contrôleur connecté au DOM, on charge l'utilisateur de manière asynchrone à l'aide de la méthode loadUsers()
:
loadUsers() { fetch(this.data.get("url")) .then(response => response.text()) .then(json => { this.renderUsers(json) }) }
Cette méthode envoie une requête de récupération à l'URL donnée, obtient la réponse et présente enfin à l'utilisateur :
renderUsers(users) { let content = '' JSON.parse(users).forEach((user) => { content += `<div>Login: ${user.login}<br>Has uploaded ${user.photos_count} photo(s)</div><hr>` }) this.element.innerHTML = content }
renderUsers()
依次解析 JSON,构造一个包含所有内容的新字符串,最后将此内容显示在页面上(this.element
是将返回控制器连接到的实际 DOM 节点,在我们的例子中是 div
).
I18Suivant
Nous allons maintenant passer à l'intégration d'I18next dans notre application. Ajoutez deux bibliothèques à notre projet : I18next lui-même et un plugin pour permettre le chargement asynchrone des fichiers de traduction depuis le backend :
yarn add i18next i18next-xhr-backend
Nous stockerons tous les éléments liés à I18next dans un fichier src/i18n/config.js séparé, alors créez-le maintenant :
import i18next from 'i18next' import I18nXHR from 'i18next-xhr-backend' const i18n = i18next.use(I18nXHR).init({ fallbackLng: 'en', whitelist: ['en', 'ru'], preload: ['en', 'ru'], ns: 'users', defaultNS: 'users', fallbackNS: false, debug: true, backend: { loadPath: '/i18n/{{lng}}/{{ns}}.json', } }, function(err, t) { if (err) return console.error(err) }); export { i18n as i18n }
Voyons ce qui se passe ici de haut en bas :
-
use(I18nXHR)
Activez le plugin i18next-xhr-backend. -
fallbackLng
Dites-lui d'utiliser l'anglais comme langue de secours. -
whitelist
Seuls les paramètres anglais et russe sont autorisés. Bien entendu, vous pouvez choisir n’importe quelle autre langue. -
preload
Demande de précharger les fichiers de traduction depuis le serveur au lieu de les charger lorsque la langue correspondante est sélectionnée. -
ns
表示“命名空间”,接受字符串或数组。在此示例中,我们只有一个命名空间,但对于较大的应用程序,您可以引入其他命名空间,例如admin
、cart
、profile
Attendez. Un fichier de traduction distinct doit être créé pour chaque espace de noms. -
defaultNS
définitdefaultNS
将users
comme espace de noms par défaut. -
fallbackNS
Désactivez le repli de l'espace de noms. -
debug
允许在浏览器的控制台中显示调试信息。具体来说,它会说明加载哪些翻译文件、选择哪种语言等。您可能希望在将应用程序部署到生产环境之前禁用此设置。 -
backend
为 I18nXHR 插件提供配置并指定从何处加载翻译。请注意,路径应包含区域设置的标题,而文件应以命名空间命名并具有 .json 扩展名 -
function(err, t)
是当 I18next 准备好时(或当出现错误时)运行的回调。
接下来,让我们制作翻译文件。俄语翻译应放入 public/i18n/ru/users.json 文件中:
{ "login": "Логин" }
login
这里是翻译键,而 Логин
是要显示的值。
英文翻译应该转到 public/i18n/en/users.json 文件:
{ "login": "Login" }
为了确保 I18next 正常工作,您可以将以下代码行添加到 i18n/config.js 文件内的回调中:
// config goes here... function(err, t) { if (err) return console.error(err) console.log(i18n.t('login')) }
在这里,我们使用一个名为 t
的方法,意思是“翻译”。该方法接受翻译键并返回相应的值。
但是,我们可能有很多 UI 部分需要翻译,而使用 t
方法来翻译会非常乏味。相反,我建议您使用另一个名为 loc-i18next 的插件,它允许您一次翻译多个元素。
一次性翻译
安装loc-i18next插件:
yarn add loc-i18next
将其导入src/i18n/config.js文件的顶部:
import locI18next from 'loc-i18next'
现在提供插件本身的配置:
// other config const loci18n = locI18next.init(i18n, { selectorAttr: 'data-i18n', optionsAttr: 'data-i18n-options', useOptionsAttr: true }); export { loci18n as loci18n, i18n as i18n }
这里有几点需要注意:
-
locI18next.init(i18n)
基于之前定义的 I18next 实例创建一个新的插件实例。 -
selectorAttr
指定使用哪个属性来检测需要本地化的元素。基本上,loc-i18next 将搜索此类元素并使用data-i18n
属性的值作为翻译键。 -
optionsAttr
指定哪个属性包含附加翻译选项。 -
useOptionsAttr
指示插件使用其他选项。
我们的用户正在异步加载,因此我们必须等到此操作完成,然后才执行本地化。现在,我们简单地设置一个计时器,在调用 localize()
方法之前等待两秒——当然,这是一个临时的 hack。
import { loci18n } from '../i18n/config' // other code... loadUsers() { fetch(this.data.get("url")) .then(response => response.text()) .then(json => { this.renderUsers(json) setTimeout(() => { // <--- this.localize() }, '2000') }) }
编写 localize()
方法本身的代码:
localize() { loci18n('.users') }
如您所见,我们只需要将选择器传递给 loc-i18next 插件即可。内部的所有元素(设置了 data-i18n
属性)都将自动本地化。
现在调整 renderUsers
方法。现在,我们只翻译“Login”一词:
renderUsers(users) { let content = '' JSON.parse(users).forEach((user) => { content += `<div class="users">ID: ${user.id}<br><span data-i18n="login"></span>: ${user.login}<br>Has uploaded ${user.photos_count} photo(s)</div><hr>` }) this.element.innerHTML = content }
不错!重新加载页面,等待两秒钟,并确保每个用户都显示“登录”字样。
复数和性别
我们对部分界面进行了本地化,这真的很酷。尽管如此,每个用户还有两个字段:上传的照片数量和性别。由于我们无法预测每个用户将拥有多少张照片,因此应根据给定的数量将“照片”一词正确地复数化。为此,我们需要之前配置的 data-i18n-options
属性。要提供计数,应为 data-i18n-options
分配以下对象:{ "count": YOUR_COUNT }
。
性别信息也应考虑在内。英语中的“uploaded”一词可以适用于男性和女性,但在俄语中它要么变成“загрузил”或“загрузила”,所以我们再次需要 data-i18n-options
,其中有 { "context": "GENDER" }
作为值。顺便请注意,您可以利用此上下文来完成其他任务,而不仅仅是提供性别信息。
renderUsers(users) { let content = '' JSON.parse(users).forEach((user) => { content += `<div class="users"><span data-i18n="login"></span>: ${user.login}<br><span data-i18n="uploaded" data-i18n-options="{ 'context': '${user.gender}' }"></span> <span data-i18n="photos" data-i18n-options="{ 'count': ${user.photos_count} }"></span></div><hr>` }) this.element.innerHTML = content }
现在更新英文翻译:
{ "login": "Login", "uploaded": "Has uploaded", "photos": "one photo", "photos_plural": "{{count}} photos" }
这里没什么复杂的。由于对于英语,我们不关心性别信息(即上下文),因此翻译键应该只是 uploaded
。为了提供正确的复数翻译,我们使用 photos
和 photos_plural
键。 {{count}}
部分为插值,将替换为实际数字。
至于俄语,事情就更复杂了:
{ "login": "Логин", "uploaded_male": "Загрузил уже", "uploaded_female": "Загрузила уже", "photos_0": "одну фотографию", "photos_1": "{{count}} фотографии", "photos_2": "{{count}} фотографий" }
首先,请注意,我们有两个可能的上下文的 uploaded_male
和 uploaded_female
键。接下来,俄语中的复数规则也比英语中更复杂,因此我们必须提供不是两个而是三个可能的短语。 I18next 支持多种开箱即用的语言,这个小工具可以帮助您了解应该为给定语言指定哪些复数键。
切换区域设置
我们已经完成了应用程序的翻译,但用户应该能够在区域设置之间切换。因此,向 public/index.html 文件添加一个新的“语言切换器”组件:
<ul data-controller="languages" class="switcher"></ul>
在 src/controllers/languages_controller.js 文件中制作相应的控制器:
import { Controller } from "stimulus" import { i18n, loci18n } from '../i18n/config' export default class extends Controller { initialize() { let languages = [ {title: 'English', code: 'en'}, {title: 'Русский', code: 'ru'} ] this.element.innerHTML = languages.map((lang) => { return `<li data-action="click->languages#switchLanguage" data-lang="${lang.code}">${lang.title}</li>` }).join('') } }
这里我们使用 initialize()
回调来显示支持的语言列表。每个 li
都有一个 data-action
属性,该属性指定单击元素时应触发的方法(在本例中为 switchLanguage
)。
现在添加 switchLanguage()
方法:
switchLanguage(e) { this.currentLang = e.target.getAttribute("data-lang") }
它只是获取事件的目标并获取 data-lang
属性的值。
我还想为 currentLang
属性添加 getter 和 setter:
get currentLang() { return this.data.get("currentLang") } set currentLang(lang) { if(i18n.language !== lang) { i18n.changeLanguage(lang) } if(this.currentLang !== lang) { this.data.set("currentLang", lang) loci18n('body') this.highlightCurrentLang() } }
getter 非常简单——我们获取当前使用的语言的值并返回它。
setter 更复杂。首先,如果当前设置的语言与所选语言不相等,我们使用 changeLanguage
方法。此外,我们将新选择的语言环境存储在 data-current-lang
属性(在 getter 中访问)下,使用 loc-i18next 插件本地化 HTML 页面的主体,最后突出显示当前使用的区域设置。
让我们编写 highlightCurrentLang()
的代码:
highlightCurrentLang() { this.switcherTargets.forEach((el, i) => { el.classList.toggle("current", this.currentLang === el.getAttribute("data-lang")) }) }
这里我们迭代区域设置切换器的数组,并将它们的 data-lang
属性的值与当前使用的区域设置的值进行比较。如果值匹配,则为切换器分配 current
CSS 类,否则删除该类。
为了使 this.switcherTargets
构建工作,我们需要按以下方式定义刺激目标:
static targets = [ "switcher" ]
此外,为 li
s 添加值为 switcher
的 data-target
属性:
initialize() { // ... this.element.innerHTML = languages.map((lang) => { return `<li data-action="click->languages#switchLanguage" data-target="languages.switcher" data-lang="${lang.code}">${lang.title}</li>` }).join('') // ... }
另一个需要考虑的重要事项是翻译文件可能需要一些时间来加载,我们必须等待此操作完成才能允许切换区域设置。因此,让我们利用 loaded
回调:
initialize() { i18n.on('loaded', (loaded) => { // <--- let languages = [ {title: 'English', code: 'en'}, {title: 'Русский', code: 'ru'} ] this.element.innerHTML = languages.map((lang) => { return `<li data-action="click->languages#switchLanguage" data-target="languages.switcher" data-lang="${lang.code}">${lang.title}</li>` }).join('') this.currentLang = i18n.language }) }
最后,不要忘记从 loadUsers()
方法中删除 setTimeout
:
loadUsers() { fetch(this.data.get("url")) .then(response => response.text()) .then(json => { this.renderUsers(json) this.localize() }) }
在 URL 中保留区域设置
切换语言环境后,我想在包含所选语言代码的 URL 中添加 ?lang
GET 参数。在 History API 的帮助下,可以轻松地添加 GET 参数而不重新加载页面:
set currentLang(lang) { if(i18n.language !== lang) { i18n.changeLanguage(lang) window.history.pushState(null, null, `?lang=${lang}`) // <--- } if(this.currentLang !== lang) { this.data.set("currentLang", lang) loci18n('body') this.highlightCurrentLang() } }
检测区域设置
我们今天要实现的最后一件事是能够根据用户的偏好设置区域设置。一个名为 LanguageDetector 的插件可以帮助我们解决这个任务。添加新的 Yarn 包:
yarn add i18next-browser-languagedetector
在 i18n/config.js 文件中导入 LanguageDetector
:
import LngDetector from 'i18next-browser-languagedetector'
现在调整配置:
const i18n = i18next.use(I18nXHR).use(LngDetector).init({ // <--- // other options go here... detection: { order: ['querystring', 'navigator', 'htmlTag'], lookupQuerystring: 'lang', } }, function(err, t) { if (err) return console.error(err) });
order
选项列出了插件应尝试的所有技术(按重要性排序),以便“猜测”首选区域设置:
-
querystring
表示检查包含区域设置代码的 GET 参数。 -
lookupQuerystring
设置要使用的 GET 参数的名称,在我们的例子中是lang
。 -
navigator
表示从用户的请求中获取语言环境数据。 -
htmlTag
涉及从html
标记的lang
属性获取首选区域设置。
结论
在本文中,我们介绍了 I18next——一种轻松翻译 JavaScript 应用程序的流行解决方案。您已经学习了如何将 I18next 与 Stimulus 框架集成、配置它以及以异步方式加载翻译文件。此外,您还了解了如何在区域设置之间切换以及如何根据用户的偏好设置默认语言。
I18next 有一些额外的配置选项和许多插件,因此请务必浏览其官方文档以了解更多信息。另请注意,Stimulus 不会强制您使用特定的本地化解决方案,因此您也可以尝试使用 jQuery.I18n 或 Polyglot 等解决方案。
C'est tout pour aujourd'hui ! Merci d'avoir lu et à la prochaine fois.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Outils d'IA chauds

Undresser.AI Undress
Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover
Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool
Images de déshabillage gratuites

Clothoff.io
Dissolvant de vêtements AI

AI Hentai Generator
Générez AI Hentai gratuitement.

Article chaud

Outils chauds

Bloc-notes++7.3.1
Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1
Puissant environnement de développement intégré PHP

Dreamweaver CS6
Outils de développement Web visuel

SublimeText3 version Mac
Logiciel d'édition de code au niveau de Dieu (SublimeText3)

WordPress est facile pour les débutants de commencer. 1. Après se connecter à l'arrière-plan, l'interface utilisateur est intuitive et le tableau de bord simple fournit tous les liens de fonction nécessaires. 2. Les opérations de base incluent la création et l'édition de contenu. L'éditeur WYSIWYG simplifie la création de contenu. 3. Les débutants peuvent étendre les fonctions du site Web via des plug-ins et des thèmes, et la courbe d'apprentissage existe mais peut être maîtrisée par la pratique.

WordPressisGoodForvirontuallyAnyWebprojectDuetOtsSversatityAsacms.itexcelsin: 1) une convivialité, permettant à la manière

Peut apprendre WordPress dans les trois jours. 1. Master les connaissances de base, telles que les thèmes, les plug-ins, etc. 2. Comprenez les fonctions principales, y compris les principes d'installation et de travail. 3. Apprenez l'utilisation de base et avancée à travers des exemples. 4. Comprendre les techniques de débogage et les suggestions d'optimisation des performances.

Wix convient aux utilisateurs qui n'ont aucune expérience de programmation, et WordPress convient aux utilisateurs qui souhaitent plus de capacités de contrôle et d'extension. 1) Wix fournit des éditeurs de glisser-déposer et des modèles riches, ce qui facilite la création d'un site Web rapidement. 2) En tant que CMS open source, WordPress possède un énorme écosystème communautaire et plug-in, soutenant la personnalisation et l'expansion approfondies.

WordPress lui-même est gratuit, mais il en coûte supplémentaire à utiliser: 1. WordPress.com propose un package allant du gratuit à payant, avec des prix allant de quelques dollars par mois à des dizaines de dollars; 2. WordPress.org nécessite l'achat d'un nom de domaine (10-20 dollars américains par an) et des services d'hébergement (5-50 dollars américains par mois); 3. La plupart des plug-ins sont gratuits, et le prix payant se situe entre des dizaines et des centaines de dollars; En choisissant le bon service d'hébergement, en utilisant des plug-ins et des thèmes raisonnablement, et en maintenant et en maintenant régulièrement, le coût de WordPress peut être efficacement contrôlé et optimisé.

Les gens choisissent d'utiliser WordPress en raison de son pouvoir et de sa flexibilité. 1) WordPress est un CMS open source avec une forte facilité d'utilisation et une évolutivité, adaptée à divers besoins en site Web. 2) Il a des thèmes et des plugins riches, un énorme écosystème et un fort soutien communautaire. 3) Le principe de travail de WordPress est basé sur des thèmes, des plug-ins et des fonctions de base, et utilise PHP et MySQL pour traiter les données, et prend en charge l'optimisation des performances.

WordPress est un système de gestion de contenu (CMS). Il fournit une gestion de contenu, une gestion des utilisateurs, des thèmes et des capacités de plug-in pour prendre en charge la création et la gestion du contenu du site Web. Son principe de travail comprend la gestion des bases de données, les systèmes de modèles et l'architecture du plug-in, adaptés à une variété de besoins, des blogs aux sites Web d'entreprise.

La version principale de WordPress est gratuite, mais d'autres frais peuvent être engagés pendant l'utilisation. 1. Les noms de domaine et les services d'hébergement nécessitent un paiement. 2. Des thèmes et des plug-ins avancés peuvent être facturés. 3. Les services professionnels et les fonctionnalités avancées peuvent être facturés.
