【问题标题】:Where's located the declaration of messageSource in Grails?Grails 中messageSource 的声明在哪里?
【发布时间】:2012-11-21 16:37:07
【问题描述】:

背景

我们对存储在数据库中的字段标签进行了一些传统的国际化,因此我尝试创建一个“合并”消息源。如果代码在数据库中,则返回,如果没有,使用PluginAwareResourceBundleMessageSource在i18n中查找。

问题

由于某种原因,cachedMergedPluginProperties 正在为区域设置缓存错误的文件。例如,如果我搜索 en_US,我会收到 pt_BR 消息(地图的键是 en_US,但属性是 pt_BR)。

我声明我的 messageSource 如下:

messageSource(DatabaseMessageSource) {
  messageBundleMessageSource = { org.codehaus.groovy.grails.context.support.PluginAwareResourceBundleMessageSource m ->
    basenames = "WEB-INF/grails-app/i18n/messages"
    } 
}  

内部 bean 是因为 Grails 不允许我拥有两个 MessageSource 类型的 bean。

我声明PluginAwareResourceBundleMessageSource 是否与Grails 的默认值不同?在哪个 Grails 文件中我可以看到这个 bean 声明?

【问题讨论】:

    标签: grails internationalization grails-2.0


    【解决方案1】:

    我在I18nGrailsPlugin 中找到了声明,它比我的更详细:

    String baseDir = "grails-app/i18n"
    String version = GrailsUtil.getGrailsVersion()
    String watchedResources = "file:./${baseDir}/**/*.properties".toString()
    ...
     Set baseNames = []
    
            def messageResources
            if (application.warDeployed) {
                messageResources = parentCtx?.getResources("**/WEB-INF/${baseDir}/**/*.properties")?.toList()
            }
            else {
                messageResources = plugin.watchedResources
            }
    
            if (messageResources) {
                for (resource in messageResources) {
                    // Extract the file path of the file's parent directory
                    // that comes after "grails-app/i18n".
                    String path
                    if (resource instanceof ContextResource) {
                        path = StringUtils.substringAfter(resource.pathWithinContext, baseDir)
                    }
                    else {
                        path = StringUtils.substringAfter(resource.path, baseDir)
                    }
    
                    // look for an underscore in the file name (not the full path)
                    String fileName = resource.filename
                    int firstUnderscore = fileName.indexOf('_')
    
                    if (firstUnderscore > 0) {
                        // grab everyting up to but not including
                        // the first underscore in the file name
                        int numberOfCharsToRemove = fileName.length() - firstUnderscore
                        int lastCharacterToRetain = -1 * (numberOfCharsToRemove + 1)
                        path = path[0..lastCharacterToRetain]
                    }
                    else {
                        // Lop off the extension - the "basenames" property in the
                        // message source cannot have entries with an extension.
                        path -= ".properties"
                    }
                    baseNames << "WEB-INF/" + baseDir + path
                }
            }
    
            LOG.debug "Creating messageSource with basenames: $baseNames"
    
            messageSource(PluginAwareResourceBundleMessageSource) {
                basenames = baseNames.toArray()
                fallbackToSystemLocale = false
                pluginManager = manager
                if (Environment.current.isReloadEnabled() || GrailsConfigUtils.isConfigTrue(application, GroovyPagesTemplateEngine.CONFIG_PROPERTY_GSP_ENABLE_RELOAD)) {
                    def cacheSecondsSetting = application?.flatConfig?.get('grails.i18n.cache.seconds')
                    if (cacheSecondsSetting != null) {
                        cacheSeconds = cacheSecondsSetting as Integer
                    } else {
                        cacheSeconds = 5
                    }
                }
            }
    

    由于 Grails 不允许您拥有两个 MessageSource 类型的 bean,因此我不得不复制此代码并适应我的“合并”消息源。

    【讨论】:

      最近更新 更多