在做Extjs4为前台的时候,遇到本地化的问题。通过google找到一点资料,希望记录下来以为后用。
参考内容:
Extjs4 API文档阅读(七)——本地化(Localization)
http://www.cnblogs.com/shukefrz/articles/2322932.html
以下为转载内容:
工作后干的活有点乱七八糟,被折磨死
每一段时间就要学新的语言。2011下半年是C#,2012年,轮换到了JavaScript
最近的任务是用ExtJS设计前端,这玩意强大到足以取代Silverlight,非常适合配合RESTful API使用,使用AJAX获取JSON或XML类型的数据,前端页面的生成完全不需要PHP/JSP,仅HTML+JS已经足够。这种情况下,前端可以和API所在服务端完全分离,部署在不同的服务器上,甚至前端可以放在用户本地运行
第一个任务是攻克多语言化(老大乃将这种任务扔给素人情何以堪)
网上搜索了一下,还有人专门写了插件(ext-locale-loader),但这种需要给每一自设计的页面弄一份语言拷贝的方式让余菊花一紧
后来阅读ExtJS的自带文档,发现有本地化的详细指引($EXTJS_FOLDER/docs/index.html#!/guide/localization)
一步步来就实现了ExtJS自身的UI元件在用户选择不同语言时的本地化
实现后的效果
演示页面:extlocalize.html
ExtJS语言列表RawData:languages.js(仅保留4个语言)
逻辑+UI:extlocalize.js
切换语言的逻辑其实非常简单,判断页面的传入参数(没错,静态页面也可以有参数),利用AJAX加载语言文件,然后执行语言文件中的代码,更新字符串
extlocalize.html
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Localization example</title> <!-- Ext Library Files --> <link rel="stylesheet" type="text/css" href="ext/resources/css/ext-all.css"> <script src="ext/ext-all-debug.js"></script> <!-- App Scripts --> <script src="languages.js"></script> <script src="extlocalize.js"></script> </head> <body> <div id="languages"></div> <div id="datefield"></div> <div id="emailfield"></div> <div id="grid"></div> </body> </html>
languages.js
/** * by kuyur@kuyur.info * 2012.2.3 */ Ext.namespace('Ext.local'); Ext.local.languages = [ ['en', 'English'], ['ja', 'Japanese(日本語)'], ['zh_CN', 'Simplified Chinese(简体中文)'], ['zh_TW', 'Traditional Chinese(繁體中文)'] ];
extlocalize.js
/** * by kuyur@kuyur.info * 2012.2.3 */ Ext.Loader.setConfig({enabled: true}); Ext.Loader.setPath('Ext.ux', 'ext/examples/ux/'); Ext.require([ 'Ext.data.*', 'Ext.tip.QuickTipManager', 'Ext.form.*', 'Ext.ux.data.PagingMemoryProxy', 'Ext.grid.Panel' ]); Ext.onReady(function() { MultiLangDemo = (function() { return { init: function() { var store = Ext.create('Ext.data.ArrayStore', { fields: ['code', 'language'], data : Ext.local.languages //from languages.js }); var combo = Ext.create('Ext.form.field.ComboBox', { renderTo: 'languages', margin: '10, 0, 0, 10', store: store, displayField: 'language', queryMode: 'local', emptyText: 'Select a language...', hideLabel: true, width: 200, listeners: { select: { fn: function(cb, records) { var record = records[0]; window.location.search = Ext.urlEncode({"lang":record.get("code")}); }, scope: this } } }); var params = Ext.urlDecode(window.location.search.substring(1)); if (params.lang) { var url = Ext.util.Format.format('ext/locale/ext-lang-{0}.js', params.lang); Ext.Ajax.request({ url: url, success: this.onSuccess, failure: this.onFailure, scope: this }); // check if there's really a language with passed code var record = store.findRecord('code', params.lang, null, null, null, true); // if language was found in store, assign it as current value in combobox if (record) { combo.setValue(record.data.language); } } else { // no language found, default to english this.setup(); } Ext.tip.QuickTipManager.init(); }, onSuccess: function(response) { try { eval(response.responseText); } catch (e) { Ext.Msg.alert('Failure', e.toString()); } this.setup(); }, onFailure: function() { Ext.Msg.alert('Failure', 'Failed to load locale file.'); this.setup(); }, setup: function() { Ext.create('Ext.FormPanel', { renderTo: 'datefield', margin: '10, 0, 0, 10', frame: true, title: 'Date picker', width: 380, defaultType: 'datefield', items: [{ fieldLabel: 'Date', name: 'date' }] }); Ext.create('Ext.FormPanel', { renderTo: 'emailfield', margin: '10, 0, 0, 10', labelWidth: 100, frame: true, title: 'E-mail Field', width: 380, defaults: { msgTarget: 'side', width: 340 }, defaultType: 'textfield', items: [{ fieldlabel: 'Email', name: 'email', vtype: 'email' }] }); var monthArray = Ext.Array.map(Ext.Date.monthNames, function (e) { return [e]; }); var ds = Ext.create('Ext.data.Store', { fields: ['month'], remoteSort: true, pageSize: 6, proxy: { type: 'pagingmemory', data: monthArray, reader: { type: 'array' } } }); Ext.create('Ext.grid.Panel', { renderTo: 'grid', margin: '10, 0, 0, 10', width: 380, height: 203, title:'Month Browser', columns:[{ text: 'Month of the year', dataIndex: 'month', width: 240 }], store: ds, bbar: Ext.create('Ext.toolbar.Paging', { pageSize: 6, store: ds, displayInfo: true }) }); // trigger the data store load ds.load(); } }; })(); MultiLangDemo.init(); });
以上仅是ExtJS UI自身的本地化。
自己系统中的文字如何本地化呢?
余的做法基本是沿着ExtJS本地化的思路,将系统用到的字符串集中在单个文件中,这也有利于后期扩展更多的语言
像Date picker/Email Field/Month Browser/Month of the year就是系统自身的语言,不应该硬编码到UI中
在加载ExtJS语言文件的时候,同时也加载系统自身的语言文件进行刷新
系统语言文件也必须使用和ExtJS语言文件相同的后缀,如en/ja/zh_CN/zh_TW
效果:
演示页面:multiplelanguages.html
逻辑+UI:multiplelanguages.js
语言列表RawData:languages.js(和上面一样)
系统默认语言文件(必须):myproject-js/myproject-lang.js(余将默认语言弄成了日文)
系统的本地化语言文件(可选):(没有参数时会保留默认语言文件中的设定)
locale/myproject-lang-en.js
locale/myproject-lang-ja.js
locale/myproject-lang-zh_CN.js
locale/myproject-lang-zh_TW.js
multiplelanguages.html
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Localization example</title> <!-- Ext Library Files --> <script src="myproject-js/myproject-lang.js"></script> <link rel="stylesheet" type="text/css" href="ext/resources/css/ext-all.css"> <script src="ext/ext-all-debug.js"></script> <!-- App Scripts --> <script src="languages.js"></script> <script src="multiplelanguages.js"></script> </head> <body> <div id="languages"></div> <div id="datefield"></div> <div id="emailfield"></div> <div id="grid"></div> </body> </html>
multiplelanguages.js
将UI的生成全部集中到setup函数里了
/** * by kuyur@kuyur.info * 2012.2.3 */ Ext.Loader.setConfig({ enabled: true }); Ext.Loader.setPath('Ext.ux', 'ext/examples/ux/'); Ext.require(['Ext.data.*', 'Ext.tip.QuickTipManager', 'Ext.form.*', 'Ext.ux.data.PagingMemoryProxy', 'Ext.grid.Panel']); Ext.onReady(function() { var params; MultiLangDemo = (function() { return { init: function() { // load ExtJS locale params = Ext.urlDecode(window.location.search.substring(1)); if (params.lang) { var url = Ext.util.Format.format('ext/locale/ext-lang-{0}.js', params.lang); Ext.Ajax.request({ url: url, success: this.onLoadExtLocaleSuccess, failure: this.onLoadExtLocaleFailure, scope: this }); } else { // no language found, locale of ExtJS will be english as default this.loadmyprojectLocale(); } }, onLoadExtLocaleSuccess: function(response) { try { eval(response.responseText); } catch (e) { Ext.Msg.alert('Failure', e.toString()); } this.loadmyprojectLocale(); }, onLoadExtLocaleFailure: function() { Ext.Msg.alert('Failure', 'Failed to load locale file.'); this.loadmyprojectLocale(); }, loadmyprojectLocale: function() { // load locale for myproject if (params.lang) { var urlmyprojectLocale = Ext.util.Format.format('locale/myproject-lang-{0}.js', params.lang); Ext.Ajax.request({ url: urlmyprojectLocale, success: this.onLoadmyprojectLocaleSuccess, failure: this.onLoadmyprojectLocaleFailue, scope: this }); } else { this.setup(); } }, onLoadmyprojectLocaleSuccess: function(response) { try { eval(response.responseText); } catch (e) { Ext.Msg.alert('Failure', e.toString()); } this.setup(); }, onLoadmyprojectLocaleFailue: function() { Ext.Msg.alert('Failure', 'Failed to load myproject locale file.'); this.setup(); }, setup: function() { var store = Ext.create('Ext.data.ArrayStore', { fields: ['code', 'language'], data: Ext.local.languages //from languages.js }); var combo = Ext.create('Ext.form.field.ComboBox', { renderTo: 'languages', margin: '10, 0, 0, 10', store: store, displayField: 'language', queryMode: 'local', emptyText: myproject.Message.SelectALanguage, hideLabel: true, width: 200, listeners: { select: { fn: function(cb, records) { var record = records[0]; window.location.search = Ext.urlEncode({ "lang": record.get("code") }); }, scope: this } } }); if (params.lang) { // check if there's really a language with passed code var record = store.findRecord('code', params.lang, null, null, null, true); // if language was found in store, assign it as current value in combobox if (record) { combo.setValue(record.data.language); } } Ext.create('Ext.FormPanel', { renderTo: 'datefield', margin: '10, 0, 0, 10', frame: true, title: myproject.Message.PickDate, width: 380, defaultType: 'datefield', items: [{ fieldLabel: myproject.Message.Date, name: 'date' }] }); Ext.create('Ext.FormPanel', { renderTo: 'emailfield', margin: '10, 0, 0, 10', labelWidth: 100, frame: true, title: myproject.Message.EmailFieldTitle, width: 380, defaults: { msgTarget: 'side', width: 340 }, defaultType: 'textfield', items: [{ fieldlabel: 'Email', name: 'email', vtype: 'email' }] }); var monthArray = Ext.Array.map(Ext.Date.monthNames, function(e) { return [e]; }); var ds = Ext.create('Ext.data.Store', { fields: ['month'], remoteSort: true, pageSize: 6, proxy: { type: 'pagingmemory', data: monthArray, reader: { type: 'array' } } }); Ext.create('Ext.grid.Panel', { renderTo: 'grid', margin: '10, 0, 0, 10', width: 380, height: 203, title: myproject.Message.MonthList, columns: [{ text: myproject.Message.MonthTitle, dataIndex: 'month', width: 240 }], store: ds, bbar: Ext.create('Ext.toolbar.Paging', { pageSize: 6, store: ds, displayInfo: true }) }); // trigger the data store load ds.load(); } }; })(); MultiLangDemo.init(); });
myproject-js/myproject-lang.js
/** * by kuyur@kuyur.info * 2012.2.3 */ var myproject = {}; myproject.Message = {}; myproject.Message.SelectALanguage = '言語を選択ください...'; myproject.Message.PickDate = '日付を選択'; myproject.Message.Date = '日付'; myproject.Message.EmailFieldTitle = 'メールアドレス'; myproject.Message.MonthList = '月の一覧'; myproject.Message.MonthTitle = '月順';
locale/myproject-lang-en.js
/** * by kuyur@kuyur.info * 2012.2.3 */ if (myproject.Message) { myproject.Message.SelectALanguage = 'Select a language...'; myproject.Message.PickDate = 'Date Picker'; myproject.Message.Date = 'Date'; myproject.Message.EmailFieldTitle = 'Email'; myproject.Message.MonthList = 'Month Browser'; myproject.Message.MonthTitle = 'Month of the year'; }
locale/myproject-lang-ja.js
/** * by kuyur@kuyur.info * 2012.2.3 */ if (myproject.Message) { myproject.Message.SelectALanguage = '言語を選択ください...'; myproject.Message.PickDate = '日付を選択'; myproject.Message.Date = '日付'; myproject.Message.EmailFieldTitle = 'メールアドレス'; myproject.Message.MonthList = '月の一覧'; myproject.Message.MonthTitle = '月順'; }
locale/myproject-lang-zh_CN.js
/** * by kuyur@kuyur.info * 2012.2.3 */ if (myproject.Message) { myproject.Message.SelectALanguage = '请选择一种语言...'; myproject.Message.PickDate = '选择日期'; myproject.Message.Date = '日期'; myproject.Message.EmailFieldTitle = '电子邮件地址'; myproject.Message.MonthList = '月份一览'; myproject.Message.MonthTitle = '月份'; }
locale/myproject-lang-zh_TW.js
/** * by kuyur@kuyur.info * 2012.2.3 */ if (myproject.Message) { myproject.Message.SelectALanguage = '請選擇一種語言...'; myproject.Message.PickDate = '選擇日期'; myproject.Message.Date = '日期'; myproject.Message.EmailFieldTitle = '電子郵件地址'; myproject.Message.MonthList = '月份一覽'; myproject.Message.MonthTitle = '月份'; }
注意事项:
1.ExtJS库的解压目录名要一致,代码中的为ext
2.由于AJAX的本地请求会因为安全问题被浏览器禁止,需要将文件放到服务器才能测试
相关推荐
这是是一款开源的跨平台、数据库和浏览器的可视化ExtJS应用开发平台。 特色: .基于浏览器的集成开发环境 .丰富的组件库,可自定义扩展ExtJS组件 .开发应用简单快速 .高效率和高稳定性 .跨平台、数据库和...
应用架构:在ExtJS 4,引入了一个标准化的几乎适合任何ExtJS应用程序的MVC风格的应用架构。使用MVC,开发团队只需要学习一种架构就能理解任何ExtJS 4的应用。 SDK工具:正在测试beta版的Sencha SDK工具,在第一版本...
extjs4.0手册翻译 0-0-入门.doc ...1-7-本地化.doc 1-8-键盘导航.doc 2-1-表格.doc 2-2-树.doc 2-3-数据.doc 2-4-表单.doc 2-5-主题.doc 3-1-Ext应用架构.doc 附件:Component基类中已经实现的模版方法.doc
第4章 ExtJS事件机制 4.1 设计模式——观察者模式 4.2 自定义事件 4.3 浏览器事件 4.4 ExtJS中的事件 4.4.1 Function.call()/apply()方法 4.4.2 函数的作用域 4.4.3 Ext.lib.Event事件 4.4.4 Ext.util....
第4章 ExtJS事件机制 4.1 设计模式——观察者模式 4.2 自定义事件 4.3 浏览器事件 4.4 ExtJS中的事件 4.4.1 Function.call()/apply()方法 4.4.2 函数的作用域 4.4.3 Ext.lib.Event事件 4.4.4 Ext.util....
ExtJs-工作坊 Sencha ExtJS 框架研讨会 工作区演示 - 创建一个类 - 用构造函数创建一个类 - 继承 - 配置的使用 - 布局 - 你好世界 - 视口 - 网格 - 网格到表单映射 - 本地化 - 休息 -
强大的美化与功能多样化,你第一个想到的应该是ExtJs ExtJS是一种主要用于创建前端用户界面,是一个基本与后台技术无关的前端ajax框架。 功能丰富,无人能出其右。 无论是界面之美,还是功能之强,ext的表格控件...
Extjs本地化包支持超过40种语言,如德语,法语,韩语,中文等。 在ExtJs中实现区域设置非常简单。您将在ext-locale软件包的覆盖文件夹中找到所有捆绑的区域设置文件。 语言环境文件只是覆盖,它指示Ext JS替换某些...
ExtJS动态布局 此示例应用程序演示了如何在ExtJS应用程序中创建动态布局,本地化和方向。 本示例使用ExtJS 4。 使用这种方法,您可以具有不同的布局,可以具有任何方向和区域。
qTemplate - Ext JSqTemplate是一个基于Ext JS经典工具包(calssic tookit)的模版...qTemplate的主要特点包括:字段自动从本地化文件获取标签列自动从本地化文件获取列标题快速CURD模版开发本地化的简单实现使用方法:
Ext-locale包提供了使用预定义词典对象进行轻量级本地化的机制。 它完全支持动态包加载器,并在任何给定级别提供类内的属性替换。 另外,它可以在XTemplate中使用,并确保与视图绑定的紧密集成。 当前版本2.5.0的...
它支持多种视图,拖放编辑,日历颜色编码,可本地化,并且易于扩展。扩展版本支持可扩展仅支持Ext JS版本3.x和4.x。 不支持Ext 5及更高版本。 可与Ext 3和Ext 4一起使用。 不幸的是,由于Ext 4不向后兼容,这意味着...
2.8 本地化 / 60 2.9 为本书示例准备一个模板 / 60 2.10 本章小结 / 61 第3章 调试工具及技巧 / 62 3.1 使用firebug进行调试 / 62 3.2 在ie中调试 / 76 3.2.1 使用debugbar和companion.js调试 / 76 3.2.2 ...
第2章介绍了ext js 4的获取、ext js库的配置与使用、语法、本地化,以及一个经典的入门示例;第3章详细讲解了调试的工具及技巧,这是本书的重要内容,希望所有web开发者都能掌握;第4章全面介绍了ext js的基础架构;...
中文本地化功能 Tomatocart中文版为中国用户量身定制了更多功能:支持团购﹑秒杀等促销方式,并支持支付宝﹑网银在线等支付模式,和顺丰快递﹑express等多个运输模式。 轻量级框架部署灵活 Tomatocart基于轻量级...
第2章介绍了ext js 4的获取、ext js库的配置与使用、语法、本地化,以及一个经典的入门示例;第3章详细讲解了调试的工具及技巧,这是本书的重要内容,希望所有web开发者都能掌握;第4章全面介绍了ext js的基础架构;...
添加文件filters / dev / jdbc.properties,并编写自己的本地化配置,可参考filters / prod / jdbc.properties 根据修改参数创建对应的MySql数据库(数据库编码:UTF-8) 执行mvn tomcat7:运行,自动创建对应的...
常用组件是一些常用的组件和可复用API的集合,它包含了公共方法、异常处理,缓存、验证、全球化\本地化、动态类生成器、Data Context工厂、日志处理、事物处理、Spring.NET整合等等 扩展模型 扩展模型可以让你在...
Ext Designer 是一个帮助用户更快的创建桌面应用程序的可视化的界面图形化工具。 Sencha Touch Sencha Touch 是第一个基于 HTML5 的 Mobile web 应用开发框架。 Sencha Animator Sencha Animator 是一个创建基于 ...