扩展 jQurey.i18n.properties 的能力来向 vue-i18n 靠齐
jQuery.i18n.properties 是 jQuery 老项目的国际化框架,其实国际化方案本质上都大同小异,都是需要用翻译函数包裹词条,然后根据词条文件来进行翻译
就是使用上与其他框架不太一样而已
但由于我们已经基于 vue 框架实现了一个国际化自动处理脚本,脚本会自动用全局函数包裹词条,自动提取到 json 文件中
因此,为了让这个老项目也能够用脚本来进行维护,又考虑到最小的改造成本和最小的影响,我们决定扩展 jQuery.i18n.properties 的能力,让它的国际化行为跟 vue-i18n 一致,也就能够用脚本来进行维护了
而且对于团队内的其他新人而言,也没必要去了解 jQuery.i18n.properties,毕竟扩展后的使用方式跟 vue-i18n 基本一样
那么扩展之前,先来看下 jQuery.i18n.properties 这个框架:
全局函数
$.i18n.properties(settings)
国际化初始化函数,用来设置当前语言,资源文件路径
$.i18n.prop(key, ...args)
国际化全局函数,根据 key 值去资源文件里找翻译,后续参数支持占位符替换
当根据 key 值找不到翻译时,会直接返回 key 值
类似 vue-i18n 的 $t
词条文件
.properties 格式文件
也是个键值对的配置文件,只是格式与 json 不一样
【en.properties】
string_login=Login
string_username=username
string_password=password
【zh.properties】
string_login=登录
string_username=账号
string_password=密码
扩展
增加支持 .json 格式的词条文件
重写 $.i18n 的全局函数,内部增加支持 json 词条的挂载,以及在原本翻译行为结束后,如果没翻译成功,则走入 json 词条里进行匹配,查看是否能翻译成功
这样能保证不改动原本项目里已有的国际化代码和行为,保持原样
新增或新改动到的代码就可以用新的方式去进行维护
所以才叫做扩展,而不是改造,毕竟扩展是以不影响原样为前提,不然谁知道老项目的屎山会由于什么修改而突然崩塌
// i18n.expand.js
/**
* 劫持 jQuery.i18n.properties 的 api,扩展国际化能力:
* 1. 支持 .json 格式的资源文件
*/
function init(i18n) {
// 注意,初始化需要在 jQuery.i18n.properties.js 文件加载后才能正常劫持到 i18n 的 api
if (!i18n) return;
wrapFnProperties(i18n);
wrapFnProp(i18n);
wrapMap(i18n);
}
/**
* 挂载新的 map 对象来存储从 .json 资源文件里读取的国际化翻译信息
*/
function wrapMap(i18n) {
i18n.mapFromJson = i18n.mapFromJson || {};
}
/**
* 劫持原 prop,如果原 prop 翻译失败,则再去 mapFromJson 里尝试翻译
*/
function wrapFnProp(i18n) {
let oldFn = i18n.prop;
i18n.prop = function (key, ...args) {
let value = oldFn.call(i18n, key, ...args);
// 如果原翻译行为未翻译成功,则尝试从 json 词条里去寻找翻译
if (value === key) {
// 这里把原 jquery.i18n.properties#prop 代码拷贝过来就行,然后把词条来源改成从json词条里寻找翻译
value = $.i18n.mapFromJson[key];
// ... 省略拷贝过来的代码
}
return value;
};
}
/**
* 劫持原 properties,获取国际化相关配置信息
* 如:当前语言 language,【新增】json的国际化翻译信息
*/
function wrapFnProperties(i18n) {
let oldFn = i18n.properties;
i18n.properties = function (settings, ...args) {
if (settings.jsonResource) {
i18n.mapFromJson = settings.jsonResource;
}
return oldFn.call(i18n, settings, ...args);
};
}
// 如果当前已经加载完jquery.i18n.properties.js文件,就直接扩展它的能力
if ($.i18n) {
// 扩展 jquery.i18n.properties 的能力
init($.i18n);
}
export default {
init: init,
};
然后在引入 jquery.i18n.properties.js 的 html 下面增加:
<script type="text/javascript" src="/lib/jquery.i18n.properties.js"></script>
<script type="text/javascript" src="/lib/i18n.expand.js"></script>
如果你们多页应用没有基类 html 文件的话,那如果有基类 js 的话,也可以在基类 js 里去初始化
尽量只在一个地方去初始化,省得需要每个 html 里去加代码
import i18nExpand from "./i18n.expand";
if ($.i18n) {
// 扩展 jquery.i18n.properties 的能力
i18nExpand.init($.i18n);
}
给 Vue 挂载个全局函数 $t 指向 $.i18n.prop
我们老项目里有引入 Vue 框架,但也仅仅引入 Vue,没有引入其他全家桶系列,只用来在有新改动时,可以局部性使用 Vue 的响应式编程
而这里老项目里没必要再引入个 Vue-i18n 框架了,直接给挂载个全局函数 $t 指向原本的国际化方案的翻译函数即可
if (Vue) {
// 给 Vue 挂载全局函数
Vue.prototype.$t = $.i18n.prop;
}
properties 转 json 的脚本
如果嫌弃 properties 格式的文件不好维护词条,可以写个脚本来转换:
/**
* 将 properties 文件的国际化资源文件转成 json 格式文件
* 脚本命令挂在 package.json 文件里
* 注:由于 properties 文件的中文经过编码,该脚本会进行解码处理,以便中文可正常显示
*/
const vfs = require("vinyl-fs");
const map = require("map-stream");
const path = require("path");
const fs = require("fs");
const ROOT_DIR = path.resolve(__dirname, "./");
const fileRules = ["**/*.+(properties)"];
const jsonFile = "properties2json.json";
function ascii2native(value) {
var character = value.split("\\u");
var native1 = character[0];
for (var i = 1; i < character.length; i++) {
var code = character[i];
native1 += String.fromCharCode(parseInt("0x" + code.substring(0, 4)));
if (code.length > 4) {
native1 += code.substring(4, code.length);
}
}
return native1;
}
function run() {
console.log("================================>start");
let zhProperties = {};
let enProperties = {};
let curProperties = {};
let res = {};
const exist = fs.existsSync(path.resolve(ROOT_DIR, jsonFile));
if (exist) {
res = fs.readFileSync(path.resolve(ROOT_DIR, jsonFile), "utf-8");
res = JSON.parse(res);
}
vfs
.src(fileRules.map((item) => path.resolve(ROOT_DIR, item)))
.pipe(
map((file, cb) => {
console.log("开始解析 =========================>", file.path);
let count = 0;
if (file.path.indexOf("_zh") > -1) {
curProperties = zhProperties;
} else {
curProperties = enProperties;
}
let fileContent = file.contents.toString();
fileContent.split("\n").map((line) => {
if (line.indexOf("=") > -1) {
count++;
line = ascii2native(line);
const [key, ...value] = line.split("=");
// console.log(key, value);
curProperties[key.trim()] = value.join("=").trim();
}
});
console.log("词条数量:", count);
console.log("解析结束 =========================>", file.path);
cb();
})
)
.on("end", () => {
console.log("================================>end");
// console.log(zhProperties);
// console.log(enProperties);
let unTranslate = {};
Object.keys(zhProperties).map((key) => {
if (enProperties[key]) {
res[zhProperties[key]] = enProperties[key];
} else {
unTranslate[key] = zhProperties[key].trim();
console.log("==>翻译丢失", key, zhProperties[key].trim());
}
});
fs.writeFileSync(
path.resolve(ROOT_DIR, jsonFile),
JSON.stringify(res, " ", 2)
);
// fs.writeFileSync(
// path.resolve(ROOT_DIR, "unTranslate.json"),
// JSON.stringify(unTranslate, " ", 2)
// );
});
}
run();
总之,老项目的国际化原则就是控制影响面,降低维护成本,包括需要考虑交给新人去维护的情况
因此,能不改动到原方案就不改动,保持原方案不变的情况下,扩展支持跟 vue 项目一致的使用方式,以便国际化自动处理脚本也能够直接用来维护老项目
扩展 jQurey.i18n.properties 的能力来向 vue-i18n 靠齐的更多相关文章
- 前端系列——jquery.i18n.properties前端国际化解决方案“填坑日记”
前言:最近,新的平台还没有开发完成,原来的老项目又提出了新的需求:系统国际化.如果是前后端完全分离的开发模式,要做国际化,真的太简单了,有现成的解决方案,基于Node构建的时下热门的任何一种技术选型都 ...
- jquery.i18n.properties.js hacking
/****************************************************************************** * jquery.i18n.proper ...
- Web前端国际化之jQuery.i18n.properties
Web前端国际化之jQuery.i18n.properties jQuery.i18n.properties介绍 国际化是如今Web应用程序开发过程中的重要一环,jQuery.i18n.propert ...
- 本地化web开发的一个例子-jquery.i18n.properties
关键字:Web本地化, jquery,jquery.i18n.properties. 运行环境:Chrome, IE. 本文介绍使用jquery.i18n.properties对网站前端实现本地化,支 ...
- 使用 jQuery.i18n.properties 实现 Web 前端的国际化
jQuery.i18n.properties 简介 在介绍 jQuery.i18n.properties 之前,我们先来看一下什么是国际化.国际化英文单词为:Internationalization, ...
- jQuery之前端国际化jQuery.i18n.properties
jQuery.i18n.properties是一款轻量级的jQuery国际化插件,能实现Web前端的国际化. 国际化英文单词为:Internationalization,又称i18n,"i& ...
- jquery.i18n.properties前端国际化解决方案“填坑日记”
但现在的情况是老的项目并没有使用这类架构.说起国际化,博主几年前就做过,在MVC里面实现国际化有通用的解决方案,主要就是通过资源文件的方式定义多语言.最初接到这个任务,并没有太多顾虑,毕竟这种东西有很 ...
- 【转】jQuery之前端国际化jQuery.i18n.properties
jQuery之前端国际化jQuery.i18n.properties 基于jQuery.i18n.properties 实现前端页面的资源国际化 jquery-i18n-properties
- 基于jQuery.i18n.properties实现前端网站语言多版本
我是参考播客做了个demo:http://blog.csdn.net/aixiaoyang168/article/details/49336709 jQuery.i18n.properties采用.p ...
- jQuery之前端国际化jQuery.i18n.properties[转]
http://www.ibm.com/developerworks/cn/web/1305_hezj_jqueryi18n/ jQuery.i18n.properties是一款轻量级的jQuery国际 ...
随机推荐
- PLC通过Modbus转Profinet网关连接变频器控制电机案例
在本案例中,通过使用Modbus转Profinet网关(XD-MDPN100),PLC可以通过Profinet协议与变频器进行通信和控制.这样,PLC可以实现对电机的转速调节.启停控制等功能. 同时, ...
- RabbitMQ保姆级教程最佳实践
一.消息队列介绍 1.消息队列概念 1.MQ全称为Message Queue,消息队列(MQ)是⼀种应⽤程序对应⽤程序的通信⽅法. 应⽤程序通过读写出⼊队列的消息(针对应⽤程序的数据)来通信,⽽⽆需专 ...
- 记一次 .NET某账本软件 非托管泄露分析
一:背景 1. 讲故事 中秋国庆长假结束,哈哈,在老家拍了很多的短视频,有兴趣的可以上B站观看:https://space.bilibili.com/409524162 ,今天继续给大家分享各种奇奇怪 ...
- Python - 中文文本进行余弦相似度比较
今天,在看论文的时候,突然想到了一件事情,爱是相对的,是双方的事情.那么"你爱我"和"你爱我"的相似度是多少呢?采用余弦相似度的方式来进行相似度比较.首先&qu ...
- C++ STL标准容器的特点和典型的使用场景
概念和作用 C++标准模板库(Standard Template Library,STL)提供了一组通用的模板类和函数,用于处理常见的数据结构和算法.STL中的标准容器是其中的重要组成部分,它们提供了 ...
- 【虹科干货】谈谈Redis Enterprise实时搜索的过人之处
我们都知道,用户在使用应用程序时候,对于速度有着越来越高的要求,真可谓是"一秒也等不及".而开发团队又该怎样来满足这种对于实时性的期望呢? 文章速览: Redis Enterpri ...
- Chromium Trace and Perfetto使用详解
1. Trace chromium 在 base 库中提供了 base::trace_event::TraceLog 类,该类是 TRACE_EVENT* , TRACE_COUNTER* 等宏的底层 ...
- Codeforces Round 823 (Div. 2)C
C. Minimum Notation 思路:我们可以进行的操作时将一个位置的数删除然后在任意位置处添加一个比当前数大1并且小于9的数,所以我们的操作只会让一个数变大,我们统计一个最大值的后缀,贪心的 ...
- 关于虚拟机的IP地址经常改变问题的解法
主要解法就是配置静态IP地址 首先了解一下IP和子网掩码,网关的含义:IP 是标识计算机特定地址的二进制数,子网掩码用于和IP组合划分子网;网关是将信息传送到网关进行收发 开始配置:首先打开Linux ...
- QT(4)-QAbstractItemView
@ 目录 1 说明 2 常用函数 2.1 交替行颜色 2.1.1 alternatingRowColors 2.1.2 setAlternatingRowColors 2.2 autoScroll 2 ...