我想不一定特定于 GAE,但我很好奇人们使用什么来翻译或本地化他们的 Web 应用程序。
恐怕我自己的方法太天真了,实际上只是通过根据用户配置文件中记录的语言环境值从数据存储中为每个包加载一个实体来解决问题。至少这允许提供一些字符串的翻译:
package foo
...
type Messages struct {
Locale string
ErrorDatastore string
LoginSuccessful string
...
}
使用与语言环境对应的字符串 id 存储,然后加载到 Gorilla 上下文或类似内容:
const Messages ContextKey = iota
...
k := datastore.NewKey(c, "Messages", "en_US", 0, nil)
m := new(Messages)
if err := datastore.Get(c, k, m); err != nil {
...
} else {
context.Set(r, Messages, m)
}
这显然是非常有限的,但至少可以通过 context.Get(r, foo.Messages) 调用代码来获取字符串。谁能指出更有用的实现,或提出更好的方法?
编辑(相关但不完全有用):
最佳答案
Jonathan Chan指出 Samuel Stauffer's go-gettext这似乎可以解决问题。给定目录:
~appname/
|~app/
| `-app.go
|+github.com/
`-app.yaml
从(假设 *nix)开始:
$ cd appname
$ git clone git://github.com/samuel/go-gettext.git github.com/samuel/go-gettext
源准备不能使用 _("String to be translate") 短格式,due to underscore's special characteristics in Go .您可以使用 -k 标志告诉 xgettext 查找驼峰式函数名称“GetText”。
最小的工作示例:
package app
import (
"fmt"
"log"
"net/http"
"github.com/samuel/go-gettext"
)
func init () {
http.HandleFunc("/", home)
}
func home(w http.ResponseWriter, r *http.Request) {
d, err := gettext.NewDomain("appname", "locale")
if err != nil {
log.Fatal("Failed at NewDomain.")
}
cat := d.GetCatalog("fr_FR")
if cat == gettext.NullCatalog {
log.Fatal("Failed at GetCatalog.")
}
fmt.Fprintf(w, cat.GetText("Yes."))
}
使用以下方法创建模板:
$ xgettext -d appname -kGetText -s -o appname.pot app/app.go
注意 -k,没有它就没有输出,因为 xgettext 不会识别对 GetText 的调用。在 appname.pot 中编辑相关字符串、电子邮件等。假设我们正在本地化法语:
$ mkdir -p locale/fr_FR/LC_MESSAGES
$ msginit -l fr_FR -o french.po -i appname.pot
编辑法语.po:
# Appname l10n
# Copyright (C) 2013 Wombat Inc
# This file is distributed under the same license as the appname package.
# Wombat <wombat@example.com>, 2013.
#
msgid ""
msgstr ""
"Project-Id-Version: appname v0.1\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-01-13 11:03+1300\n"
"PO-Revision-Date: 2013-01-13 11:10+1300\n"
"Last-Translator: Rich <rich@example.com>\n"
"Language-Team: French\n"
"Language: fr\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
#: app/app.go:15
msgid "Yes."
msgstr "Oui."
生成二进制文件(实际会随应用一起部署的文件):
$ msgfmt -c -v -o locale/fr_FR/LC_MESSAGES/appname.mo french.po
最终目录结构:
~appname/
|~app/
| `-app.go
|~github.com/
| `~samuel/
| `~go-gettext/
| +locale/
| |-catalog.go
| |-domain.go
| `-mo.go
|~locale/
| `~fr_FR/
| `LC_MESSAGES/
| `-appname.mo
`-app.yaml
(go-gettext 下的 locale 目录保存测试数据,可以删除部署。)
如果一切顺利,访问 appname 应该会显示“Oui”。
关于google-app-engine - 使用 App Engine 进行 Go 的 I18n 策略,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14124630/