关注this blog article我启用了我的应用程序从数据库加载i18n消息。它很棒。但是,我不想管理数据库中的所有消息。所以我想能够说我是否在数据库中找不到代码,然后使用默认机制加载它。
这就是我所拥有的:
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;
}
}
我尝试调用super.resolveCode(代码,语言环境)但导致编译错误。而且我很难跟踪Grails正在使用的AbstractMessageSource的实现,以查看源代码。
更新:感谢doelleri我现在意识到我需要做的就是扩展ResourceBundleMessageSource。不幸的是,这种方法存在一些问题。我在resources.groovy文件中有以下内容:
messageSource(DatabaseMessageSource)
首先,如果我只是扩展ResourceBundleMessageSource并覆盖resolveCode方法,那么永远不会调用该方法。所以在我的else块中,调用super.resolveCode是没有意义的。
然后我尝试使用ResourceBundleMessageSource中的所有代码实现我的DatabaseMessageSource类,但我显然在resources.groovy中遗漏了一些东西,因为默认的bundle没有连接起来。
所以在这一点上,我仍然迷失在我需要做的事情上。我想先检查数据库。如果代码不存在,请恢复为与ResourceBundleMessageSource相同的默认行为。
答案 0 :(得分:12)
我建议在新bean中保留一个bundle-message-source并将其注入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;
}
}
这样,在后备解决方案中,只需从一个资源包消息源请求消息,即可从相应的messages_*.properties
文件中读取消息。请注意,您应该使用PluginAwareResourceBundleMessageSource
,否则您可能会错过插件中的一些重要消息。
答案 1 :(得分:1)
您可以扩展ReloadableResourceBundleMessageSource(原始grails消息包,这似乎不是最终的),然后应用此代码:
class DatabaseMessageSource extends ReloadableResourceBundleMessageSource {
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{
format = super.resolveCode(code,locale)
}
return format;
}
}
您还可以在Resources.groovy中重新配置您的消息资源:
beans = {
messageSource(com.mycompany.DatabaseMessageSource) {
basename = "WEB-INF/grails-app/i18n/messages"
}
}
答案 2 :(得分:0)
答案 3 :(得分:0)
虽然它不是Grails特有的,但我们在Griffon创建了CompositeResourceBundle和DelegatingResourceBundle作为我们自己的i18n插件的一部分(来源于http://svn.codehaus.org/griffon/plugins/griffon-i18n/trunk/src/main/griffon/plugins/i18n/)。
ExtendedResourceBundleMessageSource显示了如何使用这些类。
答案 4 :(得分:0)
我强烈建议您使用Copycopter
(http://copycopter.com)管理i18n密钥内容。它允许您的团队使用友好的界面轻松地动态更新密钥,您可以根据需要设置默认值。这样,当需要更新密钥时,没有人会来找你。
您的代码将如下所示:
mail :to => member.email,
:subject => I18n.translate("member_mailer.reminder_to_sign_in.#{underscored_number_of_days}.subject",
:default => %{You have not signed in for #{humanized_number_of_days}})
第一次使用i18n键时,会立即在copytcopter上生成i18n键。这很容易使用。
检查一下,这是值得的。