适用于App Engine的I18n策略

Ric*_*her 21 google-app-engine localization internationalization go

我不一定特定于GAE,但我很好奇人们用什么来翻译或本地化他们的Web应用程序.

我担心自己的方法是绝对天真的,实际上只是一个问题的手动,通过从每个包的数据存储区加载一个实体,根据用户配置文件中记录的区域设置值.至少这允许提供几个字符串的翻译:

package foo

...

type Messages struct {
    Locale string
    ErrorDatastore string
    LoginSuccessful string
    ...
}
Run Code Online (Sandbox Code Playgroud)

使用与语言环境对应的字符串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)
}
Run Code Online (Sandbox Code Playgroud)

这显然是非常有限的,但至少通过context.Get(r,foo.Messages)调用代码可以使字符串可用.任何人都可以指出我更有用的实现,或建议更好的方法?

编辑(相关但不完全有用):

Ric*_*her 9

乔纳森·陈指出,塞缪尔·斯托弗的 中间人的gettext这似乎这样的伎俩.鉴于目录:

~appname/
 |~app/
 | `-app.go
 |+github.com/
 `-app.yaml
Run Code Online (Sandbox Code Playgroud)

从(假设*nix)开始:

$ cd appname
$ git clone git://github.com/samuel/go-gettext.git github.com/samuel/go-gettext
Run Code Online (Sandbox Code Playgroud)

由于下划线在Go中的特殊特性,源代码准备不能使用_("要翻译的字符串")简短形式.您可以使用-k标志告诉xgettext查找camelcase函数名"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."))
}
Run Code Online (Sandbox Code Playgroud)

创建模板:

$ xgettext -d appname -kGetText -s -o appname.pot app/app.go
Run Code Online (Sandbox Code Playgroud)

注意-k,没有它就没有输出,因为xgettext不会识别对GetText的调用.在appname.pot中编辑相关的字符串,电子邮件等.让我们假设我们正在为法语进行本地化:

$ mkdir -p locale/fr_FR/LC_MESSAGES
$ msginit -l fr_FR -o french.po -i appname.pot
Run Code Online (Sandbox Code Playgroud)

编辑french.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."
Run Code Online (Sandbox Code Playgroud)

生成二进制文件(实际上将使用该应用程序部署的文件):

$ msgfmt -c -v -o locale/fr_FR/LC_MESSAGES/appname.mo french.po
Run Code Online (Sandbox Code Playgroud)

最终目录结构:

~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
Run Code Online (Sandbox Code Playgroud)

(go-gettext下的locale目录包含测试数据,可以删除以进行部署.)

如果一切顺利,访问appname应显示"Oui".