I18N Implementation in ZK
Minjie Zha, Student, Software Institute specialising Software Engineering at Nanjing University, China.
March 25, 2007
Version
Applicable to ZK 2.2.0 and later.
Purpose
Internationalization is becoming more and more important in today's software development.
For a web site, multiple language support seems to be a necessary feature. In this article,
I am going to introduce how to implement I18N for your web pages with
org.zkoss.util.resource.Labels and taglib built in ZK.
A general login demo is presented to show you how to use them.
A General Login Demo
Following is a ZUL file, which displays a general login form:
<?xml version="1.0" encoding="UTF-8"?>
<?page title="I18N Login Demo"?>
<div align="center">
<window border="none" width="40%">
<separator spacing="50px"/>
<label id="errLabel" style="color: red"/>
<grid>
<rows>
<row>
<label value="username:"/>
<textbox id="namebox" constraint="no empty"/>
</row>
<row>
<label value="password:"/>
<textbox id="passwordbox" type="password" constraint="no empty"/>
</row>
<row spans="2" align="center">
<button label="login" onClick="onLogin()"/>
</row>
</rows>
<zscript>
void onLogin(){
// add code here
}
</zscript>
</window>
</div>
It is very simple, so I will not go to details.
Add I18N Support
However, the previous index.zul can't display different languages according to the client locale. Now, we are going make this by using labels.
A label is a Localedependent string that is stored in i3-label*.properties. We need two steps:
- Write all localedependent strings into i3-label*.properties
- Read them from i3-label*.properties with
org.zkoss.util.resource.Labels
So, firstly, create a file named i3-label_lang_CNTY.properties in your webroot/WEB-INF directory.lang and CNTY should be replaced with the right language and country name. Such as i3-label_ en_US.properties, i3-label_zh_CN.properties and i3-label_ja.properties. When a Localedependent label is about to retrieved, the matched i3-label_ang_CNTY.properties will be loaded. And the i3-label.properties file will be loaded when there are no matched locale file.
Here, we create two files in webroot/WEB-INF directory, i3-label_en_US.properties for English in USA:
i3-label_en_US.properties:
# en_US
app.username=username:
app.password=password:
app.login=login
and i3-label_zh_CN.properties for Chinese in China:
i3-label_zh_CN.properties:
# zh_CN
app.username=用户名:
app.password= 密码:
app.login=登录
Secondly, we shall read those strings with org.zkoss.util.resource.Labels. We need to modify
index.zul into:
index.zul
<?xml version="1.0" encoding="UTF-8"?>
<?page title="I18N Login Demo"?>
<div align="center">
<window border="none" width="40%">
<separator spacing="50px"/>
<label id="errLabel" style="color: red"/>
<grid>
<rows>
<zscript>
String username = org.zkoss.util.resource.Labels.getLabel("app.username");
String password = org.zkoss.util.resource.Labels.getLabel("app.password");
String login = org.zkoss.util.resource.Labels.getLabel("app.login");
</zscript>
<row>
<label value=""/>
<textbox id="namebox" constraint="no empty"/>
</row>
<row>
<label value=""/>
<textbox id="passwordbox" type="password" constraint="no empty"/>
</row>
<row spans="2" align="center">
<button label="" onClick="onLogin()"/>
</row>
</rows>
</grid>
<zscript>
void onLogin(){
// add code here
}
</zscript>
</window>
</div>
So, when visiting index.zul with Firefox, you will get:

Change your Firefox's language to zh_CN, and reload the page. Now, you will get:

Using Taglib
Sometimes, you may want to use labels in EL expression. This requires three steps:
- Add
core.dsp.tld(distributed under the dist/WEB-INF directory) to webroot/WEB-INF/tld/web directory - Include TLD file in your ZUL page: <?taglib uri="http://www.zkoss.org/dsp/web/core"prefix="c"?>
- Use
to retrieve labels
Now, the index.zul changed to
index.zul
<?xml version="1.0" encoding="UTF-8"?>
<?taglib uri="http://www.zkoss.org/dsp/web/core" prefix="c"?>
<?page title="I18N Login Demo"?>
<div align="center">
<window border="none" width="40%">
<separator spacing="50px"/>
<label id="errLabel" style="color: red"/>
<grid>
<rows>
<row>
<label value=""/>
<textbox id="namebox" constraint="no empty"/>
</row>
<row>
<label value=""/>
<textbox id="passwordbox" type="password" constraint="no empty"/>
</row>
<row spans="2" align="center">
<button label="" onClick="onLogin()"/>
</row>
</rows>
</grid>
<zscript>
void onLogin(){
// add code here
}
</zscript>
</window>
</div>
Add Parameters to Label
Till now, the onLogin() method is still empty. So we are going to add code in it. As an example, we will
make login failed all the time, and set error message to errLabel. The error message may be something
like “Your username _username does not exist or password _password is not correct”. _username and
_password are depend on the user input. If we can add parameter to label string, that will be very good.
So I write a class edu.nju.i18n.Labels, which has method public static String getLabel(String
key, String[] parameters) . Please read more about it in the source code for this article.
Now, onLogin() method looks like:
<zscript>
import edu.nju.i18n.Labels;
void onLogin(){
String username = namebox.getValue();
String password = passwordbox.getValue();
errLabel.setValue(Labels.getLabel("app.errMsg",new String[]{username,password}));
}
</zscript>
After click login button, you will get:

You can also change your Firefox's language and see what you get.
Sample
Source Code: I18N.zip
Reference
- ZK Developer's Guide: Chapter 11
Minjie Zha is a bachelor's student in Software Institute specialising Software Engineering at Nanjing University, China. He did several projects with J2ME and J2EE. He is interested in new technologies and open source projects such as Tapestry, Spring, Lucene, Ruby, and also ZK.
