`
yesjavame
  • 浏览: 688426 次
  • 性别: Icon_minigender_2
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

AOM 2.0的神奇魔力之二:国际化

阅读更多

AOM 2.0的神奇魔力之二:国际化

Kevin

1.前言

本教程介绍在 AOM 2.0中,是如何简化国际化多语言相关工作的。在阅读本文之前,我建议你首先阅读第一篇文章:

http://www.operamasks.org/articles/magic-1/html_single

2.常规国际化的做法

假设我们现在希望让 Calculator 这个示例支持中英文,让我们先回顾一下常规JSF的实现手段:

首先,我们需要准备两个资源文件,分别是:

#demo.LocalStrings_en_US.properties
first.label=First:
second.label=Second:
result.label=Result:
add.label= +
subtract.label= -
multiply.label= *
divide.label = /
#demo.LocalStrings_zh_CN.properties
first.label=数值一:
second.label=数值二:
result.label=结果:
add.label= +
subtract.label= -
multiply.label= *
divide.label = /

当然,我们需要通过 Ant 将上述的LocalStrings_zh_CN.properties进行 native2ascii 的转换,这是基础知识,不是本文介绍的重点。

为了使用上述资源文件,我们的页面要改成这样:

<f:view xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://java.sun.com/jsf/core"
xmlns:w="http://www.apusic.com/jsf/widget" xmlns:layout="http://www.apusic.com/jsf/layout"
renderKitId="AJAX" xmlns:h="http://java.sun.com/jsf/html">
<f:loadBundle basename="demo.LocalStrings" var="msgs"/>
<w:page title="Calculator">
<w:form id="calc">
<layout:panelGrid columns="3">
<h:outputLabel for="first" value="#{msgs['first.label']}"/>
<w:textField id="first"/>
<h:message for="first" value="#{msgs['second.label']}"/>
<h:outputLabel for="second"/>
<w:textField id="second"/>
<h:message for="second"/>
<h:outputLabel for="result" value="#{msgs['result.label']}"/>
<h:outputText id="result"/>
</layout:panelGrid>
<br/>
<layout:panelGrid columns="4">
<w:button id="add" value="#{msgs['add.label']}"/>
<w:button id="subtract" value="#{msgs['subtract.label']}"/>
<w:button id="multiply" value="#{msgs['multiply.label']}"/>
<w:button id="divide" value="#{msgs['divide.label']}"/>
</layout:panelGrid>
</w:form>
</w:page>
</f:view>

经过对页面进行上述修订,在中文环境下,页面运行效果如下图所示:

而在英文环境中,运行效果是这样的:

看上去好像也完成了我们的需求,但回过头来看看我们的页面,已经被我们改的面目全非。倘若这个页面是由美工设计的,请问,她知道什么叫做资源文件吗?她知道什么是 "#{msgs['add.label']}" 吗?

让我们忘掉这种丑陋的做法吧,看看 AOM 会带来怎样的魔力!

3.AOM 2.0 的国际化处理

首先,让我们把页面恢复成原先那整洁的基于IoVC原理的页面:

<f:view xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://java.sun.com/jsf/core"
xmlns:w="http://www.apusic.com/jsf/widget" xmlns:layout="http://www.apusic.com/jsf/layout"
renderKitId="AJAX" xmlns:h="http://java.sun.com/jsf/html">
<w:page title="Calculator">
<w:form id="calc">
<layout:panelGrid columns="3">
<h:outputLabel for="first"/>
<w:textField id="first"/>
<h:message for="first"/>
<h:outputLabel for="second"/>
<w:textField id="second"/>
<h:message for="second"/>
<h:outputLabel for="result"/>
<h:outputText id="result"/>
</layout:panelGrid>
<br/>
<layout:panelGrid columns="4">
<w:button id="add"/>
<w:button id="subtract"/>
<w:button id="multiply"/>
<w:button id="divide"/>
</layout:panelGrid>
</w:form>
</w:page>
</f:view>

我们继续保留 LocalStrings_en_US.properties 以及 LocalStrings_zh_CN.properties这 两个资源文件,但为了做到多语言,我们唯一需要做的事情是,将这两个资源文件的内容修订成如下内容:

#demo.LocalStrings_en_US.properties
CalcBean.first.label=First:
CalcBean.second.label=Second:
CalcBean.result.label=Result:
CalcBean.add.label= +
CalcBean.subtract.label= -
CalcBean.multiply.label= *
CalcBean.divide.label = /
#demo.LocalStrings_zh_CN.properties
CalcBean.first.label=数值一:
CalcBean.second.label=数值二:
CalcBean.result.label=结果:
CalcBean.add.label= +
CalcBean.subtract.label= -
CalcBean.multiply.label= *
CalcBean.divide.label = /

换言之,我们只是在资源串中的key上,加了一个限定词:CalcBean,然后,让我们运行这个页面。

你会发觉:哇,页面已经是多语言的了,这就是你想要的!

但回顾你做的工作,你会发觉,这是多么的简单,多么的享受!

4.AOM的扩展能力

我们现在希望对这个示例扩展一下:当鼠标移到第一个<w:textFiled>时,希望能够显示提示“请输入第一个参数”;当鼠标移到add button时,希望能够显示提示“将这些数值相加”。那么,我们只需要扩展一下这两个资源文件:

#demo.LocalStrings.properties
CalcBean.first.description=Please input the first number
CalcBean.add.description=Add these numbers
#demo.LocalStrings_zh_CN.properties
CalcBean.first.description=请输入第一个数值
CalcBean.add.description=将数值相加

然后,我们重新运行此页面,你会发觉,你预期的效果已经达到了!

我们还可以做的更好!

假设我们有这样一种场景:“add”这个Button,在中文环境下显示“加”,在英文环境下显示“Plus”,由于语言的差异, 导致在不同语言下,button的宽度发生变化。我们希望,在中文环境下,此按钮的宽度为 30,而在英文环境下,此按钮的宽度为 60。那么,我们该怎么办?

解决这个问题的思路,无非要把宽度作为一个多语言资源拿出来放到properties文件中,但我们要怎么做呢?难道在页面中写入: <w:button id="add" minWidth="#{msgs['add.minWidth]}"/>?这样一来,岂非很丑陋?在 AOM 2.0中,我们只需要更改一下LocalStrings_zh_CN.properties 文件:

#demo.LocalStrings_zh_CN.properties
CalcBean.add.minWidth=30
CalcBean.subtract.minWidth=30
CalcBean.multiply.minWidth=30
CalcBean.divide.minWidth=30

我们来看一下运行效果:

我们再更改一下LocalStrings_en_US.properties:

#demo.LocalStrings_en_US.properties
CalcBean.add.minWidth=60
CalcBean.subtract.minWidth=60
CalcBean.multiply.minWidth=60
CalcBean.divide.minWidth=60

注意,上述资源文件中设置最小宽度为60,比中文环境下的设置大了一倍,那么,在英文环境下,效果如下:

是不是非常之简单?让我们再来看一看更高级的用法。

5.在程序中注入资源文件

假设我们现在有这样一种需求:当用户点击某一个操作时,result并不仅仅简单的显示一个结果, 我们还希望能够显示用户的操作是什么,譬如,当用户执行 1 + 2 操作时,中文环境下显示:"数据 1 加 数据 2 等于 3",英文环境下显示:"Number 1 add number 2 equals 3"。换言之,我们现在要对多语言字符串进行参数化处理。在 AOM 2.0 中是怎样做的呢?

首先,我们需要把页面改一下:

<f:view xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://java.sun.com/jsf/core"
xmlns:w="http://www.apusic.com/jsf/widget" xmlns:layout="http://www.apusic.com/jsf/layout"
renderKitId="AJAX" xmlns:h="http://java.sun.com/jsf/html">
<w:page title="Calculator">
<w:form id="calc">
<layout:panelGrid columns="3">
<h:outputLabel for="first" />
<w:textField id="first" />
<h:message for="first" />
<h:outputLabel for="second" />
<w:textField id="second" />
<h:message for="second" />
1<layout:cell colspan="3" rowspan="1"> <h:outputText id="resultLabel" />
</layout:cell>
</layout:panelGrid>
<br />
<layout:panelGrid columns="4">
<w:button id="add" />
<w:button id="subtract" />
<w:button id="multiply" />
<w:button id="divide" />
</layout:panelGrid>
</w:form>
</w:page>
</f:view>

请注意,我们将<h:outputText>进行了修订,它占据了三列,id改为resultLabel。

然后,我们需要修订 CalcBean,修订如下:

@ManagedBean(scope = ManagedBeanScope.REQUEST)
public class CalcBean {

@Bind
private double first = 22.0;

@Bind
private double second = 7.0;

@Bind
private String resultLabel;

/**
* 注入资源文件
*/
@LocalString
private Map<String,String> messages;

/**
* 用来保存计算结果
*/
private double result = 0;

/**
* 用来保存用户的操作符
*/
private String operator = "";

@Action
public void add() {
result = first + second;
operator = "+";
}

@Action
public void subtract() {
result = first - second;
operator = "-";
}

@Action
public void multiply() {
result = first * second;
operator = "*";
}

@Action
public void divide() {
result = first / second;
operator = "/";
}

@BeforeRender
private void beforeRender(boolean isPostBack) {
resultLabel = MessageFormat.format(messages.get("resultLabel"), first, operator, second, result);
}
}

请注意,在CalcBean中,我们声明了两个临时变量 result 和 operator 来保存用户的计算结果及操作符,另外,声明了一个 @BeforeRender 的方法,意思就是告诉AOM,在你决定渲染前,请调用此方法。 我们在这个方法中,设置 resultLabel的具体值。那么,资源文件是怎样获取得呢?非常简单,只需要在前面声明一个private @LocalString Map<String,String> messages 即可。

再来看一下我们的资源文件:

#demo.LocalStrings_en_US.properties
CalcBean.resultLabel=Number {0} {1} number {2} equals {3}
#demo.LocalStrings_zh_CN.properties
CalcBean.resultLabel=数值 {0} {1} 数值 {2} 等于 {3}

我们在获取上述资源以后,只需要对其进行一下 format,将参数传递进去,即可获得我们期望的结果:

等等,这里好像有一个疑问:你只是帮我把资源文件的获取简化了,但在对资源字符串的解析上,AOM好像并没有带来任何改进, 我还是需要调用 MessageFormat.format 方法,在这方面上,AOM能否带来一些便利呢?要知道,我可是非常懒惰的。

OK,我只能说:AOM 的 ELite 对资源文件的处理是非常简单的,简单到令人之发指,但同时,这也超出了本章所要阐述的范围,且留待下一章节分解吧。

6.总结

本章节,我们体会了 AOM 2.0 对国际化的处理,我想,我们已经不需要再去阐述 AOM 和常规处理模式的差异了,再次重申:AOM,确实是为“懒人”准备的。

分享到:
评论

相关推荐

    QTP AOM帮助文档

    使用QTP的automation object model,可以对QTP进行自动化编程,从而自动对QTP进行选项设置、自动运行测试(或组件),而无需使用QTP界面手工进行这些操作。 如果要重复多次的完成同一项工作任务,或重复多次运行同一...

    -AoM--Client:客户端实施改装平台

    什么是 AoM? AoM 是 Argentum Online 的改装平台。 阅读有关 AoM 的更多信息版权所有 (c) 2015 AoM Powered 执照AoM 在下获得 ,请参阅LICENSE文件了解详细信息。贡献AoM 是 100% 免费和开源的。 我们鼓励并支持...

    第二波又来了:AOM3.2之8款皮肤分享(for extjs3.31)

    本文将深入探讨“第二波又来了:AOM3.2之8款皮肤分享(for extjs3.31)”这个主题,这是一次针对AOM(Opera Masks)3.2版本发布的皮肤更新,特别设计以兼容ExtJS 3.3.1框架。 AOM,全称Antelope on the Moon,是一个...

    编译android VLC时,需要的组件:aom-v1.0.0.errata.1.tar.gz

    `tarballs`子目录则可能包含了所有第三方库的源码或预编译二进制包。将`aom-v1.0.0.errata.1.tar.gz`放在这里,意味着在后续的构建过程中,VLC的构建系统会自动检测并处理这个组件。 编译VLC for Android的过程通常...

    aom-v1.0.0.errata.1.tar.gz

    标题 "aom-v1.0.0.errata.1.tar.gz" 指的是一个名为 "aom" 的开源项目,其版本为1.0.0的错误修复更新(errata)第一版,并以tar.gz格式打包。这个压缩包包含了项目的一些核心文件和文档,表明这可能是用于开发或维护...

    AOM之十二款(EXT样式)漂亮皮肤

    各位AOM的爱好者,AOM目前采用的默认EXT皮肤很漂亮,但是从1.0用到2.0再用到2.3,想必各位的项目都已经成熟稳定了,这时候很多人想锦上添花,让自己的项目更加出众一些,那就要在外观上做一些美化了。 遗憾的是,...

    AOM java原代码下载

    AOM(Academy of Motion Picture Arts and Sciences)是一个与电影技术相关的组织,而在此上下文中,它似乎指的是一个特定的Java项目或库。"AOM java原代码下载"的标题表明我们正在讨论的是该组织的Java源代码,可能...

    AOM 初体验(一)

    标题"AOM初体验(一)"以及描述中提到的工程打包下载,暗示了这是一个关于应用开发和集成环境的讨论,特别是涉及到AOM(可能是Apusic Application Object Model,一种中间件平台)的使用。标签"源码"和"工具"进一步...

    QTP/UFT AOM

    AOM 通过engine.vbs 启动UFT。

    AOM相关.rar

    标题"AOM相关.rar"指的是与AOMedia(简称AOM)相关的资料集合,这通常涉及到音视频编码技术,特别是AV1编码标准。AOMedia是一个开放的非营利组织,致力于开发下一代开源、免专利费的媒体编码技术,旨在提供高质量的...

    aom.zip_3344aom_aom.avcom_av1_h264_zip

    标题 "aom.zip_3344aom_aom.avcom_av1_h264_zip" 暗示了这是一个与视频编码相关的压缩文件,其中包含了AV1编码器的源代码,可能还有与H264编码的对比或转换相关的资料。描述 "av1 codec source open c++" 明确指出这...

    X-AOM权识区块链新经济 -泛AI时代投资多元的解决方案.pdf

    X-AOM权识区块链新经济项目旨在利用区块链技术,特别是在泛人工智能(AI)时代,为投资者提供多元化投资的策略。该项目的核心目标是建立一个全球化的平台,类似于中国的“高通”,通过这个平台,数据分享者能够从中...

    aom-v1.0.0.errata.1.zip

    标题 "aom-v1.0.0.errata.1.zip" 指示这是一个与开源视频编码库AV1相关的更新或修正文件。"errata"通常用于标识软件发布中的错误或修正,这意味着这个压缩包可能包含了针对aomedia(aom)v1.0.0版本的一些修复或改进...

    X-AOM_权识区块链新经济 -泛AI时代投资多元的解决方案(英语).pdf

    尽管没有具体细节,但可以推测X-AOM可能采取了去中心化、社区驱动的方式,以区别于传统的中心化企业。 6. **财务规划与市场预测**: 提到的时间线(2019年至2021年Q4)可能涉及到项目的开发进度和市场表现。数字...

    AOM金蝶入门

    AOM金蝶控件开发指南,入门,供大家学习

    海洋沉积物甲烷厌氧氧化作用(AOM)及其对无机硫循环的影响

    海洋沉积物甲烷厌氧氧化(AOM)作用是一个涉及甲烷和硫酸盐的生物地球化学过程,甲烷作为一种温室气体,在海洋沉积物中通过与硫酸盐还原菌作用被转化为二氧化碳或碳酸盐,同时硫酸盐作为电子受体被还原为硫化物。...

    AOM中的常用JavaScript

    在JavaScript的世界里,AOM(Accessibility Object Model)是一种新兴的标准,它旨在提升Web内容的可访问性,使得残障人士能够更好地与网页交互。AOM是Web开发领域中一个非常重要的概念,它与DOM(Document Object ...

Global site tag (gtag.js) - Google Analytics