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 靠齐的更多相关文章

  1. 前端系列——jquery.i18n.properties前端国际化解决方案“填坑日记”

    前言:最近,新的平台还没有开发完成,原来的老项目又提出了新的需求:系统国际化.如果是前后端完全分离的开发模式,要做国际化,真的太简单了,有现成的解决方案,基于Node构建的时下热门的任何一种技术选型都 ...

  2. jquery.i18n.properties.js hacking

    /****************************************************************************** * jquery.i18n.proper ...

  3. Web前端国际化之jQuery.i18n.properties

    Web前端国际化之jQuery.i18n.properties jQuery.i18n.properties介绍 国际化是如今Web应用程序开发过程中的重要一环,jQuery.i18n.propert ...

  4. 本地化web开发的一个例子-jquery.i18n.properties

    关键字:Web本地化, jquery,jquery.i18n.properties. 运行环境:Chrome, IE. 本文介绍使用jquery.i18n.properties对网站前端实现本地化,支 ...

  5. 使用 jQuery.i18n.properties 实现 Web 前端的国际化

    jQuery.i18n.properties 简介 在介绍 jQuery.i18n.properties 之前,我们先来看一下什么是国际化.国际化英文单词为:Internationalization, ...

  6. jQuery之前端国际化jQuery.i18n.properties

    jQuery.i18n.properties是一款轻量级的jQuery国际化插件,能实现Web前端的国际化. 国际化英文单词为:Internationalization,又称i18n,"i& ...

  7. jquery.i18n.properties前端国际化解决方案“填坑日记”

    但现在的情况是老的项目并没有使用这类架构.说起国际化,博主几年前就做过,在MVC里面实现国际化有通用的解决方案,主要就是通过资源文件的方式定义多语言.最初接到这个任务,并没有太多顾虑,毕竟这种东西有很 ...

  8. 【转】jQuery之前端国际化jQuery.i18n.properties

    jQuery之前端国际化jQuery.i18n.properties 基于jQuery.i18n.properties 实现前端页面的资源国际化 jquery-i18n-properties

  9. 基于jQuery.i18n.properties实现前端网站语言多版本

    我是参考播客做了个demo:http://blog.csdn.net/aixiaoyang168/article/details/49336709 jQuery.i18n.properties采用.p ...

  10. jQuery之前端国际化jQuery.i18n.properties[转]

    http://www.ibm.com/developerworks/cn/web/1305_hezj_jqueryi18n/ jQuery.i18n.properties是一款轻量级的jQuery国际 ...

随机推荐

  1. 千呼万唤始出来 JDK 21 LTS, 久等了

    平地起惊雷!!! 目录 英雄的迟暮 大人时代变了 JDK 21 LTS 前 JAVA并发编程模型 JDK 21 LTS 中的 JAVA 并发编程模型 虚拟线程 VS 线程池 The Last 你可以称 ...

  2. Redis系列23:性能优化指南

    Redis系列1:深刻理解高性能Redis的本质 Redis系列2:数据持久化提高可用性 Redis系列3:高可用之主从架构 Redis系列4:高可用之Sentinel(哨兵模式) Redis系列5: ...

  3. 【Python进阶-PyQt5】00搭建PyQt5环境

    1.创建独立开发虚拟环境 1.1虚拟环境简介 我们编写的程序,有时用到的Python库是不一样的,比如说开发桌面应用程序我们主要用到PyQt5相关的Python库.开发Web应用程序我们主要用到Dja ...

  4. oj练习题程序编程题

    打印图形Description按要求输出由*组成的图案Input无需输入Output输出下面由"组成的图案卡 11 print('*') print("***") pri ...

  5. 基于 Python 和 Vue 的在线评测系统

    基于 Docker,真正一键部署 前后端分离,模块化编程,微服务 ACM/OI 两种比赛模式.实时/非实时评判 任意选择 丰富的可视化图表,一图胜千言 支持 Template Problem,可以添加 ...

  6. 快速启动Stable Diffusion WebUI

    快速启动Stable Diffusion WebUI详情    产品文档   输入文档关键字查找   机器学习PAI 产品概述 快速入门 操作指南 准备工作 开通PAI并创建默认工作空间 开通并授权依 ...

  7. the solution of Mining Your Own Business

    the description of problem (我看的是 PDF 里面的原题所以这里描述会和题目不一样,但是大意一致) 给定一个未必连通的无向图,问最少在几个点设置出口,可以保证任意一个点坍塌 ...

  8. Python+SVM

    # !/usr/bin/env python # encoding: utf-8 # SVM算法 支持向量机 from sklearn import svm import numpy as np fr ...

  9. UVA10702 Travelling Salesman 题解

     UVA10702 Travelling Salesman 题解 题面: 有个旅行的商人,他每到一个的新城市,便卖掉所有东西再购买新东西,从而获得利润.从某城市 A 到某城市 B 有固定利润(B 到 ...

  10. Node.js中常用的设计模式有哪些?

    本文由葡萄城技术团队首发.转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 设计模式简介 设计模式是由经验丰富的程序员在日积月累中抽象出的用以解决通用问题的可 ...