1 Reply Latest reply on Dec 4, 2006 6:29 PM by Pete Muir


    Jarkko Lietolahti Novice

      Hello hello,
      Seam has nice way of handling i18n by the usage of #{messages.key}, with nice support for param passing to messages (eg. #{stuff.name} in the value ).

      Now i'm trying to implement something that would allow us to construct grammatically correct messages regarding plurals. I just started to study this so the first question is: does Seam already has something that could be used to archieve this?

      Fast googling revealed not too many resources about the issue.
      1. http://java.sun.com/docs/books/tutorial/i18n/format/choiceFormat.html

      I came up with couple bad ideas how to tackle this.

      1. Use Server side JavaScript/something with logic constructs inside the properties files. Like

      found_num_targets=switch #{foundTargets.rowCount}: {
      case 0: return "No targets found"; // nothing
      case 1: return "Found 1 target"; // one
      default: return "Found #{foundTargets.rowCount} targets"; // multiple

      pros: Allows you to do almost anything
      cons: well... it's just stupid ( and likely hard to get it right)

      2. Use "smart" concatenation with the key plus some added logic somewhere.

      and then in properties file we have:
      found_num_targets_0=No targets found
      found_num_targets_1=Found 1 target
      found_num_targets_2=Found #{foundTargets.rowCount} targets

      etc,-10,-1,0 maps to 0; 1 maps to 1; 2,3,4,etc maps to 2
      pros: seems clean enough
      cons: requires multiple keys in property file, maybe hard on the parsing (with #{} in the key part}. Could #{messages.['found_num_targets_#{foundTargets.rowCount}']} work? If so, it's starting to look pretty ugly..

      Anyone dealt the "plural" issue any other ways?

        • 1. Re: Plurals
          Pete Muir Master

          At least in English there are so many irregular plurals (e.g. dog/dogs, sheep/sheep, pony/ponies) that I think you would need to specify the messages.

          I think you would hit problems parsing that last string. Perhaps its not quite what you are after but I would suggest just using (if you are using facelets) something like

           <h:outputText value="#{messages[my:pluraliser('found_targets', foundTargets.rowCount)}" />

          public static String pluraliser(String messageBase, Integer rowCount) {
           if (rowCount == null || rowCount.equals(0)) {
           then return messageBase + "_none";
           } else if (rowCount.equals(1) {
           return messageBase + "_one";
           } else {
           return messageBase + "many";

          N.B. You might have to play around with the exact signature of the facelets function - I'm not sure whether you can return the result of a function as the key of map (but if you can't you probably should be able to). If you can't you could wrap it in a facelets source file with an inital ui:param or just lookup the message from Messages.instance() in the facelets function.