google-app-engine - 使用 App Engine 进行 Go 的 I18n 策略

标签 google-app-engine localization internationalization go

我想不一定特定于 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/

相关文章:

python - 任何在 google-app-engine 上处理文件上传的 gae 框架

java - JPA ManyToOne 字段未存储

php - 本地化 Laravel

python - 如何在 GAE 中使用 django 翻译?

google-app-engine - Datastore KeysOnly 在 Go 中的定价和实现

java - 印度尼西亚的正确区域设置( "id_ID"Vs "in_ID")?

iphone - 如何让 Cocoa 明白我的 iPhone 应用程序不是英文的?

c# - 在 C# 的未知语言环境中解析 double

java - Spring Boot 本地化来自 RestController 的每个响应参数

php - 如何在 centOS 上启用语言环境 en_EN 以使 i18n gettext 正常工作