显示导航

如何在 Grails 应用程序中更改语言?

了解如何更改应用程序中使用的默认语言,在语言之间进行切换或访问当前区域信息。

作者:Sergio del Amo

Grails 版本 5.0.1

1 Grails 培训

Grails 培训 - 由创建和积极维护 Grails 框架的人员开发和提供的!

2 开始

在本指南中,你将了解如何创建界面已翻译成四种语言的应用程序。

你将了解如何更改应用程序中使用的默认语言以及在使用应用程序时如何切换语言。

2.1 需要的事项

要完成此指南,你需要以下事项

  • 一些空闲时间

  • 一个体面的文本编辑器或 IDE

  • 已安装 JDK 1.8 或更高版本,并已正确配置了 JAVA_HOME

2.2 如何完成此指南

要开始,请执行以下操作

或者

Grails 指南存储库包含两个文件夹

  • initial 初始项目。通常是带有附加代码的简单 Grails 应用程序,用于帮助你快速上手。

  • complete 一个已完成的示例。这是执行指南中介绍的步骤并对 initial 文件夹应用这些更改的结果。

要完成此指南,请转到 initial 文件夹

  • cd进入 grails-guides/grails_i18n/initial

然后按照下一部分中的说明进行操作。

如果您进入 grails-guides/grails_i18n/complete,您可以直接使用已完成的示例 cd

3 编写应用程序

Grails 开箱即支持国际化 (i18n),这是通过利用基础 Spring MVC 国际化支持来实现的。在 Grails 中,您可以根据用户的地区来定制显示在视图中的文本

3.1 消息包

Grails 中的消息包位于 grails-app/i18n 目录中,并且是简单的 Java 属性文件。

我们希望在应用程序中支持英语、西班牙语、意大利语和德语。我们将在不同的消息包中定义这些语言环境。

默认消息包

grails-app/i18n/messages.properties
navbar.applicationStatus=Application Status
navbar.artefacts=Artefacts
navbar.installedPlugins=Installed Plugins
navbar.languages=Languages

language.en=English
language.es=Spanish
language.de=German
language.it=Italian

welcome.title=Welcome to Grails
welcome.body=Congratulations, you have successfully started your first Grails application! At the moment this is the default page, feel free to modify it to either redirect to a controller or display whatever content you may choose. Below is a list of controllers that are currently deployed in this application, click on each to execute its default action:

西班牙语消息包

grails-app/i18n/messages_es.properties
navbar.applicationStatus=Estado de la aplicación
navbar.artefacts=Artefactos
navbar.installedPlugins=Plugins instalados
navbar.languages=Idiomas

language.en=Inglés
language.es=Español
language.de=Alemán
language.it=Italiano

welcome.title=Bienvenido a Grails
welcome.body=¡Enhorabuena, ha iniciado con éxito su primera aplicación de Grails! En este momento es la página predeterminada, no dude en modificarla para redirigir a un controlador o mostrar el contenido que elija. A continuación se muestra una lista de controladores que se implementan actualmente en esta aplicación, haga clic en cada uno para ejecutar su acción predeterminada:

意大利语消息包

grails-app/i18n/messages_it.properties
navbar.applicationStatus=Stato dell'applicazione
navbar.artefacts=Artefatti
navbar.installedPlugins=Plugin installati
navbar.languages=Le lingue

language.en=Inglese
language.es=Spagnolo
language.de=Tedesco
language.it=Italiano

welcome.title=Benvenuti a Grails
welcome.body=Congratulazioni, hai iniziato con successo la tua prima applicazione Grails! Al momento questa è la pagina predefinita, sentitevi liberi di modificarla per reindirizzare a un controller o visualizzare qualsiasi contenuto che puoi scegliere. Di seguito è riportato un elenco di controller attualmente implementati in questa applicazione, fare clic su ciascuno per eseguire l'azione predefinita:

德语消息包

grails-app/i18n/messages_de.properties
navbar.applicationStatus=Bewerbungsstatus
navbar.artefacts=Artefakte
navbar.installedPlugins=Installierte Plugins
navbar.languages=Sprachen

language.en=Englisch
language.es=Spanisch
language.de=Deutsche
language.it=Italienisch

welcome.title=Willkommen in Grails
welcome.body=Herzlichen Glückwunsch, Sie haben Ihre erste Grails-Anwendung erfolgreich begonnen! Im Moment ist dies die Standard-Seite, fühlen Sie sich frei, es zu ändern, um entweder auf einen Controller umzuleiten oder anzuzeigen, welche Inhalte Sie wählen können. Unten ist eine Liste von Controllern, die derzeit in dieser Anwendung bereitgestellt werden, klicken Sie auf jeden, um seine Standardaktion auszuführen:

我们在主页中使用这些消息代码

grails-app/views/index.gsp
<h1><g:message code="welcome.title" /></h1>
<p><g:message code="welcome.body" /></p>

3.2 更改语言环境

您可以简单地将名为 lang 的参数作为请求参数传递给 Grails,从而切换语言环境

/?lang=es

Grails 将自动切换用户的语言环境并将该语言环境存储在一个 cookie 中,这样后续请求将包含新的头信息。

我们可以使用功能测试验证此行为

/src/integration-test/groovy/demo/ChangeLocaleSpec.groovy
package demo

import geb.spock.GebSpec
import grails.testing.mixin.integration.Integration

@Integration
class ChangeLocaleSpec extends GebSpec {

    def "change locale"() {
        when:
        go '/?lang=en'

        then:
        $('h1').text() == 'Welcome to Grails'

        when:
        go '/?lang=es'

        then:
        $('h1').text() == 'Bienvenido a Grails'
    }
}

3.3 更改默认语言环境

我们希望我们的应用程序在启动时默认使用西班牙语

grails-app/conf/spring/resources.groovy
import org.springframework.web.servlet.i18n.SessionLocaleResolver;

// Place your Spring DSL code here
beans = {
    localeResolver(SessionLocaleResolver) {
        defaultLocale= new java.util.Locale('es');
    }
}

我们可以使用功能测试验证默认语言环境为西班牙语

/src/integration-test/groovy/demo/DefaultLocaleSpec.groovy
package demo

import geb.spock.GebSpec
import grails.testing.mixin.integration.Integration

@Integration
class DefaultLocaleSpec extends GebSpec {

    def "change locale"() {
        when:
        go '/'

        then:
        $('h1').text() == 'Bienvenido a Grails'
    }
}

3.4 语言栏

我们将在配置属性中定义受支持的语言

/grails-app/conf/application.yml
---
guide:
    languages:
        - en
        - es
        - it
        - de
---

我们将使用标签库来渲染一个语言下拉列表

languages drop down
/grails-app/taglib/demo/LocaleNavbarTagLib.groovy
package demo

import grails.config.Config
import grails.core.support.GrailsConfigurationAware
import org.springframework.context.MessageSource
import org.springframework.context.i18n.LocaleContextHolder

class LocaleNavbarTagLib implements GrailsConfigurationAware {

    static namespace = 'navBar'

    static defaultEncodeAs = [taglib: 'none']

    MessageSource messageSource

    List<String> languages

    @Override
    void setConfiguration(Config co) {
        languages = co.getProperty('guide.languages', List) (1)
    }

    def localeDropdownListItems = { args ->
        String uri = args.uri

        for (String lang : languages) {
            String languageCode = "language.$lang"

            def locale = LocaleContextHolder.locale
            def msg = messageSource.getMessage(languageCode, [] as Object[], null, locale) (3)
            out << "<li><a href='${uri}?lang=${lang}'>${msg}</a></li>"
        }
    }
}
1 检索配置属性
2 访问当前语言环境
3 检索已本地化消息

我们可以使用单元测试测试标签库渲染。

/src/test/groovy/demo/LocaleNavbarTagLibSpec.groovy
package demo

import grails.testing.web.taglib.TagLibUnitTest
import org.springframework.context.MessageSource
import spock.lang.Specification

class LocaleNavbarTagLibSpec extends Specification implements TagLibUnitTest<LocaleNavbarTagLib> {

    void "LocaleNavbarTagLib method localeDropdown renders"() {
        given:
        def uri = '/books'
        def languages = [[code: 'en', msg: 'English'],
                         [code: 'es', msg: 'Spanish'],
                         [code: 'it', msg: 'Italian'],
                         [code: 'de', msg: 'German']]

        when:
        def expected = ''
        languages.each { Map m ->
            expected += "<li><a href='${uri}?lang=${m.code}'>${m.msg}</a></li>"
        }
        tagLib.languages = languages.collect { it.code }
        tagLib.messageSource = Stub(MessageSource) {
            getMessage('language.en', [] as Object[], null, _) >> languages.find { it.code == 'en'}.msg
            getMessage('language.es', [] as Object[], null, _) >> languages.find { it.code == 'es'}.msg
            getMessage('language.it', [] as Object[], null, _) >> languages.find { it.code == 'it'}.msg
            getMessage('language.de', [] as Object[], null, _) >> languages.find { it.code == 'de'}.msg
        }
        def result = applyTemplate('<navBar:localeDropdownListItems uri="/books"/>')

        then:
        cleanUpString(result) == cleanUpString(expected)
    }

    String cleanUpString(String str) {
        str.replaceAll('\n','').replaceAll(' ', '')
    }
}

我们在默认 GSP 的 <content> 元素中调用 TagLib

/grails-app/views/index.gsp
<li class="dropdown">
    <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><g:message code="languages" default="Languages"/> <span class="caret"></span></a>
    <ul class="dropdown-menu">
        <navBar:localeDropdownListItems uri="${request.forwardURI}"/>
    </ul>
</li>

我们向标签库提供 request.forwardURI

forwardURI - 用于获取当前请求 URI,因为 request 对象的 requestURI 属性返回原始 URI,而不是匹配的 URI。

4 运行应用程序

运行测试

./grailsw
grails> test-app
grails> open test-report

或者

./gradlew check
open build/reports/tests/index.html

要运行应用程序,请使用命令 ./gradlew bootRun,这将在 8080 端口上启动应用程序。

5 您是否需要 Grails 帮助?

Object Computing, Inc. (OCI) 赞助了本指南的制作。该公司提供多种咨询和支持服务。

OCI 是 Grails 的家

认识团队