目前,我在 Closure 应用程序中只使用纯文本。我想为这些文本添加本地化。我刚刚找到了几篇关于 goog.getMsg 函数的文章,该函数用于进行这种本地化。据我了解,它是在编译时完成的。当用户单击按钮时,我们如何在运行时更改语言?使用 Closure 最简单的方法是什么?
2 回答
我实际上已经实现了运行时 i18n。我使用带有{msg}
标签的 .soy 模板。当您将 .soy 编译为 .js 时,这些调用将编译为 goog.getMsg 调用。我必须做的是:
- 查找其中包含的所有
.js
文件goog.getMsg(
- 前置
goog.require("myApp.i18n");\n
- 将所有
goog.getMsg(
呼叫替换为myApp.i18n.translate(
- 将所有
MSG_*
属性名称替换为myprefix_MSG_*
为什么这一切:不能直接覆盖 goog.getMsg,因为它被认为是编译器原语并且不允许任何操作。同样适用于MSG_*
属性。
myApp.i18n.translate
是一个接受字符串的函数,尝试在语言环境映射中查找它(在运行时传递)并goog.getMsg
使用本地化字符串返回结果(进行goog.getMsg
一些方便的占位符替换)。
虽然这不是一个非常漂亮的解决方案,但它可以工作并且允许我在运行时更改语言,只使用一个编译文件来处理所有语言。
实际代码包括一些技巧,允许我使用生成的描述并使用 JSON 文件而不是看起来很奇怪的闭包文件格式,但要点是相同的。
然而!
您真正应该做的是从您的应用程序中编译几个文件并为每种语言加载不同的 .js 文件。
我不得不使用这个解决方案,因为我需要支持数百种不同的配置和多种语言:编译数千个 .js 文件会很疯狂,而一次编译需要 30 多秒。
虽然这不是一个单击语言切换解决方案,但我觉得它非常舒服,因为它允许在 Soy 模板和goog.getMsg()
JS 代码中使用相同的本地化文本源。这是一种使用 Google 自己的 XML 翻译格式(称为 XTB)的未记录方式。
您最终会为每种语言生成不同的编译 .js 文件,因此要切换语言环境,您必须重新加载不同的 JS 文件。
除了标准的 Closure 工具之外,还有一个名为 XtbGenerator 的第三方工具,可以在这里找到:https ://github.com/kuzmisin/xtbgenerator 。
现在的工作流程:
SoyToJsSrcCompiler.jar
使用with--shouldGenerateGoogMsgDefs --bidiGlobalDir 1
选项编译模板。还没有语言环境。使用创建依赖文件
calcdeps.py
closurebuilder.py
使用--compiler_jar
设置为XtbGenerator.jar
文件和--compiler_flags="--xtb_output_file=origin.xtb"
参数运行。这将创建一个名为 的文件
origin.xtb
,然后您可以将其用作翻译的基础。它将包含来自 Soy 模板(在{msg}
块中)和您的 JS 文件(在哪里var MSG_TEST = goog.getMsg('Text');
使用)的所有文本。复制
origin.xtb
到例如translated.cs_CZ.xtb
,更改lang
文件中的属性并翻译那里的所有文本。closurebuilder.py
使用和以标准方式为给定的语言环境编译应用程序compiler.jar
。使用参数:--compiler_flags="--translations_file=translated.cs_CZ.xtb"
--compiler_flags="--define=goog.LOCALE='cs_CZ'"
这将为您创建单一语言环境的编译版本。
所有这些步骤的好例子都在这里:http ://www.closurecheatsheet.com/skeleton
不幸的是,几乎没有官方文档。
XTB 格式:
格式如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE translationbundle>
<translationbundle lang="cs">
<translation id="4127240967364168948" key="MSG_6LRZ706911HM" source="..\test.soy.js" desc="description">test</translation>
</translationbundle>
id
对于大豆模板,key
属性也是由编译器/提取器自动生成的
这很可能是一些 Google 内部格式,其中包含尚未开源的工具。
关于 XtbGenerator 的注意事项:
它在内部使用 Closure Compiler 代码来遍历您的 JS 代码并提取消息。然而,可下载版本是使用旧版本的 Closure Compiler 构建的,所以它给我带来了一些错误。
我通过将goog
目录从当前版本复制compiler.jar
到XtbGenerator.jar
.