It has been a busy year so far. Every year I start out thinking that I really need to relax because the previous year was too hectic, but every year it ends up being much more hectic. Anyway, I thought I’d post a JSF quick time that might shave some headache for people developing internationalised applications.
Most JSF developers are aware of the resource-bundle tag in faces-config. Using this tag you can specify a resource bundle that should be available to all your pages using a given variable. For example, the code below will make a variable, msgs, available in all your pages without having to use the loadBundle tag.
<faces-config version="1.2">
...
<application>
<resource-bundle>
<base-name>my.class.path.Messages</base-name>
<var>msgs</var>
</resource-bundle>
</application>
...
</faces-config>
So, say that Messages.properties contains the following:
HELLO_WHAT_IS_YOUR_NAME=Hello, what’s your name?
you can from any page reference this text by writing:
<h:outputText value=”#{mgs.HELLO_WHAT_IS_YOUR_NAME}” />
or
<h:outputText value=”#{mgs[‘HELLO_WHAT_IS_YOUR_NAME’]}” />
I prefer the former as my favourite IDE (NetBeans) support code completion for all the messages in a managed resource bundle.
So far so good. But what if you want to do something a bit more advanced, such as outputting “Hello Allan, welcome to my site. Your last visit was 7. February 2009 at 10:45”. You are not limited to static text in your resource bundle. You can provide placeholders for content that will be replaced at run-time. Let’s have a look at the Message.properties:
WELCOME_MESSAGE=Hello {0}, welcome to my site. Your last visit was {1,date,long} at {1,time,short}
You’ll notice that the message is parameterised using two parameters. The first parameter we are expecting a string containing the name of the user, the second parameter is a java.util.Date containing both the date and time when user last visited the site. Notice that I’ve reused the second paramenter ({1}), one time for the date and the other for the time. On your JSF page you would use the message as follows (imaging that you have a bean called welcome containing a property for getting the name of the user and last visit):
<h:outputFormat value=”#{msgs.WELCOME_MESSAGE}”>
<f:param value=”#{welcome.userName}” />
<f:param value=”#{welcome.lastVisit}” />
</h:outputFormat>
Pretty neat, eh?
What about the classical case of singular and plural messages? Imagine that you want to display the number of records in a table “There are 10 records in the table”. If the Message.properties contained:
RECORDS_IN_TABLE=There are {0} records in the table
You’d end up an embarrassing problem if there was only one record in the table:
“There are 1 records in the table” (This sentence is grammatical incorrect)
Instead you would want it to output:
“There is 1 record in the table”
To do this, you have to use the choice pattern:
RECORDS_IN_TABLE=There {0, choice, 0#are|1#is|2#are} {0} {0, choice, 0#records|1#record|2#records}
The format might look a bit awkward, but once you have understood the pattern it is simple:
{0,choice | means, taking the first parameter and base the output on a choice of formats |
0#are | if the first parameter contains 0 (or below), then it should print “are” |
|1#is | or, if the first parameter contain 1, then it should print “is” |
|2#are} | or, if the first parameter contains 2 (or above), then it should print “are” |
Now, that is nice! So let’s examine the output of these examples:
<h:outputFormat value=”#{msgs.RECORDS_IN_TABLE}”> <f:param value=”#{0}” /> </h:outputFormat>
| There are 0 records in the table |
<h:outputFormat value=”#{msgs.RECORDS_IN_TABLE}”> <f:param value=”#{1}” /> </h:outputFormat>
| There is 1 record in the table |
<h:outputFormat value=”#{msgs.RECORDS_IN_TABLE}”> <f:param value=”#{2}” /> </h:outputFormat>
| There are 2 records in the table |
<h:outputFormat value=”#{msgs.RECORDS_IN_TABLE}”> <f:param value=”#{10}” /> </h:outputFormat>
| There are 10 records in the table |
Enjoy!