Wednesday, October 31, 2007

Please use translation in your Web Dynpro for Java projects

As seen more and more, developers fail to use text the proper way when developing Web Dynpro for Java (WD4J) projects. I’ve written this post to clarify where it’s OK to use literals and where it’s not, as it’s rather confusing for the new WD4J developer (and sometimes for the experienced as well). First things first. When creating Web Dynpro projects in NetWeaver Developer Studio (NWDS), you should always use a development component (DC). The reason for that I’ll describe in another post, however there is good reason for it. On the creation screen you are asked to specify which language you’ll be writing the application in. Please mind that you set this property correct as it dictates the language setup.
If you fail to set this setting correctly, chances are that your translation settings will not work properly.

When you have completed creating you project you can use the Message Pool located in within Web Dynpro component in the Web Dynpro Explorer. The Message Pool is a component wide pool of messages to use in your component, these texts will be translatable via the Web Dynpro Console, but more about that later.


To use the Message Pool, simply double click it and the editor will appear. The message editor gives access to the texts in the pool and of course to create new ones.


If you look at the message text you’ll see it ending with {0}, this is a placeholder, you can use the same placeholder several times and you can have several placeholders numbered from zero and up. You’ll provide the data for these placeholders as an java.lang.Object array, therefore the numbering. Translating the texts
So when is it OK to use literals in your translation?
I have only one answer: When you type in texts in the property pane.
When you type in texts in the property pane, these will be extracted and put into an XLF file. You can See the XLF files if you open the navigator view and expand src -> packages and whatever you source package is called.


As you can see there are two xlf files, one for the message pool and one for the start view.
To translate the texts in the xlf file, you start with simply copying the file to the same location and editing the name of the file so the ISO 639 language code is post-fixed the file name together with an underscore. If the file is called LanguageTestStartView.wdView.xlf for the default locale, then the xlf file for Danish would be LanguageTestStartView.wdView_da.xlf. Search for “Internationalization of Web Dynpro Projects” in the NWDS documentation for further details.
Using the texts pragmatically
So now you got texts, and you got them in several languages. Now it’s time to use them.
First we’ll need a minimal setup:
I’ve created a Web Dynpro development component. Created a application called LanuguageTestApp with a default view called LanguageTestStartView.
In the LanguageTestStartView i have declared a context attribute called searchText. I’ve also created a input field called SearchTextInputField which has it’s text property bound to the context attribute. Lastly I’ve created a button called searchButton with the label text set to “Search”. This is to emulate a search iView of the portal ment for the detailed navigation section.
I’ve also created an action for the button called onActionSearchClicked.

When you create a Web Dynpro component, the NWDS also create a interface called IMessage which has a public static final IWDMessage for each and every entry in your message pool. This makes it easier to fetch the messages when you need them. For this mini application we only need two messages. Open your message editor by double clicking the Message Pool icon in your Web Dynpro component in the Web Dynpro Explorer and fill in the following:


As you can see, there is a placeholder for something in the top text. What we want to insert here is of course the search text that the user has entered prior to performing the search. Insert the following code in the onActionSearchClicked:

//@@begin onActionSearchClicked(ServerEvent)

String searchText = wdContext.currentContextElement().getSearchText();
IWDMessageManager messageManager = wdComponentAPI.getMessageManager();

if ("".equals(searchText)) {
/*
* if we get to this, the user hassen't entered any text before clicking
* the Search button. This is an error, lets tell him:
*/

messageManager.raiseMessage(
IMessageLanguageTestApp.NO_SEARCH_TEXT_SUPPLIED,
null,
true);
return;
}

/*
* As we have no search, we'll just tell the user that we found nothing.
*/

messageManager.reportMessage(
IMessageLanguageTestApp.NO_ITEMS_FOUND,
new Object[] { searchText }, // this will populate the {0} placeholder
false);

//@@end

In the if section we’ll raise a message if the searchText is empty and in the latter section we report a message telling the user that we found nothing. Notice the difference between the raising a message and reporting it. You should use raiseMessage for errors and warnings. When you’re raising errors then the third parameter specifies weather or not navigation should be canceled as a result of this error. This third option is only valid for errors and is ignored for all other message types.