Reputation:
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
Reputation: 1
Look what Groovy can do for you, using a little bit of meta-programming.
greetings = Hello {0}.
inquiry = {0}: How are you {1}?
farewell = Goodbye.
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")
Hello Serge.
Serge: How are you Mary?
Goodbye.
Upvotes: 0
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