公司国际化笔记

国际化原因

为了更加方便切换版本,让代码应该一次完成,多国使用,除了使用英语外,还要可以进行单独语言包的一个添加,文章就是这样的一个例子.

公司接到一个国外的项目,需要法文版本的,但是公司通晓法文的基本没有,于是商量降低要求之后开始国际化采用英文展示就行,于是任务就开始了.

目录

[TOC]

需求分析

项目的代码全部国际化任务量不小,公司基本没有用什么框架,基本采用的是js,html实现数据的展示,没有采用框架,只是有一些简单的逻辑分层,加大了不少国际化的难度.

但是针对java部分的代码,虽说稍微熟悉一些,但是国际化就暂时不需要我负责了,虽说我也只是之前弄过纯java的一些简单的国际化.

我的话暂时只是需要复杂光伏预测系统的web展示界面.其他的国际化暂时不需要修改,毕竟最为直接的只是能够看到的部分.计算过程中的一些说明日志什么的,可以后面再继续更改.

准备工作

开始准手国际化之前,先查阅了一下相关的文章,在前端方面需要修改的部分方法有如下几种:

  • vue + vue-i18n
  • angular + angular-translate
  • react + react-intl
  • jquery.i18n.properties

由于考虑到公司原本的代码没有使用什么现在的最新框架,只是采用的最后一个,也就是jquery.i18n.properties这样子的一个解决方案了,目前方案就暂时这么定来下了,然后下载对应的jQuery文件和jQuery.i18n文件了.

由于文件更新比较快,这里就不单独提供下载连接了,自行搜索,测试版本的时候使用的是3.3的版本.对应的浏览器需要ie10及以上,谷歌基本没问题.

开始着手

引入jQuery相关js

首先是引入jQuery的文件.有两种方案了,一种是在每个页面一个个添加,这样子效率不高,但是稳定,还有一种是采用js直接内部引入外部的js的方法,两种方法的代码如下:

<!-- 页面添加连接 -->
<script type="text/javascript" language="JavaScript"
  src="../jsCommon/jquery-3.3.1.js"></script>
<script type="text/javascript" language="JavaScript"
  src="../jsCommon/jquery.i18n.properties.min.js"></script> 
<!--           <script type="text/javascript" language="JavaScript"
  src="../jsCommon/jquery.i18n.properties.js"></script> -->

这里其实是指需要两个,多的一个min的包,只是为了后面加速加载之用,开发测试的话,一般用不压缩的js包,因为看起来有些难度.

//js内部添加外部js
document.write('<script type="text/javascript" language="JavaScript"  src="../jsCommon/jquery-3.3.1.js"></script>');
document.write('<!-- <script type="text/javascript" language="JavaScript"  src="../jsCommon/jquery.i18n.properties.min.js"> </script> -->');
document.write('<script type="text/javascript" language="JavaScript"  src="../jsCommon/jquery.i18n.properties.js"></script>');

这里需要注意一下的是,添加这个之后,才能使用这个引入的js,并且不能在这个js里面使用引入的一些方法,因为会找不到,你可以尝试一下.

采用第二种方法的话,需要找一个所有页面都存在的js文件才可以,可以根据自己的需要选择,没有这样的一个js的话,就差不多只能选择第一个方法,或者自己写这么一个js了.

初始化参数

引入之后js就需要初始化了,代码以及参数如下:

var currentLang = navigator.language;   //判断除IE外其他浏览器使用语言
if(!currentLang){//判断IE浏览器使用语言
   currentLang = navigator.browserLanguage;
}
console.info("Browser: "+ currentLang);
//currentLang = 'en-US';
//currentLang = 'zh_CN';


jQuery.i18n.properties({
        name: 'nari', //必须和配置文件一致
        path : '../jsCommon/', // 资源文件路径
        mode : 'map', // 用 Map 的方式使用资源文件中的值
//      language : 'en_US',
        language : currentLang, 
//      cache:false, 
//      encoding: 'UTF-8', 
        callback: function(){ 
            console.info( $.i18n.prop('info'));
            console.info(currentLang);
        }

这里的话分为两个部分了,前面部分只是为了自动识别浏览器的语言,做的一个判断,可以不要,然后下面的参数的话,没有注释的部分,一般就是都需要填写的了,除了那个language除外,那个也是可以省略.

国际化页面

上面的那个初始化的代码可以放在页面加载完成之前,也可以放在页面加载完成之后.加载的方法有两种,一种是统一加载,一种是按需加载.

统一加载

放在页面加载完成之后的话,这个部分的代码就需要放在js的最后面了,然后在callback方法里面,通过id号或者其他的标志进行国际化操作了.
网络上面多是这么一个案例,找到应该不难,这里就copy一份例子,没有经过实际代码验证:

jQuery.i18n.properties({
        name: 'common',
        path: '/Content/i18n/' + i18nLanguage + '/', //资源文件路径
        mode: 'map', //用Map的方式使用资源文件中的值
        language: i18nLanguage,
        callback: function () {//加载成功后设置显示内容
            console.log("i18n赋值中...");
            try {
                //初始化页面元素
                $('[data-i18n-placeholder]').each(function () {
                    $(this).attr('placeholder', $.i18n.prop($(this).data('i18n-placeholder')));
                });
                $('[data-i18n-text]').each(function () {
                    //如果text里面还有html需要过滤掉
                    var html = $(this).html();
                    var reg = /<(.*)>/;
                    if (reg.test(html)) {
                        var htmlValue = reg.exec(html)[0];
                        $(this).html(htmlValue + $.i18n.prop($(this).data('i18n-text')));
                    }
                    else {
                        $(this).text($.i18n.prop($(this).data('i18n-text')));
                    }
                });
                $('[data-i18n-value]').each(function () {
                    $(this).val($.i18n.prop($(this).data('i18n-value')));
                });
            }
            catch(ex){ }
            console.log("i18n写入完毕");
        }
    });

这里需要注意的是,这里需要每一个需要更改的位置都添加类似如下的标记:

<input class="typeahead" type="text" id="menu_search" data-i18n-placeholder = "searchPlaceholder"/>

<span data-i18n-text="setting"></span>

这里的话如果是开始开发或者只是短小一些的英文的话,还是可以考虑的,但是如果是完整的项目的话,任务栏就不小了.自行选择处理.下面介绍第二种方法.

按需加载

前面的那段初始化代码如果放在页面加载之前的话,就是放在引入jQuery之后,直接初始化,然后在其他位置,需要替换成国际化的位置,按照如下的格式替换就行.

//old
alert("hello");

//new
alert($.i18n.prop('hello'));

配置文件

能够知道国际化,上面的那个替换位置的用处自然不用多说,还是提一句吧 ,这样子看似复杂了,但是后面需要修改的话,
不需要改动这里的js,而是只需要更改对应的nari.properties(具体名字根据自己的配置来)就行了,还可以根据需要自动判断语言包.

对应的nari.properties文件中文文件包的名字是nari_zh.properties和nari_zh-CN.properties,
也可以多一个繁体字的nari_zh-TW.properties,英文的对应的是nari_en.properties,
nari_en-US.properties,nari_en-UK.properties,其他国家和语言的就自己查询了,然后里面的内容大致如下格式:

#nari_zh.properties
#Chinese character need transfer to unicode 
hello = \u4F60\u597D

#nari_en.properties
hello = hello 

其他国际化内容

上面基本上可以完成大部分页面的处理了,但是还是有一些其他的需要注意一下.

标题的国际化

这里由于标题在最先加载,不管上面的那种方法,都是在这个标题之后,只能在加载之后,通过js的方法进行标题更改了.这里简单罗列一下几个有趣的方法,作用看名字就懂了.

document.getElementsByTagName("title")[0].innerText = '需要设置的值';

window.onfocus = function () {
 document.title = '恢复正常了...';
};
window.onblur = function () {
 document.title = '快回来~页面崩溃了';
};
 
$('title').html('')

需要修改的位置,只是需要把对应的字符串替换成$.i18n.prop('Title')就行了.

这里还有个问题是,如果你的浏览器加载比较慢的话,在浏览英文时候,可能会看到标题先是英文,之后才变成中文,这是应为标题加载是在js运行之前的缘故了,这个暂时没有找到好的解决办法,
一般浏览器的加载速度基本都发现不了这个现象,如果非要解决的话,就把原先的html里面的标题设置成空格把,这样就看不到中文了.

一些未启用的界面的国际化

这个部分,emmmmm,既然没启用,也没有直接的连接跳转过去,我也不启用吧.这次里面有两个不知道干嘛的页面FSDayGrid和OverhaulCapacity.

针对一些插件的处理

针对一些插件的处理的话,如果插件本身没有国际化的功能,就直接按照上面的那个按需国际化加载就行了,比方说根据自身需要引入的一些数据表格之类的插件.还有一些固定的菜单之类的等等,
当你需要同样的差不多的插件,但是有不完全相同时候,需要全部国际化是多么令人头疼的一件事情.

你能猜猜下面三个文件的作用吗?

//差不多的功能,就不能放一个文件里面处理吗?

// /PVForecast(s)1.24/WebRoot/PVForecast/jsCommon/command/MyEWISUtil.js
/PVForecast(s)1.24/WebRoot/PVForecast/jsCommon/Mcommand/MyEWISUtil.js
/PVForecast(s)1.24/WebRoot/PVForecast/jsCommon/Mcommand/MyEWISUtil1.js//runalarm
/PVForecast(s)1.24/WebRoot/PVForecast/jsCommon/command_cx/MyEWISUtil.js//StationRTList

```js
//page部分的双引用已经更改为一个引用,两个部分完全一致,但是不能自动国际化,则选择性修改后者.

//index StationRTLists PlanCapacity


//RunAlarm SolRadFigureF PowerFigureF ContrastPowerFigureF ContrastUShortRealtimeTheory ContrastLists


/PVForecast(s)1.24/WebRoot/PVForecast/Datetime/ext-lang-zh_CN.js
```

//针对一些表格位置的中文,发现是createGrid这个函数加载的,主要是针对xml文档的一个解析分析了.
//这个如果是返回或得到的数据的话,就不是很好处理了,需要在发送请求时候特殊处理.
// 数据显示的空间,针对角标的显示,有四处不同的引用,修改需要针对不同的部分进行修改.文件名至少都是GeneralGrid.js类似的名字.
//时间选择控件针对google的兼容性不是很好,需要进行处理,
//同时,日期对应的格式需要转化为国际化的形式,注意文件的位置,和时间控件有三个

/PVForecast(s)1.24/WebRoot/PVForecast/jsCommon/command/EditorGrid.js
/PVForecast(s)1.24/WebRoot/PVForecast/jsCommon/command/GeneralGrid.js
/PVForecast(s)1.24/WebRoot/PVForecast/jsCommon/command/GeneralGrid1.js
/PVForecast(s)1.24/WebRoot/PVForecast/jsCommon/command/GeneralGrid2.js
/PVForecast(s)1.24/WebRoot/PVForecast/jsCommon/command/GeneralGrid3.js
/PVForecast(s)1.24/WebRoot/PVForecast/jsCommon/command/GeneralGrid4.js
/PVForecast(s)1.24/WebRoot/PVForecast/jsCommon/command_cx/GeneralGrid.js
/PVForecast(s)1.24/WebRoot/PVForecast/jsCommon/command_cx/GeneralGrid1.js

如果一些插件本身是带有国际化的,一般通过一些方法引入就行了.下面的一个例子可以参考一下:

var userLanguage = getlanguageCookie("userLanguage");
//如果cookie里面没有,则使用默认值
if (!userLanguage) {
    userLanguage = 'zh-CN';
}
if (userLanguage == 'zh-CN') {
    var script = $('<script><\/script>');
    script.attr('src', '/Content/bootstrap-table/locale/bootstrap-table-zh-CN.js');
    $('body').append(script);
}
else if (userLanguage == 'en') {
    var script = $('<script><\/script>');
    script.attr('src', '/Content/bootstrap-table/locale/bootstrap-table-en-US.js');
    $('body').append(script);
}

这个是自动判断中英文然后加载了,代码没有验证成功,getlanguageCookie函数加载失败了,可能要自己写.不过有一个自动化一点的可以参考,代码已经经过验证:

console.info(currentLang);
currentLang=currentLang.replace('-','_');
var scr= '<script type="text/javascript" src="../jsCommon/ext/source/locale/ext-lang-'+currentLang+'.js"></script>';
document.write(scr);

代码是可以正常运行了,但是需要注意一下文件的名字和路径的问题.

针对返回数据的处理

有些位置通过定时查询数据库是否有异常数据之后直接alert获取到的数据,你就没办法了,如果是java代码还好,还可以采用java代码的国际化,这里后面有机会再提了.方法和这个类似.

如果你硬是要通过解析判断获取到数据的中文,然后写一个替换的过程的话,我在精神上面支持你,也欢迎你把写好的代码评论一番.

针对xml文件的配置国际化

针对一些通过xml动态配置页面的部分,解决方案就太多了,一个是在所有的节点旁边配置一个英文节点,但是后面维护,估计不好添加其他的语言.

那就再重写一套英文的?暂时就这么处理吧,复制一份为英文,中文的还是保留,可以在需要中文时候加载中文的配置文件,这里暂时就先自动化处理了,等后面有时间的话再添加.

复制之后,基本把所有的中文,改成英文,就完成了.

说明

欢迎评论,欢迎指正,转载也请注明出处.

参考博客

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

js 前端实现国际化配置

CommanderXL/di18n_translate: di18n_translate

Java中的国际化

JS判断浏览器语言及终端类型

js笔记浏览器及版本判断

js 获取浏览器版本信

BrowserInfo

JavaScript进阶(二)在一个JS文件中引用另一个JS文件

版本记录

20180606 起草任务
20180627 完成翻译
20180728 完成文章

猜你喜欢

转载自www.cnblogs.com/wangkun1993/p/9240177.html