本地化软件应用程序






2.50/5 (3投票s)
2001 年 9 月 4 日
21分钟阅读

156643
本地化 ASP 应用程序简介。
你是在开玩笑吧?
当需要让应用程序实现语言独立时,所有销售人员都会欢呼雀跃,而开发人员则会躲起来。对销售人员来说,本地化软件意味着更多的市场和更多的销售额;对开发人员来说,它意味着一长串令人头疼的问题。
主要问题之一是软件通常不是从头开始就设计成支持语言切换的。如果不是从头开始就包含这种支持,那么每一个向用户呈现语言的代码片段(按钮、菜单、图像、提示、帮助、文本)都必须被找到并修改,以支持语言独立性。当处理有数十万行代码,并且由不同开发人员不断修改的应用程序时,这个问题会呈指数级增长。
基于网络的电子商务应用程序也存在上述问题,但还带来了货币问题。对于每种支持的语言,所有处理货币的功能都必须被定位并修改,以支持每种语言的货币面额。货币必须以一种易于在所有支持的语言之间转换的方式存储,无论用户以美元查看,存储的值都必须能够转换为比索、法郎或英镑。另一件要记住的事情是汇率不是静态的,它们会变化。
面向对象来救援
无论您来自哪一方(销售或开发),现在都可以看到存在的问题。如果目标应用程序在构建时没有考虑到本地化,那么工作量将是两倍。另一方面,如果目标应用程序处于设计阶段,我们可以制定本地化行动计划。
面向对象编程 (OOP) 是一种将编程代码封装到预定义执行和数据中的方法。我们无需拥有一长串函数和变量,而是可以使用 OOP 来使开发大型(或小型)应用程序变得易于理解和实现。一个简单的现实世界面向对象示例是基本的业务结构。尽管在小型企业中,总裁了解每个人、他们应该做什么、他们应该如何做,但在大型企业中这是不可能的。以面向对象的方式分解这家公司,我们可以看到以下内容
Object Employee Object Manager Object Vice President Object President:
每个对象都有自己的属性(attributes)和方法(actions)
Object Employee Skill (property) Pay (property) Responsibilities (property) Execute (method) Object Manager Skill (property) Pay (property) Responsibilities (property) Execute (method) Collection of Employee Objects (employees he is responsible for) Object Vice President Skill (property) Pay (property) Responsibilities (property) Execute (method) Collection of Manager Objects (managers he is responsible for) Object President: Skill (property) Pay (property) Responsibilities (property) Execute (method) Collection of Vice President Objects (Vice Presidents he is responsible for)
整个公司现在可以用以下对象来表示
Object Company: Incoming (property) Outgoing (property) President Object (property) Collection of Vice President Objects (property) Collection of Manager Objects (property) Collection of Employee Objects (property)
通过使用面向对象 (OO),我们可以执行操作,甚至无需知道涉及谁或它是如何工作的。例如,如果一位总裁希望发放奖金支票,并且他有 3000 名员工,那么他几乎不可能评估所有员工的绩效并分发适当的奖金支票。通过使用 OO,总裁只需将命令交给他的副总裁,副总裁再将其传递给他们手下的每位经理,最终到达员工层面。因此,在不了解员工或经理的任何信息的情况下,总裁可以这样做:
Company -> President -> ExecuteBonusCheckPayments()
所有员工都会收到适当的奖金支票。
回到我们的应用程序,我们可以使用 OOP 来最大限度地开发和实施语言和货币独立性。通过消除开发人员了解或关心应用程序使用何种语言的需要,我们简化了他们的开发,并最大限度地利用他们的时间来关注功能。尽管本地化的实施是一项艰巨的工作,但一旦初步代码到位,开发人员将无需过多处理,甚至完全无需处理。我将重点关注一个 ASP 电子商务应用程序,但该理论可以轻松地应用于任何开发环境。
数据表示
数据表示是为开发人员和翻译人员准备的。使用本地化软件的客户端永远不会看到或需要看到数据是如何表示的。基本上,数据表示就是我们在代码中表示本地化数据的方式。我们数据表示的基础语言将是英语。应用程序创建后,开发人员将引用文本的数据表示,而不是实际文本,翻译人员将引用文本并忽略数据表示。让我们以一个需要本地化的按钮为例。该按钮上显示“Help”字样,但本地化后,西班牙语中的“HELP”是“Socorro”。我们的数据表示是 dr_txt_HELP。
英文
dr_txt_HELP = "Help"
西班牙语
dr_txt_HELP = "Socorro"
现在我们的开发人员对帮助按钮的语言毫不关心,因为在代码中他们将始终只使用 dr_txt_HELP。这种数据表示也可以用于图像。
英文
dr_img_HELP = "Help.jpg"
西班牙语
dr_img_HELP = "Socorro.jpg"
如您所见,这种数据表示在编程和翻译方面为我们提供了两全其美的优势。您支持的语言越多,翻译人员查看文本文件并将其翻译成目标语言就越容易。定义数据表示后,开发人员无需关心应用程序以何种语言显示。
包含
到目前为止,我们已经清楚地了解了数据如何表示,现在我们需要定义如何将这些数据集成到应用程序中。我们将使用包含文件和面向对象来实现所需的功能。在最高层,我们需要知道我们将显示哪种语言,这可以通过一个名为 USING_LANGUAGE 的变量来实现。每种支持的语言都将有一个关联的值,该值将包含在一个支持的语言文件中。
我们支持的语言文件示例
LANUGAGE_ENGLISH = 0 LANGUAGE_SPANISH = 1 LANGUAGE_FRENCH = 2 LANGUAGE_CUBAN = 3
支持的语言文件将包含在 Web 应用程序的每个页面中。在处理服务器端脚本传递时,优化是需要关注的问题,因此我将把每个依赖语言的 include 拆分成单独的文件,并放置在不同的目录中。这将防止每个页面的性能受到大量 if/then/else 语句的影响。我们的目录结构如下:
(root) (language files) (localized)
因此,如果我们添加主页,目录将如下所示:
(root) home.asp (language files) I_supported_languages.asp I_home.asp (localized) I_home_english.asp I_home_spanish.asp I_home_french.asp I_home_cuban.asp
根目录中的 home.asp 是实际页面,它将包含 I_supported_languages.asp 和“language files”目录中的 I_home.asp。“language files”目录中的 I_home.asp 将根据我们的 USING_LANGUAGE 变量包含适当的本地化文件。让我们看看 I_home.asp 文件里面有什么
I_home.asp 的列表
<%if USING_LANGUAGE = "LANUGAGE_ENGLISH" then%> <!--#INCLUDE FILE=" localized /I_home_english.asp" --> <%elseif USING_LANGUAGE = "LANGUAGE_SPANISH" then%> <!--#INCLUDE FILE=" localized /I_home_spanish.asp" --> <%elseif USING_LANGUAGE = "LANGUAGE_FRENCH" then%> <!--#INCLUDE FILE=" localized /I_home_french.asp" --> <%elseif USING_LANGUAGE = "LANGUAGE_CUBAN" then%> <!--#INCLUDE FILE=" localized /I_home_cuban.asp" -->
通过查看上面的列表,我们可以看到,如果在包含 I_home.asp 之前我们将 USING_LANGUAGE 变量设置为 LANGUAGE_ENGLISH,它会指示 I_home.asp 包含 I_home_english.asp 文件。你问那有什么用?让我们看看 I_home_english.asp 文件内部,找出答案
I_home_english.asp 的列表
<% ‘ English Data Representations for home.asp dr_txt_PAGETITLE = "Welcome to MyStore.com" dr_txt.ABOUT = "MyStore.com is the ecommerce site of the century. " &_ "You will find that we have only the best goods and services." dr_txt.SENDEMAIL = "Send Us Some Email" %>
通过包含上面列出的文件,我们现在可以访问数据表示,而不是实际文本。我之前提到过,我们的基本语言是英语,这就是为什么变量是英语的原因。通过查看实际的 home.asp 页面,您将看到这一切是如何组合在一起的。
home.asp 的列表
<!--#INCLUDE FILE=" language files / I_supported_languages.asp" --> <% USING_LANGUAGE = "LANUGAGE_ENGLISH" %> <!--#INCLUDE FILE=" language files / I_home.asp" --> <center> <b> <%=dr_txt_PAGETITLE%> </b> <br> <%= dr_txt.ABOUT %> <br> <a HREF=mailto://president@aol.com><%=dr_txt.SENDEMAIL %></a>
如果通过浏览器查看,输出将如下所示
欢迎来到MyStore.comMyStore.com是本世纪的电商网站。您将发现我们只提供最好的商品和服务。
给我们发邮件 |
这是一个非常简单的页面,但它表明开发人员不再需要关心文本是哪种语言。通过更改 USING_LANGUAGE 变量,页面会立即更改为相应的语言。要添加新语言,我们只需要发送 I_home_english.asp 页面(都是文本),让翻译人员修改等号后面的文本,然后在 supported languages 文件中添加相应的语言标题。您此时可能想知道为什么不直接用所需语言创建页面。原因是基于网络的应用程序通常在页面上有很多代码,如果我们有 5 个页面代表不同的语言,那么当开发人员更改一个页面上的代码时,他们将不得不更改所有 5 个页面中的代码。这也带来了一个重要的问题:何时进行文件翻译。只有当页面完成并准备发布时,才应该进行翻译。在此之前的任何时候,您都将面临持续不断的未翻译项目的斗争。
现在我们可以用任何语言显示页面了,我们需要解决另外两个问题。
货币
上一节介绍了我们以语言独立方式处理文本和图像对象的方法。现在我们将处理货币换算。面向对象将为我们提供将货币作为语言独立数据表示来处理的手段。我们需要创建一个对象,它将以美分表示的美元基本面额转换为所需的货币。一个需要解决的问题是,某人可能正在用西班牙语查看页面,但将用美元购买商品。我们通过创建一个名为 USING_CURRENCY 的新变量来解决这个问题,该变量将告诉我们的应用程序客户希望查看哪种货币。汇率和转换最好由第三方处理,因此我建议使用 Cloanto 货币服务器。Cloanto 货币服务器(995 美元)提供每日更新的汇率来源,与 ASP 接口后,它为我们提供了一种将我们的美国美分(产品、运费)转换为 Cloanto 货币服务器支持的所有面额的方法——以下是一个长列表(来源:www.cloanto.com)
安圭拉 |
东加勒比元 |
XCD |
安提瓜和巴布达 |
东加勒比元 |
XCD |
阿拉伯埃及共和国 |
埃及镑 |
EGP |
阿根廷共和国 |
阿根廷比索 |
ARS |
阿鲁巴 |
阿鲁巴盾 |
AWG |
阿塞拜疆共和国 |
阿塞拜疆马纳特 |
AZM |
巴巴多斯 |
巴巴多斯元 |
BBD |
伯利兹 |
伯利兹元 |
BZD |
百慕大 |
百慕大元 |
BMD |
波斯尼亚和黑塞哥维那 |
波斯尼亚第纳尔; 波斯尼亚可兑换马克 |
BAD; BAM |
英属维尔京群岛 |
美元 |
USD |
布基纳法索 |
非洲金融共同体法郎 |
XOF |
Canada |
加拿大元 |
CAD |
开曼群岛 |
开曼群岛元 |
KYD |
中非共和国 |
非洲金融共同体法郎 |
XAF |
圣诞岛领地 |
澳大利亚元 |
AUD |
澳大利亚联邦 |
澳大利亚元 |
AUD |
多米尼克联邦 |
东加勒比元 |
XCD |
波多黎各联邦 |
美元 |
USD |
巴哈马联邦 |
巴哈马元 |
BSD |
北马里亚纳群岛联邦 |
美元 |
USD |
库克群岛 |
新西兰元 |
NZD |
圭亚那合作共和国 |
圭亚那元 |
GYD |
捷克共和国 |
捷克克朗 |
CZK |
朝鲜民主主义人民共和国 |
朝鲜元 |
KPW |
圣多美和普林西比民主共和国 |
多布拉 |
STD |
刚果民主共和国 |
新扎伊尔 |
ZRN |
斯里兰卡民主社会主义共和国 |
斯里兰卡卢比 |
LKR |
法属圭亚那省 |
法国法郎 |
FRF |
瓜德罗普省 |
法国法郎 |
FRF |
马提尼克省 |
法国法郎 |
FRF |
留尼汪省 |
法国法郎 |
FRF |
多米尼加共和国 |
多米尼加比索 |
DOP |
东帝汶 |
印度尼西亚盾 |
IDR |
乌拉圭东岸共和国 |
乌拉圭比索 |
UYU |
欧盟 |
欧元 |
EUR |
法罗群岛 |
丹麦克朗 |
DKK |
福克兰群岛 |
福克兰群岛镑 |
FKP |
埃塞俄比亚联邦民主共和国 |
埃塞俄比亚比尔 |
ETB |
德意志联邦共和国 |
德国马克 |
DEM |
尼日利亚联邦共和国 |
奈拉 |
NGN |
南斯拉夫联邦共和国 |
南斯拉夫第纳尔 |
YUM |
南斯拉夫联邦共和国 |
南斯拉夫新第纳尔 |
YUD |
密克罗尼西亚联邦 |
美元 |
USD |
圣基茨和尼维斯联邦 |
东加勒比元 |
XCD |
巴西联邦共和国 |
巴西雷亚尔 |
BRL |
前南斯拉夫的马其顿共和国 |
第纳尔 |
MKD |
法兰西共和国 |
法国法郎 |
FRF |
加蓬共和国 |
非洲金融共同体法郎 |
XAF |
格鲁吉亚 |
拉里 |
GEL |
直布罗陀 |
直布罗陀镑 |
GIP |
卢森堡大公国 |
卢森堡法郎 |
LUF |
格陵兰 |
丹麦克朗 |
DKK |
格林纳达 |
东加勒比元 |
XCD |
约旦哈希姆王国 |
约旦第纳尔 |
JOD |
希腊共和国 |
希腊德拉克马 |
GRD |
香港特别行政区(HKSAR) |
港元 |
HKD |
巴布亚新几内亚独立国 |
基那 |
PGK |
萨摩亚独立国 |
塔拉 |
WST |
爱尔兰 |
爱尔兰镑 |
IEP |
科摩罗伊斯兰联邦共和国 |
科摩罗法郎 |
KMF |
伊朗伊斯兰共和国 |
伊朗里亚尔 |
IRR |
毛里塔尼亚伊斯兰共和国 |
毛里塔尼亚乌吉亚 |
MRO |
巴基斯坦伊斯兰共和国 |
巴基斯坦卢比 |
PKR |
阿富汗伊斯兰国 |
阿富汗尼 |
AFA |
意大利共和国 |
意大利里拉 |
ITL |
牙买加 |
牙买加元 |
JMD |
日本 |
日元 |
JPY |
比利时王国 |
比利时法郎 |
BEF |
不丹王国 |
努扎姆 |
BTN |
柬埔寨王国 |
瑞尔 |
KHR |
丹麦王国 |
丹麦克朗 |
DKK |
莱索托王国 |
洛蒂 |
LSL |
摩洛哥王国 |
摩洛哥迪拉姆 |
MAD |
尼泊尔王国 |
尼泊尔卢比 |
NPR |
挪威王国 |
挪威克朗 |
NOK |
沙特阿拉伯王国 |
沙特里亚尔 |
SAR |
西班牙王国 |
西班牙比塞塔 |
ESP |
斯威士兰王国 |
里拉吉尼 |
SZL |
瑞典王国 |
瑞典克朗 |
SEK |
泰王国 |
泰铢 |
THB |
荷兰王国 |
荷兰盾 |
NLG |
汤加王国 |
潘加 |
TOP |
吉尔吉斯共和国 |
索姆 |
KGS |
老挝人民民主共和国 |
基普 |
LAK |
黎巴嫩共和国 |
黎巴嫩镑 |
LBP |
澳门 |
澳门元 |
MOP |
马来西亚 |
马来西亚林吉特 |
MYR |
蒙古 |
图格里克 |
MNT |
蒙特塞拉特 |
东加勒比元 |
XCD |
文莱达鲁萨兰国 |
文莱元 |
BND |
荷属安的列斯群岛 |
荷属安的列斯盾 |
ANG |
新西兰 |
新西兰元 |
NZD |
纽埃 |
新西兰元 |
NZD |
阿尔及利亚民主人民共和国 |
阿尔及利亚第纳尔 |
DZD |
孟加拉人民共和国 |
塔卡 |
BDT |
中华人民共和国 |
人民币元 |
CNY |
皮特凯恩群岛 |
新西兰元 |
NZD |
葡萄牙共和国 |
葡萄牙埃斯库多 |
PTE |
安道尔公国 |
西班牙比塞塔;法国法郎 |
ESP;FRF |
列支敦士登公国 |
瑞士法郎 |
CHF |
摩纳哥公国 |
法国法郎 |
FRF |
阿尔巴尼亚共和国 |
列克 |
ALL |
安哥拉共和国 |
调整后的宽扎 |
AON |
亚美尼亚共和国 |
德拉姆 |
AMD |
奥地利共和国 |
奥地利先令 |
ATS |
白俄罗斯共和国 |
白俄罗斯卢布 |
BYB |
贝宁共和国 |
非洲金融共同体法郎 |
XOF |
玻利维亚共和国 |
玻利维亚诺 |
BOB |
博茨瓦纳共和国 |
普拉 |
BWP |
保加利亚共和国 |
列弗 |
BGL |
布隆迪共和国 |
布隆迪法郎 |
BIF |
喀麦隆共和国 |
非洲金融共同体法郎 |
XAF |
佛得角共和国 |
佛得角埃斯库多 |
CVE |
乍得共和国 |
非洲金融共同体法郎 |
XAF |
智利共和国 |
智利比索 |
CLP |
中华民国 |
新台币 |
TWD |
哥伦比亚共和国 |
哥伦比亚比索 |
COP |
哥斯达黎加共和国 |
哥斯达黎加科朗 |
CRC |
科特迪瓦共和国 |
非洲金融共同体法郎 |
XOF |
克罗地亚共和国 |
库纳 |
HRK |
古巴共和国 |
古巴比索 |
CUP |
塞浦路斯共和国 |
塞浦路斯镑 |
CYP |
吉布提共和国 |
吉布提法郎 |
DJF |
厄瓜多尔共和国 |
苏克雷 |
ECS |
萨尔瓦多共和国 |
萨尔瓦多科朗 |
SVC |
赤道几内亚共和国 |
非洲金融共同体法郎 |
XAF |
爱沙尼亚共和国 |
爱沙尼亚克朗 |
EEK |
斐济共和国 |
斐济元 |
FJD |
芬兰共和国 |
芬兰马克 |
FIM |
加纳共和国 |
塞地 |
GHC |
危地马拉共和国 |
危地马拉格查尔 |
GTQ |
几内亚共和国 |
几内亚法郎 |
GNF |
几内亚比绍共和国 |
非洲金融共同体法郎 |
XOF |
海地共和国 |
古德 |
HTG |
洪都拉斯共和国 |
伦皮拉 |
HNL |
匈牙利共和国 |
福林 |
HUF |
冰岛共和国 |
冰岛克朗 |
ISK |
印度共和国 |
印度卢比 |
INR |
印度尼西亚共和国 |
印度尼西亚盾 |
IDR |
伊拉克共和国 |
伊拉克第纳尔 |
IQD |
哈萨克斯坦共和国 |
坚戈 |
KZT |
肯尼亚共和国 |
肯尼亚先令 |
KES |
基里巴斯共和国 |
澳大利亚元 |
AUD |
大韩民国 |
韩元 |
KRW |
拉脱维亚共和国 |
拉特 |
LVL |
利比里亚共和国 |
利比里亚元 |
LRD |
立陶宛共和国 |
立特 |
LTL |
马达加斯加共和国 |
马达加斯加法郎 |
MGF |
马拉维共和国 |
马拉维克瓦查 |
MWK |
马尔代夫共和国 |
拉菲亚 |
MVR |
马里共和国 |
非洲金融共同体法郎 |
XOF |
马耳他共和国 |
马耳他里拉 |
MTL |
毛里求斯共和国 |
毛里求斯卢比 |
MUR |
摩尔多瓦共和国 |
摩尔多瓦列伊 |
MDL |
莫桑比克共和国 |
梅蒂卡尔 |
MZM |
纳米比亚共和国 |
纳米比亚元 |
NAD |
瑙鲁共和国 |
澳大利亚元 |
AUD |
尼加拉瓜共和国 |
科尔多瓦 |
NIO |
尼日尔共和国 |
非洲金融共同体法郎 |
XOF |
帕劳共和国 |
美元 |
USD |
巴拿马共和国 |
巴波亚 |
PAB |
巴拉圭共和国 |
瓜拉尼 |
PYG |
秘鲁共和国 |
新索尔 |
PEN |
波兰共和国 |
兹罗提 |
PLZ |
圣马力诺共和国 |
意大利里拉 |
ITL |
塞内加尔共和国 |
非洲金融共同体法郎 |
XOF |
塞舌尔共和国 |
塞舌尔卢比 |
SCR |
塞拉利昂共和国 |
利昂 |
SLL |
新加坡共和国 |
新加坡元 |
SGD |
斯洛文尼亚共和国 |
托拉尔 |
SIT |
南非共和国 |
兰特 |
ZAR |
苏丹共和国 |
苏丹镑 |
SDD |
苏里南共和国 |
苏里南盾 |
SRG |
塔吉克斯坦共和国 |
塔吉克卢布 |
TJR |
刚果共和国 |
非洲金融共同体法郎 |
XAF |
冈比亚共和国 |
达拉西 |
GMD |
马绍尔群岛共和国 |
美元 |
USD |
菲律宾共和国 |
菲律宾比索 |
PHP |
特立尼达和多巴哥共和国 |
特立尼达和多巴哥元 |
TTD |
突尼斯共和国 |
突尼斯第纳尔 |
TND |
土耳其共和国 |
土耳其里拉 |
TRL |
乌干达共和国 |
乌干达先令 |
UGX |
乌兹别克斯坦共和国 |
sum |
UZS |
瓦努阿图共和国 |
瓦图 |
VUV |
委内瑞拉共和国 |
玻利瓦尔 |
VEB |
也门共和国 |
也门里亚尔 |
YER |
赞比亚共和国 |
赞比亚克瓦查 |
ZMK |
津巴布韦共和国 |
津巴布韦元 |
ZWD |
罗马尼亚 |
罗马尼亚列伊 |
ROL |
俄罗斯联邦 |
新卢布 |
RUB |
卢旺达共和国 |
卢旺达法郎 |
RWF |
圣赫勒拿岛及属地 |
圣赫勒拿镑 |
SHP |
圣卢西亚 |
东加勒比元 |
XCD |
圣文森特和格林纳丁斯 |
东加勒比元 |
XCD |
斯洛伐克共和国 |
斯洛伐克克朗 |
SKK |
利比亚阿拉伯社会主义人民民众国 |
利比亚第纳尔 |
LYD |
越南社会主义共和国 |
越南盾 |
VND |
所罗门群岛 |
所罗门群岛元 |
SBD |
索马里民主共和国 |
索马里先令 |
SOS |
巴林国 |
巴林第纳尔 |
BHD |
厄立特里亚国 |
纳克法 |
ERN |
以色列国 |
新谢克尔 |
ILS |
科威特国 |
科威特第纳尔 |
KWD |
卡塔尔国 |
卡塔尔里亚尔 |
QAR |
阿曼苏丹国 |
阿曼里亚尔 |
OMR |
斯瓦尔巴群岛和扬马延岛 |
挪威克朗 |
NOK |
瑞士联邦 |
瑞士法郎 |
CHF |
阿拉伯叙利亚共和国 |
叙利亚镑 |
SYP |
马约特领土集体 |
法国法郎 |
FRF |
圣皮埃尔和密克隆领土集体 |
法国法郎 |
FRF |
美属萨摩亚领地 |
美元 |
USD |
科科斯(基林)群岛领地 |
澳大利亚元 |
AUD |
法属波利尼西亚领地 |
太平洋法郎 |
XPF |
关岛领地 |
美元 |
USD |
新喀里多尼亚和属地领地 |
太平洋法郎 |
XPF |
诺福克岛领地 |
澳大利亚元 |
AUD |
瓦利斯和富图纳群岛领地 |
太平洋法郎 |
XPF |
教廷 |
意大利里拉 |
ITL |
多哥共和国 |
非洲金融共同体法郎 |
XOF |
托克劳 |
新西兰元 |
NZD |
土库曼斯坦 |
土库曼马纳特 |
TMM |
特克斯和凯科斯群岛 |
美元 |
USD |
图瓦卢 |
澳大利亚元 |
AUD |
乌克兰 |
格里夫尼亚 |
UKH |
缅甸联邦 |
缅元 |
MMK |
阿拉伯联合酋长国 |
阿联酋迪拉姆 |
AED |
大不列颠及北爱尔兰联合王国 |
英镑 |
GBP |
墨西哥合众国 |
墨西哥比索 |
MXN |
坦桑尼亚联合共和国 |
坦桑尼亚先令 |
TZS |
美国本土外小岛屿 |
美元 |
USD |
美利坚合众国 |
美元 |
USD |
美属维尔京群岛 |
美元 |
USD |
自己实现转换程序将是低效的,而且很可能比 Cloanto 收取的 995.00 美元贵得多。正如我之前提到的,我们将使用 USING_CURRENCY 变量来定义所需的转换。我们将创建一个 ASP 脚本对象来缓冲货币转换的实际实现。完成后,要获取任何货币的值,我们应该能够执行以下操作:
// Include the supported languages file <!--#INCLUDE FILE=" language files / I_supported_languages.asp" --> // Set the language to English <% USING_LANGUAGE = "LANUGAGE_ENGLISH" %> // Set our target currency to be Tanzanian shillings <% USING_CURRENCY = "TZS" %> <center> Us Dollars: $10.00 Tanzanian shillings: <%=localCurrency.ConvertFromUS(1000)%>
请注意“<%=local_Currency(1000)%>”这一行,我们将 10.00 美元(以美分为单位)发送到名为 localCurrency 的对象中的 ConvertFromUS 函数。结果应该是 10.00 美元在坦桑尼亚先令中的表示。我们在代码中使用美分来表示货币,因为美分可以在不使用小数点的情况下反映全部或部分美元金额(这可以加快计算速度)。
创建 localCurrency 对象
在上一节中,我们使用了一个名为“localCurrency”的虚构对象,将我们(美国)美分转换为我们想要的任何面额。现在我们将创建 localCurrency 对象。
Outline
LocalCurrency // Methods ConvertFromUS (method) // Properties m_sCurrencyCode (string based representation of the destination denomination EX: "TZS") m_objCloanto (Cloanto Conversion Object)
通过创建此对象并调用 ConvertFromUS 方法,开发人员不再需要关心客户端正在查看何种货币。将此放入对象的另一个好处是,如果转换方法从使用 Cloanto 更改,开发人员只需更改此对象的实现,而无需更改其他任何内容。例如,有 50 个页面使用 LocalCurrency 对象进行货币转换。如果我们的公司决定使用 WidgetCompanies 的解决方案而不是 Cloanto,开发人员只需修改 ConvertFromUS 的实现(它位于单个文件中),功能就会传递到所有 50 个页面,而无需触及它们。
我们将在 I_supported_languages.asp 文件中创建并包含 LocalCurrency 对象。这样,每当该文件被包含时,我们就知道我们已经掌握了语言和货币独立性。
创建 LocalCurrency 对象时,它将传递三字母货币代码。localCurrency 对象可以添加各种其他功能,但目前我们的单一方法已足够。
数据库文本
到目前为止,我们已经解决了网络应用程序本地化的大部分问题。现在,我们所有的页面和货币都能够以不同的语言显示。最后一个要解决的问题是,电子商务在数据库中存储了大量的文本。产品名称、描述、商店名称、信息文本都存储在数据库中。我们如何本地化数据库条目?我们只需要关注最终用户将看到的文本,但这仍然给我们留下了一个重要问题。解决方案是能够判断特定记录支持哪些语言,然后从数据库中提取特定语言字段。如果特定记录不支持所需语言,我们将不得不默认为它所支持的语言。如果我们从数据库中提取已知记录,这很容易,但当处理像产品搜索这样动态的东西时,就变得很棘手了。您不希望在查询包含数千(或更多)条记录的数据库时查看每个项目,这会很慢,并且不适用于多个用户可能同时访问数据库的网络环境。我们将在大小和速度之间进行权衡。对于记录集中每个具有可查看文本的条目,我们将实际复制与所支持语言数量相等的条目。为了阐明这一点,我们将创建支持语言的表格表示。
此表主要用于参考和管理。
支持的语言表
Lanugage : (string representation of language)
LanguageID : (ID of the language)
如果我们回顾之前基于页面的本地化实现,我们使用以下变量来描述所需语言
LANGUAGE_ENGLISH = 0 LANGUAGE_SPANISH = 1 LANGUAGE_FRENCH = 2 LANGUAGE_CUBAN = 3
我们现在将这些值放入我们的支持语言表中
Language: English LanguageID: 0 Language: Spanish LanguageID: 1 Language: French LanguageID: 2 Language: Cuban LanguageID: 3
现在我们已经有了整个应用程序支持哪些语言的参考,我们需要深入研究特定的记录集,看看它是如何使用的。让我们以一个非常简单的产品表为例
Product Table (not localized) ProductID : (ID of product) ProductName : (String Representation of products name) Price_retail : (retail Price in pennies) Description : (string representation of product description) Notes : (string representation of additional product notes)
产品条目的一个例子是
ProductID: 55 ProductName: SuperSlingShot5000 Price_retail: 1000 Description: Introducing the SuperSlingShot5000, the finest slingshot you could ever own. Can propel an acorn over 200 yards. Notes: Not recommended for children under the age of 15
由于我们只关注将呈现给最终用户的文本,因此我们不会触及 ProductID、Price_retail 或 ProductName 字段。产品名称理论上可以考虑本地化,但我不认为它适用。要本地化此条目,我们首先需要通过添加 languages_supported 字符串字段来指定此条目支持哪些语言。我们修改后的表现在具有以下结构
ProductID : (ID of product) ProductName : (String Representation of products name) Price_retail : (retail Price in pennies) Description : (string representation of product description) Notes : (string representation of additional product notes) Languages_supported : (list of languages supported separated by commas)
我们将使用逗号分隔的支持语言 ID 字符串列表
ProductID: 55 ProductName: SuperSlingShot5000 Price_retail: 1000 Description: Introducing the SuperSlingShot5000, the finest slingshot You could ever own. Can propel an acorn over 200 yards. Notes: Not recommended for children under the age of 15 Languages_supported 0
如果我们支持英语和西班牙语,Languages_Supported 字段将如下所示
Languages_supported 0,1
我们现在必须添加与整个应用程序支持的语言数量相等的本地化字段。尽管我们目前只在表中支持英语,但整个应用程序支持 4 种语言。这是我们示例表的最终结构
ProductID : (ID of product) ProductName : (String Representation of products name) Price_retail : (retail Price in pennies) Description0 : (string representation of product description) Description1 : (string representation of product description) Description2 : (string representation of product description) Description3 : (string representation of product description) Notes0 : (string representation of additional product notes) Notes1 : (string representation of additional product notes) Notes2 : (string representation of additional product notes) Notes3 : (string representation of additional product notes) Languages_supported : (list of languages supported separated by commas)
现在每个字段的末尾都附加了语言 ID。现在我们可以获取任何支持语言的任何字段。如果我们的记录集只支持英语,而整个应用程序支持四种不同的语言怎么办?这个问题在记录生成时解决。无论记录最终将支持多少种语言,我们都会将记录创建时使用的任何语言填充到所有语言字段中。因此,如果此记录只支持英语,则 Description0-3 将全部包含英语。复制数据可能看起来很浪费,但请记住我们正在用速度换取大小。使用上述方法,我们可以通过提取 Description0 来查询整个英文数据库,或通过 Description1 来查询西班牙文数据库,我们不需要验证每个条目是否符合要求。
整合
本文档涵盖了大量内容,但现在我们将把它们整合在一起。通过使用名为 USING_LANGUAGE 的变量,我们现在能够更改页面显示的语言。通过使用名为 USING_CURRENCY 的变量,我们可以更改货币显示的面额。由于我们已经对整个数据库进行了本地化,我们现在可以使用相同的变量(USING_LANGUAGE - 已在每个页面上定义)来知道要提取哪些字段。
从头开始,我们为将新语言和货币无缝集成到我们的应用程序中奠定了基础。通过在数据库端牺牲空间换取速度,使用第三方解决方案进行货币兑换,以及我们使用“语言包含文件”,最大限度地提高了开发时间和应用程序速度。在规划应用程序本地化时,我对细节的关注怎么强调都不为过。项目中的每个人,从销售人员到开发人员,都需要沟通并了解彼此的职责和时间表。只有团队合作,像电子商务网站这样庞大的项目才能成功本地化并发布。