Grails scaffolding: enums and i18n
Join the DZone community and get the full member experience.
Join For Freegrails scaffolding feature is a great asset for quickly generating create/read/update/delete (crud) screens for your domain classes. create an entity, create a controller and put static scaffold on top. for various types of properties within your domain class a suitable (html) input is used, to take the user's input: booleans become checkboxes, associations with other domain classes become (depending on ownership and constraints) e.g. dropdowns or multi-selects, etc.
even an enum works out of the box as one could imagine :-) this post serves as a small quicktip - primarily for me and other developers looking for these kind of things - of internationalizing scaffolded screens in general and enums in particular using tostring() and spring's messagesourceresolvable .
take the following product with a status :
class product { enum status { available, sold_out } string name status status static constraints = { name blank: false, unique: true } } class productcontroller { def scaffold = true }
opening up our /product/create url will show what you would expect.
a great thing of the scaffolding is that
internationalizing
the elements on the screen is a breeze! default translations for
home
and
create
have already been provided for a dozen or so languages in the
i18n
folder. the name of the entity itself ("product") and its properties can be defined by following a convention:
[entity name].label
and
[entity name].[property name].label
- see your grails installation
/src/grails/templates/scaffolding
folder.
take a look at how we would translate a few things into dutch, by adding a few keys to messages_nl.properties :
product.label=product product.name.label=naam product.status.label=status
if we want to test for a certain language (without changing your - browser - environment) or you just want to fix the application to a certain locale, we can override the default locale with spring globally. let's do that for dutch for the following examples.
beans = { localeresolver(org.springframework.web.servlet.i18n.fixedlocaleresolver) { defaultlocale = new locale("nl", "nl") } }
reviewing our screen again shows us the correct dutch translations, for the default ui elements as for our own properties.
so far so good, but wouldn't we like to have translated values for our enum values available and sold_out too? there are a few approaches we can take, of which i will describe tostring() and using spring's messagesourceresolvable .
#1. tostring()
as you know, the scaffolded screens just output values in selects and dropdowns through the tostring() method of the shown object. we can construct each enum with a hardcoded translation and have tostring() return that value.
class product { enum status { available("beschikbaar"), sold_out("uitverkocht") final string value status(string value) { this.value = value } string tostring() { value } } string name status status static constraints = { name blank: false, unique: true } }
and presto!
the actual names of the enum now only appear in the generated html:
<select name="status" required="" id="status" > <option value="available" >beschikbaar</option> <option value="sold_out" >uitverkocht</option> </select>
#2. messagesourceresolvable
by now you'll probably understand above hardcoded solution works for just one language, one hardcoded in the enum itself - which will cause problems when in a month from now your application actually needs to support a 2nd language :-) so how do we leverage the fact that we have already have message_xx.properties where we've put our other message keys?
use the underlying spring framework. have our enum implement org.springframework.context.messagesourceresolvable e.g. like this:
enum status implements org.springframework.context.messagesourceresolvable { available, sold_out public object[] getarguments() { [] as object[] } public string[] getcodes() { [ name() ] } public string getdefaultmessage() { "?-" + name() } }
just like validation errors - spring's fielderror and objecterror which implement aformentioned interface - we can provide our own codes to lookup a particular message key.
reviewing our screen you'll notice that since we haven't provided a translation yet, the value from getdefaultmessage() is taken. i just added a "?-" in front of it to make this more noticeable, but you can do whatever you like there e.g. just return name() maybe.
now we can provide a value in our messages_nl.properties for each enum we have:
product.label=product product.name.label=naam product.status.label=status <b>available=beschikbaar sold_out=uitverkocht</b>
and we have the same effect of our earlier hardcoded version, but now we've done i18n the proper way!
original article: http://tedvinke.wordpress.com/2012/08/22/grails-scaffolding-enums-and-i18n
Opinions expressed by DZone contributors are their own.
Trending
-
Cypress Tutorial: A Comprehensive Guide With Examples and Best Practices
-
Mastering Time Series Analysis: Techniques, Models, and Strategies
-
What Is Istio Service Mesh?
-
Why You Should Consider Using React Router V6: An Overview of Changes
Comments