Forum User
Forum User

Reputation: 111

MultiLingual Email template with grails

I am trying to send emails from grails and the mail template should be multilingual.

I found that we can render GSP as a string or even in the grails mail plugin we can render the GSP.

In the GSP now I read the static messages from messages.properties assuming that I would define for each languages and my emails would go multi lingual.

Now here is the problem that I am facing

In the template the language is always set to en_US. I am using the below API to get the string of the template. I am not using mail plugin directly as I need to store the send message as string into the database as well

    def contents = groovyPageRenderer.render(template:"/layouts/emailparse", model:[mailObj: mailObj])

I also read on other post on forum about setting the language using lang parameter but still the language is set to en_US only.

Would the above method call support specifying language? Is there an option to use velocity template to do this kind of multilingual mails?

Upvotes: 2

Views: 914

Answers (2)

Ian Roberts
Ian Roberts

Reputation: 122414

If you're sending the mail from within a request handling thread (e.g. from a controller action) then it should pick up the right locale from the request automatically. If you're sending from a background thread then it won't know what locale to use because there's no "current request" context.

If you have another way to know the correct language to use (e.g. if you store each user's preferred language in the database) then you could reset the LocaleContextHolder

def savedContext = LocaleContextHolder.getLocaleContext()
LocaleContextHolder.setLocale(correctLocaleForThisUser)
try {
  def contents = groovyPageRenderer.render(template:"/layouts/emailparse", model:[mailObj: mailObj])
  // etc. etc.
} finally {
  LocaleContextHolder.setLocaleContext(savedContext)
}

Exactly how you determine the correctLocaleForThisUser depends on your application. You could store each user's preferred language as a property of the User domain object in the database, or if you're using something like the executor plugin's runAsync from a controller action then you could save the request locale while you have access to it and then re-use that in the async task:

// SomeController.groovy
def sendEmail() {
  // get locale from the thread-local request and save it in a local variable
  // that the runAsync closure can see
  Locale localeFromRequest = LocaleContextHolder.getLocale()
  runAsync {
    def savedContext = LocaleContextHolder.getLocaleContext()
    // inject the locale extracted from the request
    LocaleContextHolder.setLocale(localeFromRequest)
    try {
      def contents = groovyPageRenderer.render(template:"/layouts/emailparse", model:[mailObj: mailObj])
      // etc. etc.
    } finally {
      LocaleContextHolder.setLocaleContext(savedContext)
    }        
  }
}

Upvotes: 1

Can you work around this by creating a model containing a list with the correct translations?

For example:

def messages = [:]
messages['hello.world'] = messageSource.getMessage(
        "hello.world",
        null,
        new Locale("nb")
)
def template = groovyPageRenderer.render(
        template: '/mail/email',
        model:[messages:messages]
)

And then in the view you just write:

<html>
    <head>
       <title>${messages['hello.world']}</title>
    </head>
    <body>
    </body>
</html>

Upvotes: 0

Related Questions