ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Homepage 组件国际化指南:基于 next-i18next 的 Widget 翻译与本地化实战

Homepage 组件国际化指南:基于 next-i18next 的 Widget 翻译与本地化实战 Homepage 组件国际化指南基于 next-i18next 的 Widget 翻译与本地化实战【免费下载链接】homepageA highly customizable homepage (or startpage / application dashboard) with Docker and service API integrations.项目地址: https://gitcode.com/GitHub_Trending/ho/homepage本篇指南聚焦 Homepage自托管主页 / 应用仪表盘中自定义 Widget组件的国际化i18n与本地化l10n实现。它面向想要为自己开发的 Widget 接入多语言支持的开发者系统讲解翻译框架的接入方式、翻译字符串的配置流程、内置通用翻译数值格式化与常用文本的用法并结合仓库源码说明这些能力背后的实现原理。读完本文你将能够为任意新增 Widget 正确接入useTranslation、注册英文翻译条目并复用项目内置的字节/速率/百分比/日期等格式化能力从而让 Widget 在多语言环境下正确显示。Widget 翻译体系概览Homepage 中 Widget 内的所有文本与数值内容都应进行翻译与本地化。整个体系的默认语言是英语en其他语言通过 Crowdin 社区协作平台补充各语言的翻译文件统一存放在 public/locales 目录下例如 public/locales/zh-Hans/common.json、public/locales/en/common.json。在技术选型上Homepage 使用next-i18next库来处理翻译。该库提供了一组 hooks 与工具函数帮助开发者本地化自己的 WidgetHomepage 在其基础上还进行了扩展——这一点从 next-i18next.config.js 中注册的自定义 formatter 可以看出后文会详细展开。整个应用在入口 src/pages/_app.jsx 中通过appWithTranslation(MyApp, nextI18nextConfig)包裹根组件将next-i18next与项目配置见 next-i18next.config.jsdefaultLocale: en、locales: [en]、serializeConfig: false注入到全局所有页面与组件因此都能直接使用翻译能力。在组件中接入翻译useTranslation 与 BlockWidget 组件是一个 React 组件翻译接入的核心代码非常简单。官方推荐的写法如下来自 docs/widgets/authoring/translations.mdimport { useTranslation } from next-i18next; import Container from components/services/widget/container; import Block from components/services/widget/block; export default function Component() { const { t } useTranslation(); return ( Container service{service} Block labelyourwidget.key1 / Block labelyourwidget.key2 / Block labelyourwidget.key3 / /Container ); }要点说明useTranslation()返回的t函数负责根据当前语言环境解析翻译 keyBlock labelyourwidget.key1 /中的label就是翻译 keyBlock组件内部会自动对它做翻译当 Widget 处于加载占位状态value未传入时同样通过label渲染文本因此加载态、错误态、正常态都不需要硬编码任何字符串。从源码看src/components/services/widget/block.jsx 中Block组件本身就从next-i18next/pages导入useTranslation并在渲染标签时调用{t(label)}见 block.jsx。注意文档示例使用next-i18next顶层导入而仓库内的实际组件如 src/widgets/adguard/component.jsx普遍使用next-i18next/pages子路径导入useTranslation两者在本项目中均可正常工作。以 AdGuard Widget 的真实实现为例src/widgets/adguard/component.jsxBlock labeladguard.queries value{t(common.number, { value: adguardData.num_dns_queries })} / Block labeladguard.blocked value{t(common.number, { value: adguardData.num_blocked_filtering })} / Block labeladguard.filtered value{t(common.number, { value: filtered })} / Block labeladguard.latency value{t(common.ms, { value: adguardData.avg_processing_time * 1000, style: unit, unit: millisecond })} highlightValue{adguardData.avg_processing_time * 1000} /可以看到文本类内容走label翻译 key数值类内容则交给t(common.xxx, { value })复用内置格式化——这是所有官方 Widget 遵循的统一模式。添加 Widget 自己的翻译字符串要为你的 Widget 添加英文翻译只需两步打开 public/locales/en/common.json在文件列表末尾为你的 Widget 新增一个对象结构如下yourwidget: { key1: Value 1, key2: Value 2, key3: Value 3 }添加后组件中的labelyourwidget.key1就会解析为Value 1。仓库中每个官方 Widget 都在该文件中注册了自己的命名空间例如 public/locales/en/common.json 中的duplicati、docker、ping、siteMonitor等新增时照此追加即可。注意即使你母语是其他语言在仓库中也只需添加英文翻译。等你的 Widget 合并后再通过 Crowdin 平台补充你母语的翻译即可——这是为了保证单一事实来源、避免贡献者在仓库内直接编辑各语言文件造成冲突。关于 key 命名一个值得注意的细节common.json是一个扁平的 JSON 对象common、resources、adguard等都是其中的顶级命名空间。你的 Widget key 不应与既有顶级 key 冲突label中使用的完整路径如yourwidget.key1与 JSON 的嵌套结构一一对应Block组件用t()解析它。复用内置通用翻译Common TranslationsHomepage 提供了一组开箱即用的通用翻译专门用于格式化数值内容、日期等常见元素开发者无需自己实现。数值格式化以下表格原样继承自 docs/widgets/authoring/translations.md列出了全部数值类通用 keyKey示例输出说明common.bytes1,000 B以字节为单位格式化数值common.bits1,000 bit以比特为单位格式化数值common.bbytes1 KiB以二进制字节1024 进制格式化common.bbits1 Kibit以二进制比特1024 进制格式化common.byterate1,000 B/s格式化字节速率common.bibyterate1 KiB/s格式化二进制字节速率common.bitrate1,000 bit/s格式化比特速率common.bibitrate1 Kibit/s格式化二进制比特速率common.percent50%格式化百分比common.number1,000格式化普通数值common.ms1,000 ms以毫秒为单位格式化数值common.date2024-01-01格式化日期common.relativeDate1 day ago格式化相对日期common.duration1 day, 1 hour格式化时长这些 key 在 public/locales/en/common.json 中的实际定义是 i18next 的插值 formatter 语法例如bytes: {{value, bytes}}, bits: {{value, bytes(bits: true)}}, bbytes: {{value, bytes(binary: true)}}, bbits: {{value, bytes(bits: true; binary: true)}}, byterate: {{value, rate(bits: false)}}, bibyterate: {{value, rate(bits: false; binary: true)}}, percent: {{value, percent}}, date: {{value, date}}, relativeDate: {{value, relativeDate}}, duration: {{value, duration}}它们底层的格式化逻辑全部注册在 next-i18next.config.js 中通过i18next.services.formatter.add(...)挂载为 i18next 的自定义 formatter其实现要点如下bytes基于prettyBytes实现代码注释标明其灵感来自 pretty-bytes 工具见 next-i18next.config.js支持bits、binary选项切换 1000/1024 进制与 B/bit 单位并通过toLocaleString(number, locale, options)实现按语言环境的千分位分组rate在字节格式化基础上追加/s后缀且binary决定以 1024 还是 1000 为底数next-i18next.config.jspercent先将数值除以 100 再用Intl.NumberFormat(lng, { style: percent, ... })格式化next-i18next.config.jsdate基于Intl.DateTimeFormat(lng, options)可按语言环境输出日期next-i18next.config.jsrelativeDate基于Intl.RelativeTimeFormat实现相对时间如 1 day ago内部按秒/分钟/小时/天/周/月/年选取合适粒度next-i18next.config.jsduration将秒数拆分为月/天/小时/分钟/秒并复用t(common.months)、t(common.days)、t(common.hours)、t(common.minutes)、t(common.seconds)这些本地化单位后缀拼接输出next-i18next.config.js。文本翻译常用文本类 key 如下Key翻译说明resources.cpuCPUCPU 使用率resources.memMEM内存使用率resources.totalTotal总资源resources.freeFree空闲资源resources.usedUsed已用资源resources.loadLoad负载值resources.tempTEMP温度值resources.maxMax最大值resources.uptimeUP运行时长这些 key 在 public/locales/en/common.json 的resources命名空间下有完整定义可供任何 Widget 直接引用。真实 Widget 中的本地化实践仓库中的资源类 Widget 是复用上述通用翻译的最佳范例src/components/widgets/resources/memory.jsx 使用t(common.bytes, { value: data.memory.available, maximumFractionDigits: 1, binary: true })——传入binary: true与小数位限制输出如1.2 GiB这样的二进制字节格式src/components/widgets/resources/network.jsx 使用t(common.byterate, { value: data.network.tx_sec })显示网络速率并用↑/↓区分上传/下载方向src/components/widgets/resources/uptime.jsx 使用t(common.duration, { value: data.uptime })将秒数转换为人类可读的时长。这些调用说明一个通用模式把原始数值传给t(common.xxx, { value, ...options })由内置 formatter 负责语言环境相关的格式化而不是在组件里手动拼字符串。非 React 场景直接使用 i18next 实例除组件 hook 外Homepage 还扩展了直接使用 i18next 实例的方式。例如 src/components/services/kubernetes-status.jsx 中直接import { t } from i18next在普通函数体内调用t(docker.unknown)、t(docker.error)等 key。这适用于无法使用useTranslationhook 的场景如普通函数、非组件模块是仓库对 next-i18next 能力的一种扩展用法。开发与测试建议为 Widget 接入翻译后请遵循以下实践详见 docs/widgets/authoring/getting-started.md 的测试章节组件内不要出现硬编码文本所有文本与数值一律走label或t()只添加英文翻译即使你懂其他语言也仅在common.json中添加英文条目其余语言交给 Crowdin编写组件测试Widget 应包含component.test.jsx覆盖加载占位状态、错误状态与正常渲染路径并断言翻译 key 能正确渲染仓库中的测试工具见 src/test-utils/widget-assertions.js 与 src/test-utils/render-with-providers.jsx保持命名空间唯一common.json是全局共享文件你的 Widget key 命名空间不要与其他 Widget 冲突。更多关于 Widget 编写规范的内容可参考 docs/widgets/authoring/index.md、docs/widgets/authoring/component.md 与 docs/widgets/authoring/metadata.md。小结Homepage 的 Widget 国际化体系可以总结为三条主线接入组件内通过useTranslation获得t函数Block的label即翻译 key注册在 public/locales/en/common.json 末尾追加自己的命名空间对象只需提供英文复用数值与日期格式化直接引用common.bytes、common.byterate、common.percent、common.duration等内置 key底层由 next-i18next.config.js 注册的 i18next formatter 按语言环境统一处理。遵循这套约定你开发的 Widget 就能与 Homepage 现有的 40 语言生态无缝衔接在任意语言环境下都保持一致的展示质量。【免费下载链接】homepageA highly customizable homepage (or startpage / application dashboard) with Docker and service API integrations.项目地址: https://gitcode.com/GitHub_Trending/ho/homepage创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表