2011-11-11 16 views
11

正在關注this blog article我啓用了我的應用程序從數據庫加載i18n消息。它效果很好。但是,我不想管理數據庫中的所有消息。所以我想能夠說,如果我沒有找到數據庫中的代碼,然後使用默認機制加載它。Grails 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

你有沒有這個工作? – Marco

回答

11

我建議將一個bundle-message-source保存在一個新的bean中,並將它注入到你的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。常規:

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,否則您可能會錯過插件中的一些重要消息。

0

AbstractMessageSource中的resolveCode(code,locale)是一種抽象方法,因此您將無法調用它。請嘗試擴展ResourceBundleMessageSourceReloadableResourceBundleMessageSource

+0

啊哈!謝謝。 ResourceBundleMessageSource可能是我需要的。我會在早上測試它並報告回來。非常感謝。 – Gregg

+0

事實證明,簡單地擴展ResourceBundleMessageSource不起作用。 resolveCode方法永遠不會被調用,如果我嘗試和實現它在實際類中編碼的方式完全相同(我下載了源代碼),它不會根據我在做什麼正確地連接它的所有包信息在resources.groovy文件中。我已更新我的問題以反映這一點。 – Gregg

0

雖然它不是Grails特有的,但我們在Griffon創建了CompositeResourceBundle和DelegatingResourceBundle作爲我們自己的i18n插件的一部分(來源於http://svn.codehaus.org/griffon/plugins/griffon-i18n/trunk/src/main/griffon/plugins/i18n/)。

ExtendedResourceBundleMessageSource顯示如何使用這些類。

+0

謝謝aalmiray。我真的需要恢復爲默認的Spring/Grails。你的代碼看起來像是處理自己的加載包。我需要Grails以grails加載它們的方式加載這些包。我只需要添加首先查看消息數據庫的功能。也許我現在太累了,現在得到它。但我也認爲訣竅在於如何在resources.groovy中定義我的bean,這可能需要grails答案。 – Gregg

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" 
    } 
} 
+0

不,使用ReloadableResourceBundleMessageSource也不起作用。它甚至沒有進入我的DatabaseMessageSource類中設置了斷點。而呈現的唯一消息是消息taglib用法中提供的默認消息。 – Gregg

+0

我猜不知道在resources.groovy中的接線不好,即不覆蓋默認的messageSource配置。同時檢查resources.groovy的配置,我原來的配置是錯誤的,即使用'beans {..}'並且不要忘記com.mycompany ....或者任何你使用的前綴 – fixitagain

+0

關於這個問題的任何消息? – fixitagain

0

我強烈建議您使用Copycopter(http://copycopter.com)來管理國際密鑰內容。它將允許您的團隊使用友好的界面輕鬆更新密鑰,並且您可以根據需要設置默認值。這樣,當需要更新密鑰時,沒有人會來找你。

ThoughtBot是一個強大的網絡開發諮詢公司,它是該產品的幕後推手。它是堅實的。

您的代碼將是這樣的,那麼:

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}}) 

的國際化按鍵上copytcopter飛,你使用它的第一次產生。它非常易於使用。

看看它,這是值得的。

+0

你爲什麼低調? – Quentin