Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
445 views
in Technique[技术] by (71.8m points)

internationalization - Grails i18n From Database but Default Back To File

Following this blog article I enabled my application to load i18n messages from the database. It works great. However, I don't want to manage all messages in the database. So I'd like to be able to say if I don't find the code in the database, then load it using the default mechanism.

Here is what I have:

class DatabaseMessageSource extends AbstractMessageSource {
  protected MessageFormat resolveCode(String code, Locale locale) {
    Message msg = Message.findByCodeAndLocale(code, locale)
    def format = null
    if (msg) {
      format = new MessageFormat(msg.text, msg.locale)
    }else{
      // What do I do here to grab it from the file
    }
    return format;
  }
}

I tried calling super.resolveCode(code, locale) but that resulted in compile errors. And I'm having a hard time tracking down the implementation of AbstractMessageSource that Grails is using by default to look at the source.

UPDATE: Thanks to doelleri I now realize what I need to do is something like extending the ResourceBundleMessageSource. Unfortunately, there are several issues with this approach. I have the following in my resources.groovy file:

messageSource(DatabaseMessageSource)

First of all, if I simply extend ResourceBundleMessageSource and override the resolveCode method, that method never gets called. So in my else block, calling super.resolveCode is moot.

I then attempted to just implement my DatabaseMessageSource class with all the code from ResourceBundleMessageSource but I'm apparently missing something in resources.groovy because the default bundles aren't getting wired up.

So at this point, I'm still lost on what I need to do. I want to first check the database. If the code doesn't exist, revert to the same default behavior as ResourceBundleMessageSource.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I would propose to keep one bundle-message-source in a new bean and inject it into your DatabaseMessageSource.

resources.groovy:

// Place your Spring DSL code here
beans = {
    messageSource(DatabaseMessageSource) {
        messageBundleMessageSource = ref("messageBundleMessageSource")
    }    
    messageBundleMessageSource(org.codehaus.groovy.grails.context.support.PluginAwareResourceBundleMessageSource) {
        basenames = "WEB-INF/grails-app/i18n/messages"
    }
}

DatabaseMessageSource.groovy:

class DatabaseMessageSource extends AbstractMessageSource {

    def messageBundleMessageSource

    protected MessageFormat resolveCode(String code, Locale locale) {
         Message msg = Message.findByCodeAndLocale(code, locale)
         def format
         if(msg) {
             format = new MessageFormat(msg.text, msg.locale)
         }
         else {
             format = messageBundleMessageSource.resolveCode(code, locale)
         }
         return format;
    }
}

This way, in fallback solution, the message will be read from the appropriate messages_*.properties file, by just requesting it from one resource bundle message source. Note that you should use the PluginAwareResourceBundleMessageSource, otherwise you could miss some important messages from your plugins.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...