web-dev-qa-db-fra.com

Grails: Comment accéder à i18n depuis le contrôleur ou le service?

J'ai fait ce contrôleur, qui devrait être utilisé pour envoyer des emails. J'ai besoin d'accéder à i18n pour pouvoir envoyer des emails localisés.

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

Il y a alors le fichier i18n (situé dans le dossier i18n):

file name: messages.properties
content: somemessagekey = Blabla {0} - blablabla

Après avoir lancé ceci, cela jette (dans un test d'intégration):

groovy.lang.MissingPropertyException: pas de propriété de ce type: messageSource pour la classe: org.codehaus.groovy.grails.support.MockApplicationContext

Je suis à court d'idées sur la façon de gérer cette localisation dans le contrôleur (je l'ai également essayée dans un service, mais c'est encore plus compliqué).

20
Ondrej Kvasnovsky

Si vous utilisez grails 1.3.7, vous devez déclarer la source du message comme suit:

def messageSource

De cette façon, il sera injecté dans votre contrôleur. Je pense qu'en 2.0, vous pouvez le faire comme vous l'avez posté, mais malgré tout, je pense que cela vaut la peine d'essayer de le déclarer comme indiqué ci-dessus.

23
Roberto Guerra

Je sais qu'il y a une réponse, mais voici ce que je pense. J'ai rendu un service (inspiré par d'autres) 

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

Maintenant, dans un service, il suffit d'injecter i18nService et vous êtes prêt à partir! Cela facilite également les tests unitaires d’autres services, car vous pouvez vous moquer du i18nService.

En prime, le service tentera de trouver les paramètres régionaux en vigueur pour la requête en ligne en cours, étant donné que le service s'exécute dans un contexte de requête en ligne.

13
sbglasius

Dans Grails 2.2.3, cela devrait fonctionner:

import org.springframework.context.MessageSource
...
def MessageSource messageSource
...
String subject = messageSource.getMessage("somemessagekey", [name], null)
...

Lien de référence et plus de possibilités ici: http://static.springsource.org/spring/docs/2.0.8/api/org/springframework/context/MessageSource.html

6
chelder

La réponse ci-dessus ne m'a pas aidé. J'utilise Grails 3.0.1 et la solution ci-dessous m'a été utile.

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
emihailov

J'utilise grails 3.x.Injected messageSource 

org.springframework.context.MessageSource

et utilisé

String getMessage(String code, Object[] args, String defaultMessage, Locale locale);

cette méthode.Modifiez votre code pour

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...
    }
}
1
Shivam Pandey

La voie officielle est en fait assez facile. La documentation officielle indique ce qui suit:

Il est simple de lire les messages dans un contrôleur car vous pouvez appeler les balises En tant que méthodes:

def show() {
    def msg = message(code: "my.localized.content", args: ['Juan', 'lunes'])
}

La même technique peut être utilisée dans bibliothèques de balises , mais si votre bibliothèque de balises Utilise un répertoire personnalisé namespace , vous devez préfixer l'appel Avec g.:

def myTag = { attrs, body ->
    def msg = g.message(code: "my.localized.content", args: ['Juan', 'lunes'])
}

Veuillez également noter de ne pas fournir d'arguments lorsque votre traduction n'utilise pas d'arguments:

def msg = message(code: "my.localized.content")
1
Cristan

J'ai essayé ci-dessous le code et son fonctionnement à l'aide de titulaires.

def messageSource = Holders.getGrailsApplication().getMainContext().getBean("messageSource")

String errorMesssage = messageSource.getMessage('validation.error.catalogue.not.found', null, messageSource.getMessage(
                        'validation.error.catalogue.not.found', null, 'No Content found for the Reserved Instance Plan Catalogue', locale), locale)
0
Pukhraj soni