Tutorial:Localizing Ext (本地化ext)

 

1 引言
2 慢慢开始
3 原理是??
4 本地化文件的葫芦里卖的什么药?
5 应用程序的本地化
6 高级提示

引言
如果你是英语的用户就不必做任何本地化的工作了,这篇教程是为非英语用户所准备的,好像一般的用户,开发主管,业务员等,他们的外语可能稍逊,这样就需要你对如何本地化ext的整个流程了解一番了。

慢慢开始
如果你曾浏览Ext 2.x目录的树状结构,你就会发现source/locale的目录(或SVN目录的src/locale)。此目录包含了Ext本地化类。先不长篇大论地讲太多概念的东西,我们应了解如何先使用。

下面的一个例子就是使用了本地化的ext,但是不是在ext同一个目录下的。因此通常的,你需要调整head标签内的路径,以正确指向Ext的安装目录。尤其注意本地化的那个目录路径。

把你服务器的路径Copy and paste到相应文件路径中:

注意: 下里的代码我是动态加载到head头部的,只能在FireFox通过。不过实际情况你不必如此,你只要在服务端指定script的路径而不必动态加载。

  1. <html>  
  2. <head>  
  3.     <meta http-equiv="Content-Type"  content= "text/html; charset=utf-8" >  
  4.     <link rel="stylesheet"  type= "text/css"  href= "../ext/resources/css/ext-all.css" >  
  5.     <script type="text/javascript"  src= "../ext/adapter/ext/ext-base.js" ></script>  
  6.     <script type="text/javascript"  src= "../ext/ext-all-debug.js" ></script>  
  7.     <script type="text/javascript" >  
  8.    
  9.     //根据url上指定的语言进行解码   
  10.     var  locale = window.location.search   
  11.                  ? Ext.urlDecode(window.location.search.substring(1)).locale   
  12.                  : '' ;  
  13.    
  14.     // 将本地化的JS文件加入head元素内   
  15.     var  head = Ext.fly(document.getElementsByTagName( 'head' )[0]);  
  16.     if (locale) {  
  17.         Ext.DomHelper.append(head, {  
  18.              tag:'script'   
  19.             ,type:'text/javascript'   
  20.             ,src:'../ext/src/locale/ext-lang-'  + locale +  '.js'   
  21.         });  
  22.     }  
  23.    
  24.     //预先定义的window继承类   
  25.     Ext.ns('Tutorial' );  
  26.     Tutorial.LocalizationWin = Ext.extend(Ext.Window, {  
  27.         initComponent:function () {  
  28.             Ext.apply(this , {  
  29.                  width:500  
  30.                 ,id:'winid'   
  31.                 ,height:300  
  32.                 ,layout:'fit'   
  33.                 ,border:false   
  34.                 ,closable:false   
  35.                 ,title:Ext.get('title' ).dom.innerHTML  
  36.                 ,items:[{  
  37.                      xtype:'form'   
  38.                     ,frame:true   
  39.                     ,defaultType:'textfield'   
  40.                     ,items:[{  
  41.                           xtype:'combo'   
  42.                          ,fieldLabel:'Select Language'   
  43.                          ,name:'locale'   
  44.                          ,store:new  Ext.data.SimpleStore({  
  45.                              id:0  
  46.                             ,fields:['file''locale' ]  
  47.                             ,data:[  
  48.                                  ['cs''Czech' ]  
  49.                                 ,['''English' ]  
  50.                                 ,['fr''French' ]  
  51.                                 ,['de''German' ]  
  52.                                 ,['gr''Greece' ]  
  53.                                 ,['hu''Hungarian' ]  
  54.                                 ,['it''Italian' ]  
  55.                                 ,['ja''Japaneese' ]  
  56.                                 ,['pl''Polish' ]  
  57.                                 ,['pt''Portugal' ]  
  58.                                 ,['ru''Russian' ]  
  59.                                 ,['sk''Slovak' ]  
  60.                                 ,['es''Spanish' ]  
  61.                                 ,['sv_SE''Swedish' ]  
  62.                                 ,['tr''Turkish' ]  
  63.                             ]  
  64.                          })  
  65.                         ,listeners:{  
  66.                             select:{fn:function (combo){  
  67.                                 window.location.search = '?'    
  68.                                     + Ext.urlEncode({locale:combo.getValue()})  
  69.                                 ;  
  70.                             }}  
  71.                         }  
  72.                         ,mode:'local'   
  73.                         ,editable:false   
  74.                         ,forceSelection:true   
  75.                         ,valueField:'file'   
  76.                         ,displayField:'locale'   
  77.                         ,triggerAction:'all'   
  78.                         ,value:locale  
  79.                      },{  
  80.                          fieldLabel:'Text Field'   
  81.                         ,allowBlank:false   
  82.                     },{  
  83.                          xtype:'datefield'   
  84.                         ,fieldLabel:'Date Field'   
  85.                         ,allowBlank:false   
  86.                     }]  
  87.                 }]  
  88.             }); // eo apply   
  89.             Tutorial.LocalizationWin.superclass.initComponent.apply(this , arguments);  
  90.         } // eo function initComponent   
  91.     }); // eo Tutorial.LocalizationWin   
  92.    
  93. Ext.BLANK_IMAGE_URL = '../ext/resources/images/default/s.gif' ;  
  94. Ext.onReady(function () {  
  95.     Ext.QuickTips.init();  
  96.     Ext.form.Field.prototype.msgTarget = 'side' ;  
  97.    
  98.     // create example window   
  99.     var  win =  new  Tutorial.LocalizationWin();  
  100.     win.show();  
  101. });  
  102.     </script>  
  103.     <title id="title" >Localization Example</title>  
  104. </head>  
  105. <body>  
  106. </body>  
  107. </html>  

现在完整的本地化工作是限于ComboBox、TextField和DateField这些Ext基础组件。试试在已翻译好的DataPicker组件中输入一些文字。

原理是??
原理是一改变cobmo box里面的"Select Language"就会包含(include)相应的Ext本地化文件(这里我使用了一些技巧性的做法,改变本地化文件的过程是用过客户端脚本完成的)

本地化文件的葫芦里卖的什么药?
首先要打开本地化文件来看看,读懂里面的源码后不但对Ext的理解有帮助而且对整个程序的本地化,也是有帮助的。我们以法语版的DatePicker为例子:

  1. if (Ext.DatePicker){  
  2.    Ext.override(Ext.DatePicker, {  
  3.       todayText         : "Aujourd'hui" ,  
  4.       minText           : "Cette date est antérieure à la date minimum" ,  
  5.       maxText           : "Cette date est postérieure à la date maximum" ,  
  6.       disabledDaysText  : "" ,  
  7.       disabledDatesText : "" ,  
  8.       monthNames        : Date.monthNames,  
  9.       dayNames          : Date.dayNames,  
  10.       nextText          : 'Mois suivant (CTRL+Flèche droite)' ,  
  11.       prevText          : "Mois précédent (CTRL+Flèche gauche)" ,  
  12.       monthYearText     : "Choisissez un mois (CTRL+Flèche haut ou bas pour changer d'année.)" ,  
  13.       todayTip          : "{0} (Barre d'espace)" ,  
  14.       okText            : " OK " ,  
  15.       cancelText        : "Annuler" ,  
  16.       format            : "d/m/y" ,  
  17.       startDay          : 1  
  18.    });  

通过观察,我们得知如果DataPicker对象存在(这是需要检测的,事因有些ext是你自己可制定的)就重写DataPicker的部分属性; 更严格说,我们是把法语的文字替换掉英语的文字而已。Ext.override的作用是在DatePicker建立实例之前改变class的原型。

应用程序的本地化
我们对范例文件略加修改,把所有的静态文本变为类成员,修改过后看起来是这样的:

  1. <html>  
  2. <head>  
  3.     <meta http-equiv="Content-Type"  content= "text/html; charset=utf-8" >  
  4.     <link rel="stylesheet"  type= "text/css"  href= "../ext/resources/css/ext-all.css" >  
  5.     <script type="text/javascript"  src= "../ext/adapter/ext/ext-base.js" ></script>  
  6.     <script type="text/javascript"  src= "../ext/ext-all-debug.js" ></script>  
  7.    
  8.     <!-- Ext localization javascript -->  
  9.     <script type="text/javascript"  id= "extlocale" ></script>  
  10.    
  11.     <!-- Locale and example extension javascript -->  
  12.     <script type="text/javascript" >  
  13.    
  14.     // decode language passed in url   
  15.     var  locale = window.location.search   
  16.                  ? Ext.urlDecode(window.location.search.substring(1)).locale   
  17.                  : ''   
  18.     ;  
  19.    
  20.     // append locale script to the head   
  21.     var  head = Ext.fly(document.getElementsByTagName( 'head' )[0]);  
  22.     if (locale) {  
  23.         Ext.fly('extlocale' ).set({src: '../ext/src/locale/ext-lang-'  + locale +  '.js' });  
  24.     }  
  25.    
  26.     // create pre-configured example window extension class   
  27.     Ext.ns('Tutorial' );  
  28.     Tutorial.LocalizationWin = Ext.extend(Ext.Window, {  
  29.          titleText:'Localization Example'   
  30.         ,selectLangText:'Select Language'   
  31.         ,textFieldText:'Text Field'   
  32.         ,dateFieldText:'Date Field'   
  33.         ,initComponent:function () {  
  34.             Ext.apply(this , {  
  35.                  width:500  
  36.                 ,id:'winid'   
  37.                 ,height:300  
  38.                 ,layout:'fit'   
  39.                 ,border:false   
  40.                 ,closable:false   
  41.                 ,title:this .titleText  
  42.                 ,items:[{  
  43.                      xtype:'form'   
  44.                     ,frame:true   
  45.                     ,defaultType:'textfield'   
  46.                     ,items:[{  
  47.                           xtype:'combo'   
  48.                          ,fieldLabel:this .selectLangText  
  49.                          ,name:'locale'   
  50.                          ,store:new  Ext.data.SimpleStore({  
  51.                              id:0  
  52.                             ,fields:['file''locale' ]  
  53.                             ,data:[  
  54.                                  ['cs''Czech' ]  
  55.                                 ,['''English' ]  
  56.                                 ,['fr''French' ]  
  57.                                 ,['de''German' ]  
  58.                                 ,['gr''Greece' ]  
  59.                                 ,['hu''Hungarian' ]  
  60.                                 ,['it''Italian' ]  
  61.                                 ,['ja''Japaneese' ]  
  62.                                 ,['pl''Polish' ]  
  63.                                 ,['pt''Portugal' ]  
  64.                                 ,['ru''Russian' ]  
  65.                                 ,['sk''Slovak' ]  
  66.                                 ,['es''Spanish' ]  
  67.                                 ,['sv_SE''Swedish' ]  
  68.                                 ,['tr''Turkish' ]  
  69.                             ]  
  70.                          })  
  71.                         ,listeners:{  
  72.                             select:{fn:function (combo){  
  73.                                 window.location.search = '?'    
  74.                                     + Ext.urlEncode({locale:combo.getValue()})  
  75.                                 ;  
  76.                             }}  
  77.                         }  
  78.                         ,mode:'local'   
  79.                         ,editable:false   
  80.                         ,forceSelection:true   
  81.                         ,valueField:'file'   
  82.                         ,displayField:'locale'   
  83.                         ,triggerAction:'all'   
  84.                         ,value:locale  
  85.                      },{  
  86.                          fieldLabel:this .textFieldText  
  87.                         ,allowBlank:false   
  88.                     },{  
  89.                          xtype:'datefield'   
  90.                         ,fieldLabel:this .dateFieldText  
  91.                         ,allowBlank:false   
  92.                     }]  
  93.                 }]  
  94.             }); // eo apply   
  95.             Tutorial.LocalizationWin.superclass.initComponent.apply(this , arguments);  
  96.         } // eo function initComponent   
  97.     }); // eo Tutorial.LocalizationWin   
  98.     </script>  
  99.    
  100.     <!-- Application localization javascript -->  
  101.     <script type="text/javascript"  id= "applocale" ></script>  
  102.    
  103.     <!-- Set src for  application localization javascript -->  
  104.     <script>  
  105.     if (locale) {  
  106.         Ext.fly('applocale' ).set({src: 'app-lang-'  + locale +  '.js' });  
  107.     }  
  108.     </script>  
  109.    
  110.     <!-- Main application -->  
  111.     <script type="text/javascript" >  
  112.     Ext.BLANK_IMAGE_URL = '../ext/resources/images/default/s.gif' ;  
  113.     Ext.onReady(function () {  
  114.         Ext.QuickTips.init();  
  115.         Ext.form.Field.prototype.msgTarget = 'side' ;  
  116.    
  117.         // create example window   
  118.         var  win =  new  Tutorial.LocalizationWin();  
  119.         win.show();  
  120.     });  
  121.     </script>  
  122.     <title id="title" >Localization Example</title>  
  123. </head>  
  124. <body>  
  125. </body>  
  126. </html>  

最后一步,我们需要为特定的语种创建程序本地化的文件(翻译,语种)。这里是app-lang-sk.js文件因为我操的是斯洛伐克语的缘故。你可因应你需求的语种去设置(保存html的格式放到同一目录下或修改上面代码的目录):

  1. /**  
  2.  * 斯洛伐克语版的教程之本地化文件  
  3.  */   
  4. if (Tutorial.LocalizationWin) {  
  5.     Ext.override(Tutorial.LocalizationWin, {  
  6.          titleText:'Príklad lokalizácie'   
  7.         ,selectLangText:'Zvoľ jazyk'   
  8.         ,textFieldText:'Textové pole'   
  9.         ,dateFieldText:'Dátumové pole'   
  10.     });  
  11. }  

高级提示
请明确,要做Ext程序的本地化需要遵循哪些的原则。关键点在于将所有翻译文本作为公共类的成员出现,重写原先类的prototype的属性

Advanced developers will immediately feel some drawback of having, maintaining and deploying that many localization files especially if they already have a server with some translating infrastructure such as GNU gettext. For these users I would recommend to generate localization files on the fly by the server using gettext as backend.

这种做法最大的好处是可讲翻译文件集中在一块(*.po),客户端和服务端都可以使用。

如果本地化这主题反映还不错的话而读者又非常想进一步了解我会写进阶的Ext本地化。


Author: Jozef Sakalos(译者:Frank Cheung)
Published: March 9, 2008
Ext Version: 2.0+

文章来自:http://extjs.com/learn/Tutorial:Localizing_Ext_%28Chinese%29

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值