Monday Jun 09, 2008

I18n Best practices for web application- Part 1

I have created clear and concise best practices list for making your application I18n'ed.

General

  • No hardcoded strings
  • Data format I18n
  • Number format I18n
  • Usage of  Apostrophe in Message Format class. 
  • Currency I18n
  • Sort I18n
  • Calendar I18n
  • Read/write file in UTF-8
    • Use methods like :public OutputStreamWriter(OutputStream out, String charsetName); public InputStreamReader(InputStream in, String charsetName)
  • Locale lookup should be correct - Find out what lookup mechanism needs to be used.
  • Send/Receive Locale when communicating with other compoments
  • If any property in property file does not need to be locaized put a comment on top property file.
  • Make sure property file does not have duplicate properties
  • When you use Message format to parse string make sure "'"(aphostrophy) in string is escaped.
  • File system name should be allowed to i18n

JSP Prgoram

  • Encoding of file should be "UTF-8"
    • <%@ page contentType="mimeType ;charset=characterSet ?" | "text/html; charset=UTF-8" %>
  • Use JSTL taglib to include the messages in the JSP file.
  • Request and Response should be in "UTF-8"

Resource Bundle

  • Should not use duplicate key properties file
  • Try to create less number of Property files
  • Try to use same message which already found in other components or even products if it make sense.
  • Do not change layout of message once translated
  • Property file for UI message and Log message should be SEPARATE
  • Message should not be slang or culturally sensitive
  • Always create _en.properties file along with base property file

GUI

  • Each button/textfield should have enough space to accommodate localized sentences
  • Layout and Text rendering
  • Input validation should consider multibyte data

Logging

  • If you are writing a WEB UI, the UI should appear in the client locale, not the server locale. Logging should be done in the server locale to avoid log messages with mixed data from different locales. Use UTF-8 as encoding for the web UI, because UTF-8 supports all languages.

Database

  • Reading and writing data to/from database should be in UTF-8

JUnit Testcase

  • Make sure all your Junit Testcase is I18n'ed. This will help in great way to integrate i18n testing in Unit testing.

AJAX

Refer AJAX I18n

References

Tuesday Sep 18, 2007

AJAX Internationalization (I18n) in Portal Server

In latest release of Portal Server AJAX capability has been introduced in the form of AJAX containers.

First ,  What is  AJAX containers in Portal Server?

The AJAXTableContainerProvider integrates Asynchronous JavaScript and XML (AJAX) capabilities at the portal framework level. The container provides asynchronous loading of individual channels and portlets. Therefore, a slow channel or portlet will not affect the loading time of the other channels and portlets on a page, improving overall performance. The AJAXTableContainerProvider includes AJAX based interaction for all container controls and features which provides for a much richer and faster user experience.

Let move to core item of this blog,  AJAX I18n.

Some clerification before we procedd.
- Sources(js , jsp , java) are referred from OpenPortal repository.
Location of ajaxcontainers in portal source code:
.../openportal/portal/samples/ajaxcontainers

Thare are two containers provided in Portal Server
1) AJAXEditContainer
2) AJAXTableCotainerProvider

For example I will use "AJAXTableCotainerProvider".

AJAXTableCotainerProvider:

In this AJAX container thare two primary source for I18n

1)Java Server Pages(JSP) Internationalization(I18n)
Location in OpenPortal repository:
.../openportal/portal/samples/ajaxcontainers/src/channels/AJAXTableContainerProvider

How these JSPs are I18n'ed?
JSP I18n is quite straight forward , lets understand it by example of one of the jsp from source i.e. table.jsp

Steps for JSP i18n: 

1.1) Defining I18n tag library:
<%@ taglib uri="/tld/i18n.tld" prefix="i18n"%>
This tag libarary contains various tags required to perform I18n functions.

1.2) Loading the resource bundle:
<i18n:setBundle baseName="ajaxcontainers" var="ajaxcontainersRB"/>
This tag will load resource bundle "ajaxcontainers"  based on user locale.
Have a look at base resource bundle ajaxcontainers.properties

1.3) Fetching value from resource bundle
<i18n:message key="loading.page" bundle="ajaxcontainersRB"/>
"message" tag will fetch value from resource bundles for specified key.

2)Java Scripts(JS) Internationalization(I18n)

You have reached to most interesting part of this blog i.e Java Script I18n.
The fact that java script does not have any defined framework for I18n makes it very interesting and scope of innovation. In this blog I will explain one of the innovative and well proven approach used for I18n of java script in AJAX container.

Location of Java Scripts in Source :
.../openportal/portal/samples/ajaxcontainers/src/web-src/js

Following steps are require for JS I18n.
2.1) Method to fetch all the properties from resource bundle in table.jsp.
public JSONObject getLocalizedStrings(java.util.ResourceBundle rb)
      throws JSONException {
JSONObject localizedStrings = new JSONObject();
      if (rb == null) {
                      localizedStrings.put("x", "y");
      }
      if (rb != null) {
              for (Enumeration e = rb.getKeys() ; e.hasMoreElements()  ;)   {
                      String key = (String)e.nextElement();
                      String val = rb.getString(key);
                      localizedStrings.put(key, val);
              }
      }
      return localizedStrings;
}

2.2)  Creating  "tableContainerProviderModel" JSON <http://www.json.org/> object in table.jsp.
JSONObject tableContainerProviderModel = new JSONObject();
This JSON object will be used to hold localized values in terms of property along with other properties

2.4) Next step would be to add localized value to this JSON object using method to fetch localized value from resource bundle.
tableContainerProviderModel.put("localizedStrings", getLocalizedStrings(ajaxcontainersRB));

2.5) Now we need variable which can be used in Java Script. Creating "containerModel" variable in table.jsp and assigning "tableContainerProviderModle" JSON Object to it.

<script type="text/javascript">
      var containerModel = <%=tableContainerProviderModel.toString(4)%>
      var pageStyles = new sunportal.AJAXPageStyles('<dtpc:getStaticContentPath/>');
      pageStyles.init();
</script>

2.6) Loading of java script in table.jsp using <script> tag
<script type="text/javascript" src="<dt:scontent/>/desktop/ajaxcontainers/js/sunportal/AJAXUtils.js"></script>

We done with our intial setup i.e these steps will be performed intially when user makes request to server.  All the further interaction will be through Java Scripts and localized string will be fetched from JSON object.

How lets see?

2.7)  JS Function below used by all JS to fetch localized value : sunportal.getLocalizedString
This  function is defined in AJAXUtils.js as below:

sunportal.getLocalizedString=function(){
var _1=arguments[0];
var _2=containerModel.localizedStrings[_1];
for(var i=1;i<arguments.length;i++){
var j=i-1;
var re=new RegExp("\\\\{"+j+"\\\\}","g");
_2=_2.replace(re,arguments[i]);
}
return _2;
};
As you can see this function takes "key" as argument and fetch loalized value from containerModel.localizedStrings Map which we have poplulated in step 2.2.

2.8) Let see how this functions is used in Java Scripts at Client side.
eg. AJAXChangeLayout.js
td.innerHTML=sunportal.getLocalizedString("full.top.portlets");
This function used by all the Java Scripts to fetch localized values without  accessing resource bundles stored at Server side.

I hope , I am able explain it correctly ... Any questions/comments are welcome ...:-).

About

Mahipalsinh Rana

Search

Categories
Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today