Grails: Как получить доступ к i18n от контроллера или службы?
Я сделал этот контроллер, который должен использоваться для отправки электронных писем. Мне нужно получить доступ к i18n для отправки локализованных писем.
class MailController {
MessageSource messageSource
static transactional = false
public void sendEmail() {
String name = "some name..."
String subject = message(code:"somemessagekey", args:[name])
// do some fancy stuff here...
}
}
Тогда есть файл i18n (расположенный в папке i18n):
file name: messages.properties
content: somemessagekey = Blabla {0} - blablabla
После запуска этого запуска он запускает (в тесте интеграции):
groovy.lang.MissingPropertyException: No such property: messageSource for class: org.codehaus.groovy.grails.support.MockApplicationContext
Я не в курсе, как обрабатывать эту локализацию в контроллере (я также пробовал его в службе, но это еще сложнее).
Ответы
Ответ 1
Если вы используете grails 1.3.7, вам нужно объявить источник сообщения как:
def messageSource
Таким образом, он будет введен в ваш контроллер. Я думаю, что в 2.0 вы можете сделать это так, как вы разместили, но это так, я думаю, стоит попробовать объявить это, как указано выше.
Ответ 2
Я знаю, что есть ответ, но здесь я беру на это. Я сделал услугу (вдохновил других)
import org.springframework.web.servlet.i18n.SessionLocaleResolver
import org.springframework.context.MessageSource
class I18nService {
boolean transactional = false
SessionLocaleResolver localeResolver
MessageSource messageSource
/**
*
* @param msgKey
* @param defaultMessage default message to use if none is defined in the message source
* @param objs objects for use in the message
* @return
*/
def msg(String msgKey, String defaultMessage = null, List objs = null) {
def msg = messageSource.getMessage(msgKey,objs?.toArray(),defaultMessage,localeResolver.defaultLocale)
if (msg == null || msg == defaultMessage) {
log.warn("No i18n messages specified for msgKey: ${msgKey}")
msg = defaultMessage
}
return msg
}
/**
* Method to look like g.message
* @param args
* @return
*/
def message(Map args) {
return msg(args.code, args.default, args.attrs)
}
}
Теперь, в службе просто введите i18nService, и вам хорошо идти! Это также делает модульное тестирование другого сервиса легким, поскольку вы можете высмеивать i18nService
В качестве бонуса служба попытается найти текущую локаль для текущего веб-запроса, считая, что служба работает в контексте webrequest.
Ответ 3
В Grails 2.2.3 он должен работать:
import org.springframework.context.MessageSource
...
def MessageSource messageSource
...
String subject = messageSource.getMessage("somemessagekey", [name], null)
...
Ссылка ссылки и больше возможностей здесь: http://static.springsource.org/spring/docs/2.0.8/api/org/springframework/context/MessageSource.html
Ответ 4
Ответ выше не помог мне.
Я использую Grails 3.0.1, и решение ниже было полезно для меня.
import org.springframework.context.i18n.LocaleContextHolder as LCH
import grails.util.Holders;
class MyService{
def messageSource = Holders.getGrailsApplication().getParentContext();
public String MyMethod()
{
String message = messageSource.getMessage("code",args,LCH.getLocale());
}
}
Ответ 5
Официальный способ на самом деле довольно прост. В официальной документации указано следующее:
Простое чтение сообщений в контроллере, так как вы можете вызывать теги как методы:
def show() {
def msg = message(code: "my.localized.content", args: ['Juan', 'lunes'])
}
Такую же технику можно использовать в тегах библиотеки, но если ваш тег библиотека использует пользовательский namespace, тогда вы должны префикс вызова с g.
:
def myTag = { attrs, body ->
def msg = g.message(code: "my.localized.content", args: ['Juan', 'lunes'])
}
Также обратите внимание, чтобы не предоставлять аргументы, когда ваш перевод не использует аргументы:
def msg = message(code: "my.localized.content")
Ответ 6
Я использую grails 3.x.Injected messageSource
org.springframework.context.MessageSource
и используется
String getMessage(String code, Object[] args, String defaultMessage, Locale locale);
этот метод. Модифицируйте свой код на
class MailController {
MessageSource messageSource
static transactional = false
public void sendEmail() {
String name = "some name..."
String subject = messageSource.getMessage('somemessagekey', [name], '', null)
// do some fancy stuff here...
}
}