Showing posts with label i18n. Show all posts
Showing posts with label i18n. Show all posts

Saturday, February 15, 2014

Accessing i18n Messages from exception (validation errors) in Grails in a Service

To access your message, inject the MessageSource into your service:
def messageSource  

And to get the error messages from exception based on your i18n properties file, use the following code block in your service:
 
def messageSource;

def printAllMessage(Exception ex) {
    ex.errors.allErrors.eachWithIndex { ObjectError objectError, Integer index ->
        println "Error #${index}: " + messageSource.getMessage(objectError, Locale.default);
    }
}


Will output something like this based on you i18n messages.properties file:

Error #0: Property [accountId] cannot be null
Error #1: Property [displayName] cannot be null
Error #2: Property [emailAddress] with value [pritom@bitmascot.com] must be unique

If your i18n file contains something like:

default.null.message=Property [{0}] cannot be null
default.not.unique.message=Property [{0}] with value [{2}] must be unique

Wednesday, December 11, 2013

Change i18n locale from a controller before calling the view


package pritom.com.locale;

import org.springframework.web.servlet.support.RequestContextUtils as RCU

class FormController {
    def test() {
        Locale locale = new Locale("fr");
        RCU.getLocaleResolver(request).setLocale(request, response, locale);
        render g.message(code: "default.paginate.prev");
    }
}

Monday, December 9, 2013

Reading i18n messages from the database with Grails

At first create a model class:


package com.locale.messaging

class Message {
    String code
    Locale locale
    String text

    static constraints = {
        code(unique: ["locale"])
    }

    static mapping = {
        version(false);
    }
}

Then implement a class that extends the org.springframework.context.support.AbstractMessageSource class. In the example below I am using simple GORM finders to lookup a message using the code and locale


package com.locale.messaging

import com.locale.messaging.Message
import net.sf.ehcache.Ehcache
import org.springframework.context.support.AbstractMessageSource
import net.sf.ehcache.Element;
import java.text.MessageFormat

/**
 * Created with IntelliJ IDEA.
 * User: pritom
 * Date: 9/12/13
 * Time: 9:09 AM
 * To change this template use File | Settings | File Templates.
 */
class DatabaseMessageSource extends AbstractMessageSource {
    Ehcache messageCache
    def messageBundleMessageSource

    @Override
    protected MessageFormat resolveCode(String code, Locale locale) {
        def key = "${code}_${locale.language}_${locale.country}_${locale.variant}";
        def format = messageCache.get(key)?.value;
        if (!format) {
            Message message = Message.findByCodeAndLocale(code, locale);
            if (message) {
                format = new MessageFormat(message.text, message.locale);
            } else {
                format = messageBundleMessageSource.resolveCode(code, locale);
            }
            messageCache.put(new Element(key, format))
        } else {
            format = (MessageFormat) format;
        }
        return format;
    }
}

Then configure an appropriate cache bean (I'm using Ehcache) in Spring and wire it into your MessageSource in grails-app/conf/spring/resources.groovy file:

import com.bitmascot.util.DatabaseMessageSource
import org.springframework.cache.ehcache.EhCacheFactoryBean

// Place your Spring DSL code here
beans = {
    messageCache(EhCacheFactoryBean) {
        eternal = false;
        timeToIdle = 5000;
    }
    messageSource(DatabaseMessageSource) {
        messageCache = messageCache
        messageBundleMessageSource = ref("messageBundleMessageSource")
    }

    messageBundleMessageSource(org.codehaus.groovy.grails.context.support.PluginAwareResourceBundleMessageSource) {
        basenames = "grails-app/i18n/messages"
    }
}

http://graemerocher.blogspot.com/2010/04/reading-i18n-messages-from-database.html