1. Introduction

This plugin adds an annotation on Enums to easy add and implement the MessageSourceResolvable interface. It was heavily inspired by this blog-entry by Rob Fletcher

1.1. If you use it, let me know

If you use this plugin in your application, let me know - it’s always nice to know, when ones work is used in the wild. Send me a tweet @sbglasius or an email soeren@glasius.dk - thank you!

1.2. Documentation for pre 2.x version of this plugin

This documentation also applies for the latest v1.0.8 of the plugin (for Grails 2.x), except for using the I18nEnumTrait.

1.3. License

Licensed under the Apache2.0 license. See http://www.apache.org/licenses/LICENSE-2.0 for more information.

2. Installation

In your build.gradle insert into your dependencies:

2.1. Grails 3.x

compile 'org.grails.plugins:i18n-enums:2.0.2'

2.2. Grails 4.x

There is no released version for Grails 4.x, try with the Grails 3.x version

2.3. Grails 5.x

implementation 'dk.glasius:i18n-enums:5.0.0'

2.4. Grails 6.x

implementation 'dk.glasius:i18n-enums:${RELEASE_VERSION}'

3. Basic usage

There are two ways to use the I18n Enum plugin:

You can either implement the trait I18nEnumTrait on your enumeration like this (Only Grails 3.x):

package test
import grails.plugins.i18nEnums.traits.I18nEnumTrait

enum MyEnum implements I18nEnumTrait {
    ONE, Two, three
}

or you can annotate your enumeration with @I18nEnum (also works for Grails 2.x)

package test
import grails.plugins.i18nEnums.annotations.I18nEnum

@I18nEnum
enum MyEnum {
    ONE, Two, three
}

will generate the following codes for each enum:

test.MyEnum.ONE.codes   == ['test.MyEnum.ONE',   'test.MyEnum.ONE',   'test.MyEnum.one']
test.MyEnum.Two.codes   == ['test.MyEnum.TWO',   'test.MyEnum.Two',   'test.MyEnum.two']
test.MyEnum.three.codes == ['test.MyEnum.THREE', 'test.MyEnum.three', 'test.MyEnum.three']

And the following default values:

test.MyEnum.ONE.defaultMessage == 'ONE'
test.MyEnum.Two.defaultMessage == 'Two'
test.MyEnum.three.defaultMessage == 'three'

as it can be seen, the codes comes in three variations: UPPER_CASE, UNCHANGED and LOWER_CASE, and the default message is simply the Enum value.

If you use the Trait behaviour of the MessageSourceResolvable implementation can only be done from the config file (see the Configuration section below). If you use the annotation, it is possible to use fine grained configuration for each annotation (See the Advanced usage section below)

4. Advanced usage

To get even more control over, how the codes and the default value are generated, you can add parameters to the annotation:

@I18nEnum(prefix = '', postfix = '', shortName = false, defaultNameCase = DefaultNameCase.UNCHANGED)

The above are the default values.

4.1. Prefix and Postfix

Prefix controls what is added before the package name. If you do not add a dot after the prefix, one will be added for you.

Postfix controls what is added after the ENUM_VALUE. If you do not add a dot before the postfix, one will be added for you.

4.1.1. Example:

package test
import grails.plugins.i18nEnums.annotations.I18nEnum

@I18nEnum(prefix = 'enum', postfix = 'label')
enum MyEnum {
    ONE, Two, three
}

will generate the following codes for each enum:

test.MyEnum.ONE.codes ==   ['enum.test.MyEnum.ONE.label',   'enum.test.MyEnum.ONE.label',   'enum.test.MyEnum.one.label']
test.MyEnum.Two.codes ==   ['enum.test.MyEnum.TWO.label',   'enum.test.MyEnum.Two.label',   'enum.test.MyEnum.two.label']
test.MyEnum.three.codes == ['enum.test.MyEnum.THREE.label', 'enum.test.MyEnum.three.label', 'enum.test.MyEnum.three.label']

4.2. shortName

If you do not want the package name in the generated codes, just add shortName = true to your annotation parameters

4.2.1. Example:

package test
import grails.plugins.i18nEnums.annotations.I18nEnum

@I18nEnum(shortName = true)
enum MyEnum {
    ONE, Two, three
}

will generate the following codes for each enum:

test.MyEnum.ONE.codes ==   ['MyEnum.ONE',   'MyEnum.ONE',   'MyEnum.one']
test.MyEnum.Two.codes ==   ['MyEnum.TWO',   'MyEnum.Two',   'MyEnum.two']
test.MyEnum.three.codes == ['MyEnum.THREE', 'MyEnum.three', 'MyEnum.three']

4.3. defaultNameCase

To control the defaultMessage you can use defaultNameCase. It can be set to one of the following values:

UPPER_CASE, LOWER_CASE, CAPITALIZE, ALL_CAPS, UNCHANGED

where UNCHANGED is the default.

4.3.1. Example:

DefaultNameCase.CAPITALIZE:

package test
import grails.plugins.i18nEnums.annotations.I18nEnum
import grails.plugins.i18nEnums.DefaultNameCase

@I18nEnum(defaultNameCase = DefaultNameCase.CAPITALIZE)
enum MyEnum {
    ONE, Two, three
}

And the following default values:

test.MyEnum.ONE.defaultMessage == 'One'
test.MyEnum.Two.defaultMessage == 'Two'
test.MyEnum.three.defaultMessage == 'Three'

DefaultNameCase.ALL_CAPS:

package test
import grails.plugins.i18nEnums.annotations.I18nEnum
import grails.plugins.i18nEnums.DefaultNameCase

@I18nEnum(defaultNameCase = DefaultNameCase.ALL_CAPS)
enum MyEnum {
    ONE, Two, three, Four_five
}

And the following default values:

test.MyEnum.ONE.defaultMessage == 'One'
test.MyEnum.Two.defaultMessage == 'Two'
test.MyEnum.three.defaultMessage == 'Three'
test.MyEnum.Four_five.defaultMessage == 'Four Five'

DefaultNameCase.LOWER_CASE:

package test
import grails.plugins.i18nEnums.annotations.I18nEnum
import grails.plugins.i18nEnums.DefaultNameCase

@I18nEnum(defaultNameCase = DefaultNameCase.LOWER_CASE)
enum MyEnum {
    ONE, Two, three
}

And the following default values:

test.MyEnum.ONE.defaultMessage == 'one'
test.MyEnum.Two.defaultMessage == 'two'
test.MyEnum.three.defaultMessage == 'three'

5. Configuration

It is possible to configure default settings from configuration. This is the only way to control the code generation if you choose to use the I18nEnumTrait.

In application.groovy create a configuration tree like this:

import grails.plugin.i18nEnum.transformation.DefaultNameCase

// Your other configuration

grails {
    plugin {
        i18nEnum {
            postfix = "label"
            shortName = true
            defaultNameCase = DefaultNameCase.ALL_CAPS
        }
    }
}

If you prefer application.yml the configuration will be like this:

grails:
    plugin:
        i18nEnum:
            postfix: label
            shortName: true
            defaultNameCase: ALL_CAPS

The settings values are the same as the configuration directives for the annotation.

6. Change Log

6.1. Changes

6.1.1. v5.0.0

This plugin is now rewritten for Grails 5.x and is not backwards compatible.

  • Migrate group name from org.grails.plugins to dk.glasius

  • Remove deprecated usages of ConfigObject

  • Migrate to Maven Central from grails artifactory instance

Migration to Grails 5 by James Daugherty. Thank you for your contribution.

6.1.2. v2.0.2

No functionality changes

  • More cleanup and automatic build on Travis-CI.

  • Migrated documentation to AsciiDoctor

6.1.3. v2.0.1

Code cleanup by Burt Beckwith. Thank you for your contribution.

6.1.4. v2.0.0

The plugin is now rewritten for Grails 3.x and is not backwards compatible.

  • Still supports annotations, where configuration can be done on every annotation or in config

  • Now also supports implementing the I18nEnumTrait on your own enumerations.

  • Documentation mentions what sections that only works for Grails 3.x

6.1.5. v1.0.8

Cleanup. No functionality changes.

6.1.6. v1.0.7

  • Files to be pre-compiled moved from groovy-ast to groovy, that way Intellij Idea can find them when parsing the project for completions.

  • Test project (test/project/I18nEnumTest) now has more tests incl. GEB

6.1.7. v1.0.5, v1.0.6

Updating plugin descriptor, documentation and build dependencies

6.1.8. v1.0.4

Documentation now on GitHub pages instead of grails.org

6.1.9. v1.0.3

Plugin now runs under Grails 2.4.x It is no longer a binary plugin. It should compile before all other classes.

6.1.10. v1.0.2

The plugin is now released as a binary plugin due to AST transformations not being applied to inlined plugins.

6.1.11. v1.0.1

Grails event hook to precompile AST transformations before the rest of the Grails compile phase. This is needed so that enums annotated will be compiled correctly.

6.1.12. v1.0.0

The plugin was formerly known as EnumMessageSourceResolvable, but was renamed to I18nEnums for easier reading and writing. Functionality wise it has not changed from v1.0.0 of EnumMessageSourceResolvable.

Now support configuration in Config.groovy - see documentation below

6.1.13. Previous versions

For previous versions see [EnumMessageSourceResolvable|http://grails.org/plugin/enum-message-source-resolvable]