Grails i18n из файлов свойств, заархивированных БД? - PullRequest
2 голосов
/ 28 ноября 2011

Я пытаюсь получить ситуацию, когда я могу использовать файлы свойств i18n, для которых выполняется резервное копирование с помощью базы данных?

Так что для некоторых стандартных вещей я хотел бы использовать файлы свойств, но некоторые поля должны быть доступны для редактирования конечным пользователем, поэтому я планировал использовать i18n в базе данных для этого. Так что реальная комбинация была бы великолепна. Если код i18n не найден в файлах свойств, выполните поиск в БД.

Есть идеи, как мне справиться с этим? Я видел сообщение Grails i18n из базы данных, но по умолчанию обратно в файл

Но нет реального ответа на проблему, есть другие предложения о том, как решить эту проблему?

Ответы [ 4 ]

5 голосов
/ 28 ноября 2011

Поместите новый класс домена в ваш проект:

class Message {
    String code
    Locale locale
    String text
}

Добавьте следующие строки в ваш 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"
    }
}

И добавьте следующий класс в вашу папку src/groovy:

class DatabaseMessageSource extends AbstractMessageSource {

    def messageBundleMessageSource

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

Теперь Grails попытается разрешить сообщение из пакета сообщений. Если он недоступен, он будет искать его из базы данных. Вы можете добавить некоторую обработку ошибок, но эта версия работает, если все сообщения доступны хотя бы в одном месте.

Подробнее см. http://graemerocher.blogspot.com/2010/04/reading-i18n-messages-from-database.html.


Некоторые подробности изменений, внесенных в resources.groovy:

В этом файле вы можете определить инъецируемые классы groovy, которые можно включить, просто указав переменную с тем же именем, как определено в resources.groovy. Например. в этом файле есть messageSource и messageBundleMessageSource, которые вы можете включить в любой контроллер или служебные файлы. Если эта переменная определена, создается экземпляр класса в скобках.

В этом случае мы перезаписываем общий messageSource, чтобы использовать нашу пользовательскую реализацию DatabaseMessageSource. Поэтому функция I18n message теперь будет использовать нашу пользовательскую реализацию.

Поскольку наша пользовательская реализация требует проверки message.properties -файлов, мы сохраняем исходный источник сообщений во втором компоненте. Определив этот экземпляр в нашей пользовательской реализации, мы все еще можем использовать старую реализацию (и, следовательно, искать сообщения обычным способом).

1 голос
/ 28 ноября 2011

Я не уверен, что знаю, что вы подразумеваете под

Файлы свойств i18n, для которых выполняется резервное копирование с помощью базы данных

Но если вы просто хотите сказать, что вы хотите, чтобы ключи сообщений были разрешены с использованием таблицы базы данных (вместо файла .properties), то вы можете сделать это, написав собственную реализацию интерфейса MessageSource

class DBMessageSource implements MessageSource {
  String getMessage(MessageSourceResolvable resolvable, Locale locale) {
   // IMPLEMENT ME
  }

  String getMessage(String code, Object[] args, Locale locale) {
   // IMPLEMENT ME    
  }

  String getMessage(String code, Object[] args, String defaultMessage, Locale locale) {
   // IMPLEMENT ME    
  }
}

Затем просто замените реализацию по умолчанию компонента messageSource на вашу реализацию, добавив следующее к resources.groovy

messageSource(DBMessageSource)
0 голосов
/ 04 февраля 2014

Взгляните на https://github.com/goeh/grails-i18n-db и https://github.com/halfbaked/grails-localizations. Оба предлагают также графический интерфейс для управления локализацией.

0 голосов
/ 28 ноября 2011

В ответ на ответ @crudolf я реализовал следующий метод для достижения своей цели.

class DatabaseMessageSource extends AbstractMessageSource {
    // the message bundle resource that holds all of the messages
    def messageBundleMessageSource

    // the default locale used when there is no correct results found
    // if a visitor (x) comes along with an unknown locale in the DB
    // then this locale will be used as fallback!
    Locale fallbackLocale = new Locale("nl", "NL")

    protected MessageFormat resolveCode(String code, Locale locale) {
        // first try to find the message in the messagebundles
        MessageFormat messageFormat = messageBundleMessageSource.resolveCode(code, locale)

        if(!messageFormat) {
            // no message found so lets find one in the database
            def message = Message.findByCodeAndLocale(code, locale) ?: Message.findByCodeAndLocale(code, fallbackLocale)
            if (message) {
                // found one create a message format!
                messageFormat = new MessageFormat(message.text, message.locale)
            } else {
                // not found! create a standard message format
                messageFormat = new MessageFormat(code, locale)
            }
        }
        return messageFormat
    }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...