Give us a call +386 1 542 06 00

Razum

Get a proposal

Blog

There is no clean way to get i18n messages defined in Grails' .properties files from Javascript. The always brilliant Mr. Haki posted a solution in 2011 using the JAWR plugin but it no longer works cleanly for Grails versions 2.4 and newer. Besides, installing the whole JAWR plugin just for this purpose seems to be an overkill. Therefore I’ve cooked up a solution using Groovy traits.

Exporting Grails' i18n messages into Javascript by Gregor

There is no clean way to get i18n messages defined in Grails' .properties files from Javascript. The always brilliant Mr. Haki posted a solution in 2011 using the JAWR plugin but it no longer works cleanly for Grails versions 2.4 and newer. Besides, installing the whole JAWR plugin just for this purpose seems to be an overkill. Therefore I’ve cooked up a solution using Groovy traits.

The whole problem could be solved by accessing the protected getMergedProperties and getMergedPluginProperties of the messageSource bean. Subclassing and overriding it in resources.groovy could work but we would have to define all the bean properties correctly and those could change in later Grails versions. So I decided to use a Groovy trait:

/**
       * This trait allows us to extract message codes from the I18n system.
       * Usage: ctx.getBean('messageSource').withTraits(MessagePropertiesTrait).messageKeys(locale)
       * (the locale can be obtained using org.springframework.web.servlet.support.RequestContextUtils.getLocale(request))
       */
      @GrailsCompileStatic(TypeCheckingMode.SKIP)
      trait MessagePropertiesTrait {
          Properties getMessageKeys(Locale locale) {
              this.getMergedProperties(locale).properties
          }
      
          Properties getPluginMessageKeys(Locale locale) {
              this.getMergedPluginProperties(locale).properties
          }
      }
      

 

Then I create a TranslationsController and use the following code to render the translations I need in my frontend code:

import org.springframework.web.servlet.support.RequestContextUtils as RCU
      import grails.converters.JSON
      
      class TranslationsController {
          def messageSource
          static defaultAction = "index"
      
          def index() {
              def keys = messageSource.withTraits(MessagePropertiesTrait).getMessageKeys(RCU.getLocale(request))
              def jsKeys = keys.findAll { code, value -> code.startsWith('js.') }
              render jsKeys as JSON
          }
      }
      

 

The code above renders all i18n strings whose code starts with js. but it would be trivial to implement a different rule. On the client, an AngularJS service requests these strings and provides them to a directive that works similarly to g:message.

I still haven’t decided where to go with this code: cache the results for a given time, calculate ETags or perhaps even write a plugin for the Asset Pipeline plugin. But digging in the Grails internals part is done.

< Back to article list