user122299
user122299

Reputation:

What function is meant to format/substitute {0} {1} parameters in an string in Grails/Groovy?

I'm just getting started with Groovy/Grails

I noticed the error messages you get when you validate a form look like this:

Property [{0}] of class [{1}] cannot be blank

For example this code to dump the errors to the console

        s.errors.allErrors.each
        {
            println it.defaultMessage
        }

Now, it.arguments contains the arguments that need to be filled in here.

The problem is, I can't find any method in the Grails or Groovy documentation that formats strings based on positional parameters like {0}, {1} and substitutes values from an array

I need something like python's %

What is the proper way to format these error strings so the parameters get substituted properly?

Upvotes: 7

Views: 7377

Answers (2)

Serge Rehem
Serge Rehem

Reputation: 1

Look what Groovy can do for you, using a little bit of meta-programming.

MessagesBundle_en_US.properties:

   greetings = Hello {0}.
   inquiry = {0}: How are you {1}? 
   farewell = Goodbye.

ResourceBundleWithSugar.groovy:

    import java.text.MessageFormat
    class ResourceBundleUtils {
      def propertyMissing(String name) { this.getString(name) }
      def methodMissing(String name, args) {
        MessageFormat.format(this.getString(name), args)
      }
    }
    ResourceBundle.metaClass.mixin ResourceBundleUtils

    def msg = ResourceBundle.getBundle("MessagesBundle", new Locale("en","US"));
    println msg.greetings("Serge")
    println msg.inquiry("Serge","Mary")
    println msg.farewell // You can use also: msg.['farewell'] msg."farewell" or msg.getString("farewell")

Output:

    Hello Serge.
    Serge: How are you Mary?
    Goodbye.

Upvotes: 0

Dirk
Dirk

Reputation: 31061

These markers are actually replaced using the standard java.text.MessageFormat APIs. If you display the messages using Grail's g:message tag, it will fill in the gaps if you pass a suitable args="..." attribute:

<g:message code="mymessagecode" args="${['size', 'org.example.Something']}"/>

Under certain circumstances (within GSP pages and from controllers IIRC) you cann call the tag like a function:

g.message(code:'mymessagecode',args: ['size', 'org.example.Something'])

Note, that the value to supply as message code is only a symbolic string constant. The actual translation (the message text with the "gaps" in it) will be read by the framework using Spring's reloadable resource bundles.

If all you actually have is a translation text, you can call the message formatting APIs directly. See for example:

import java.text.MessageFormat

...

args = ["english"].toArray()
println(MessageFormat.format("Translation into {0}", args))

// Or - as the method is variadic:
println(MessageFormat.format("Translation into {0}", "english"))

Upvotes: 8

Related Questions