如何在 Grails 应用程序中更改语言?
了解如何更改应用程序中使用的默认语言,在语言之间进行切换或访问当前区域信息。
作者:Sergio del Amo
Grails 版本 5.0.1
1 Grails 培训
Grails 培训 - 由创建和积极维护 Grails 框架的人员开发和提供的!
2 开始
在本指南中,你将了解如何创建界面已翻译成四种语言的应用程序。
你将了解如何更改应用程序中使用的默认语言以及在使用应用程序时如何切换语言。
2.1 需要的事项
要完成此指南,你需要以下事项
-
一些空闲时间
-
一个体面的文本编辑器或 IDE
-
已安装 JDK 1.8 或更高版本,并已正确配置了
JAVA_HOME
2.2 如何完成此指南
要开始,请执行以下操作
-
下载源代码并解压
或者
-
克隆 Git 存储库
git clone https://github.com/grails-guides/grails_i18n.git
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 属性文件。
我们希望在应用程序中支持英语、西班牙语、意大利语和德语。我们将在不同的消息包中定义这些语言环境。
默认消息包
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:
西班牙语消息包
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:
意大利语消息包
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:
德语消息包
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:
我们在主页中使用这些消息代码
<h1><g:message code="welcome.title" /></h1>
<p><g:message code="welcome.body" /></p>
3.2 更改语言环境
您可以简单地将名为 lang
的参数作为请求参数传递给 Grails,从而切换语言环境
/?lang=es
Grails 将自动切换用户的语言环境并将该语言环境存储在一个 cookie 中,这样后续请求将包含新的头信息。
我们可以使用功能测试验证此行为
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 更改默认语言环境
我们希望我们的应用程序在启动时默认使用西班牙语
import org.springframework.web.servlet.i18n.SessionLocaleResolver;
// Place your Spring DSL code here
beans = {
localeResolver(SessionLocaleResolver) {
defaultLocale= new java.util.Locale('es');
}
}
我们可以使用功能测试验证默认语言环境为西班牙语
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 语言栏
我们将在配置属性中定义受支持的语言
---
guide:
languages:
- en
- es
- it
- de
---
我们将使用标签库来渲染一个语言下拉列表
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 | 检索已本地化消息 |
我们可以使用单元测试测试标签库渲染。
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
。
<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 端口上启动应用程序。