让你的Chrome App支持多语言(i18n)
2015-09-24 16:28
489 查看
开始
Chrome Store在上传应用时要求提供源码打包的.zip格式,因此Chrome Store会读取你的源码文件,有一些固定的目录格式,和清单列表。支持多语言化就是其中一个。这是一个固定的文件夹,在你的应用中创建_locales文件夹,并在下面创建对应你语言代码的文件夹,常用的几个:
中文(简体):zh_CN
中文(繁体):zh_TW
英文:en
同样还有一个固定的文件格式就是messages.json,存放你的语言内容,在每个语言代码文件夹里面。
然后你的文件结构看起来像这样:
应用多语言
多语言的支持方法跟“定义一个变量然后调用它”有相似之处,在你需要的地方,用:__MSG_somethingYouNeed__
这种结构来替换掉,就是以两个下划线__包裹,用大写的MSG做标识符后跟变量名。然后在对应的每个语言代码文件夹下声明它的内容。
如我的应用名在中文是“RGB转Hex”,英文是“RGB to Hex”,那么我在manifest.json中的"name"(定义应用名的键),的值写MSG_appName,如:
{ "name" : "__MSG_appName__" }
然后在/_locales/en/messages.json中对应,如:
{ "appName": "RGB to Hex" }
,同理,在/_locales/zh_CN/messages.json中:
{ "appName": "RGB转Hex" }
这样,在中文Chrome Store和英文的Chrome Store会显示不同的应用名称。
建议使用驼峰方式命名。
代码中
那么如何让你的应用支持“原生的”i18n呢,Chrome给了这样一个APIchrome.i18n.getMessage( key );
也就是说,在你需要的地方chrome.i18n.getMessage('appName');就会根据系统语言显示不同的应用名(当然不能用在manifest.json里)
Stay Native
如果在一个方式、效果(交互)或是方法上纠结如何处理才能更“优雅”,Stay Native。
最后
最后在的清单文件manifest.json中定义默认语言:{ "default_locale": "zh_CN" }
========================================
今天在查看Proxy SwitchySharp的源码时,看到了一个国际化的技巧。 觉得很不错,于是给Sync My Tabs插件增加了国际化支持,并在此分享。 其实之前我在做Chrome插件时都有个疑点,翻译JavaScript里的文字用Chrome的i18n API很容易,但是要翻译HTML就麻烦了,毕竟动态生成HTML没有静态的方便。 而今天看到的这个技巧则是给HTML元素添加了一个自定义属性,然后再根据这个属性来翻译。 以这段代码为例:
<a href="#tabs">保存标签页</a> <input id="select-all-for-save" type="button" value="全选" title="选定所有的标签页"/>
这里有3段文本需要翻译,分别是innerHTML、value和title,于是用3个自定义属性来标记:
<a href="#tabs" data-i18n-content="save_tabs">保存标签页</a> <input id="select-all-for-save" type="button" value="全选" title="选定所有的标签页" data-i18n-value="select_all" data-i18n-title="select_all_tabs"/>
要注意的是:对于XHTML来说,自定义属性需要修改DTD;而对于HTML 5来说,只要属性名以data开头即可。
然后在_locales/en/messages.json里准备英文翻译:
{ "save_tabs": {"message": "Save Tabs"}, "select_all": {"message": "Select All"}, "select_all_tabs": {"message": "select all tabs"} }
现在需要翻译的文本和翻译都有了,就可以查找和替换了:
$('[data-i18n-content]').each(function() { var message = chrome.i18n.getMessage(this.getAttribute('data-i18n-content')); $(this).html(message); }); $('[data-i18n-value]').each(function() { var message = chrome.i18n.getMessage(this.getAttribute('data-i18n-value')); $(this).val(message); }); $('[data-i18n-title]').each(function() { var message = chrome.i18n.getMessage(this.getAttribute('data-i18n-title')); $(this).prop('title', message); });
其中,$('[data-i18n-content]')是指获取所有带data-i18n-content属性的DOM元素,而this.getAttribute('data-i18n-content')则是获取它的data-i18n-content属性(也可以用$(this).data('i18nContent'))。对于#tabs元素来说,这个值就是"save_tabs"。
接着用chrome.i18n.getMessage('save_tabs')就能从messages.json获取到"Save Tabs"这个翻译,然后替换自身的文本或属性即可。
在这个例子中,中文已经在HTML源码里写上了,我不想再在_locales/zh/messages.json里进行翻译了,于是就设为{}。
再修改一下翻译的脚本,让它在获取不到值时就忽略:
$('[data-i18n-content]').each(function() { var message = chrome.i18n.getMessage(this.getAttribute('data-i18n-content')); if (message) { $(this).html(message); } });
接着又想了下,其实用JavaScript模板会更简单。
于是找了个mustache.js,可它需要传一个翻译字典进去。于是编辑了一下源码,把context[name]替换成context(name),这样就可以使用翻译函数了,而这个函数自然就是chrome.i18n.getMessage。
现在这一长串代码就可以用一行代码表示了:
$('body').html(Mustache.to_html($('body').html(), chrome.i18n.getMessage));
这里要注意的是body元素里不能有JavaScript代码,否则可能重复执行。简单的解决办法就是用一个div把需要翻译的部分包起来,然后只替换这个部分。
而HTML则简化成这样:
<a href="#tabs">{{save_tabs}}</a> <input id="select-all-for-save" type="button" value="{{select_all}}" title="{{select_all_tabs}}"/>
相关文章推荐
- 关于 XcodeGhost , 如何进行保护APP安全性
- IOS MD5 + Base64加密
- 得到Android设备的唯一id
- Android 关于页卡布局的一个小技巧---如何在当前页刷新数据
- Android的多线程与异步任务3-使用AsyncTask快速实现异步任务
- Unity的旋转问题
- ios激情详解之通知
- MPAndroidChart的具体属性方法
- 移动端开发多设备适配
- Android虚拟机器学习总结Dalvik虚拟机创建进程和线程分析
- Android5.0之CardView使用教程
- Android 图片二次采样、质量压缩
- Android 编程下的代码混淆proguard
- iOS学习笔记(二)
- android ORM框架LitePal 封装SQLite
- TabHost的一点注意事项
- MPAndroidChart的使用
- Android事件的传递机制
- 推荐几本介绍Android Studio开发的好书
- iOS扫描二维码的实现