i18n 国际化
简介
NitaiPage 的国际化基于 vue-i18n 实现,基础字典统一放在 public/basicLanguageSetting.json,key 保持 @global:xxx 的格式,与插件生态共用同一份字典
页面文本的翻译与插件词条的注入由 src/core/npp/pluginI18n.js 负责,对外提供 window.i18n.addTranslationEntries() 供翻译插件使用
功能说明
实时翻译
- 支持翻译 HTML 属性(placeholder、title、alt)
- 监听 DOM 变化,实时翻译新增的文本节点
- 支持跳过特定元素(
translate="none")及其所有子元素
字典
- 基础字典在应用挂载前 fetch 并装载,避免出现像
@global:这样的原始 key - 字典格式:
'@global:xxx': '译文' - 替换时按 key 长度从长到短,避免短 key 抢先匹配长 key
- 找不到词条时回退显示 key 本身,便于发现漏译
API
addTranslationEntries(entries)
用于批量注入翻译词条
参数:
entries(Object) - 翻译条目对象,格式为{ '@global:xxx': '译文', ... }
返回值:
boolean- 注入成功返回 true,参数不合法返回 false
这是个同步方法,直接调用即可。
示例:
javascript
const success = window.i18n.addTranslationEntries({
'@yourPluginTextPart:a-part-of-the-plugin-text1': '你好',
'@yourPluginTextPart:a-part-of-the-plugin-text2': '世界',
'@yourPluginTextPart:a-part-of-the-plugin-text3': '设置',
'@yourPluginTextPart:a-part-of-the-plugin-text4': '保存'
});
if (success) {
console.log('翻译条目添加成功');
}注意事项
- 词条会合并进当前语言的消息表,同名 key 会被覆盖
- 合并后会自动重扫一遍已有 DOM,因此后到的词条同样生效
- 为了避免与其它插件的 key 冲突,建议在 key 前添加插件名称前缀(如
@yourPluginTextPart:)
字典存储
基础字典放在 public/basicLanguageSetting.json,应用启动时 fetch 并交给 vue-i18n,不写入 IndexedDB
翻译插件的词条通过 addTranslationEntries() 合并进 vue-i18n 的当前语言。 翻译插件本身(@type translate)是普通插件,代码保存在插件源码库中,每次启动随插件一起加载并重新注入词条
用户设置
自动安装翻译插件开关
开启后在安装新的插件时,自动安装对应的翻译
工作流
装载基础字典
- 应用挂载前 fetch
public/basicLanguageSetting.json,交给 vue-i18n - 这一步为了保证首屏不会出现像
@global:这样的原始 key
- 应用挂载前 fetch
检测浏览器语言
- 读取
navigator.languages或navigator.language,取第一个有效的语言代码 - 默认回退到
en-US
- 读取
安装翻译插件(首次访问)
- 只在刚走完引导页时安装一次,之后不再重复检查
- 下载
https://nppdb.nitai.cc/translateGlobal-{langCode}.js - 作为普通插件存入插件源码库,随插件一起加载并注入词条
- 在 localStorage 记录
installedTranslationLang
回退
- 目标语言下载失败时先尝试
translateGlobal-en-US.js - 仍失败则标记为
basic,此时只有基础字典生效
- 目标语言下载失败时先尝试
示例
制作翻译插件
javascript
// ==Npplication==
// @name ...
// @id ...
// @version 1.0.0
// @type translate
// @translates language
// @description 设置全局...
// @author ...
// @icon ...
// @setting false
// ==/Npplication==
// localStorage.setItem('autoInstallTranslationGlobal', 'language'); //仅全局翻译插件需要设置,如果你是为其它插件制作翻译插件,请删除这一行
// 添加字典
(function () {
const translateEntries = {...};
if (typeof window !== 'undefined' && window.i18n && window.i18n.addTranslationEntries) {
window.i18n.addTranslationEntries(translateEntries);
}
})();