Friday, November 11, 2016

ADF: Token replacement for resource bundle af:formatNamed

Problem Description: There is a common usecase to have a translatable string in resource bundle with tokens. In this blog I want to show how to use such strings using af:formatNamed apis

Let say we have a string in bundle as

WELCOME_MESSAGE=Hello {USER_NAME}. Welcome to Benefits Application.

We want to replace username token at run-time.

Solution: You can simply use af:formatNamed apis to do so

<af:outputText value="#{af:formatNamed(viewcontrollerBundle.WELCOME_MESSAGE,'USER_NAME','Sanjeev')}" id="ot1"/>

In above you make 'Sanjeev' to an expression like securityContext.userName to show actual username.
<af:outputText value="#{af:formatNamed(viewcontrollerBundle.WELCOME_MESSAGE,'USER_NAME',securityContext.userName)}" id="ot1"/>

If you have two tokens you can use af:formatNamed2, It can replace two tokens

<af:outputText value="#{af:formatNamed2(viewcontrollerBundle.WELCOME_MESSAGE,'USER_NAME','Sanjeev', APPLICATION_NAME, 'Benefits Application')}" id="ot1"/>

Similarly for 3 tokens, use af:formatNamed3 and 4 tokens use af:formatNamed4 apis

Token name in bundle must be surrounded by curly braces as {USER_NAME}

What if I don't use token but simply break strings in multiple parts. For example instead of
WELCOME_MESSAGE=Hello {USER_NAME}. Welcome to Benefits Application.
I create a bundle as
WELCOME_MESSAGE_PART2=Welcome to Benefits Application.

Now in expression I write it like
<af:outputText value="#{viewcontrollerBundle.WELCOME_MESSAGE_PART1} Sanjeev. #{viewcontrollerBundle.WELCOME_MESSAGE_PART2}"

If you run application you may not find any difference but I suggest NOT to do that. This approach has some hidden problems

a. Your translator will not be able to understand whole message. Breaking message in parts can be very difficult to translate and may end up having a completely different meaning.
b. Also I have my doubts that it may not work properly with RTL language. Need to verify this point.