Not necessarily specific to GAE I suppose, but I'm curious as to what people are using to translate or localise their web applications.
My own approach I'm afraid is hopelessly naive, really just a hand-wave at the issue by loading an entity from the datastore for each package based on a locale value recorded in the user's profile. At least this allows translations of a few strings to be provided:
package foo
...
type Messages struct {
Locale string
ErrorDatastore string
LoginSuccessful string
...
}
Store with a string id corresponding to a locale, then load to Gorilla context or similar:
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)
}
Which is obviously incredibly limited, but at least makes strings available from calling code via context.Get(r, foo.Messages). Can anyone point me at more useful implementations, or suggest a better approach?
Edit (relevant but not completely useful):
Internationalization (I18N) is the process of designing and preparing software products (apps) to support multiple locales, languages, and regions. By internationalizing a codebase, developers and businesses can expand their user base and access a wider audience.
Internationalization (sometimes shortened to "I18N , meaning "I - eighteen letters -N") is the process of planning and implementing products and services so that they can easily be adapted to specific local languages and cultures, a process called localization .
Lightweight simple translation module with dynamic JSON storage. Supports plain vanilla Node. js apps and should work with any framework (like Express, restify and probably more) that exposes an app. use() method passing in res and req objects.
Jonathan Chan points out Samuel Stauffer's go-gettext which seems to do the trick. Given the directories:
~appname/
|~app/
| `-app.go
|+github.com/
`-app.yaml
Start with (assumes *nix):
$ cd appname
$ git clone git://github.com/samuel/go-gettext.git github.com/samuel/go-gettext
Source preparation cannot use the _("String to be translated") short form, due to underscore's special characteristics in Go. You can tell xgettext to look for the camelcase function name "GetText" using the -k flag.
Minimal working example:
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."))
}
Create the template with:
$ xgettext -d appname -kGetText -s -o appname.pot app/app.go
Note -k, without it there'll be no output as xgettext won't recognise calls to GetText. Edit relevant strings, email etc in appname.pot. Let's assume we're localising for French:
$ mkdir -p locale/fr_FR/LC_MESSAGES
$ msginit -l fr_FR -o french.po -i appname.pot
Edit french.po:
# Appname l10n
# Copyright (C) 2013 Wombat Inc
# This file is distributed under the same license as the appname package.
# Wombat <[email protected]>, 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 <[email protected]>\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."
Generate the binary (the file that'll actually get deployed with the app):
$ msgfmt -c -v -o locale/fr_FR/LC_MESSAGES/appname.mo french.po
Final directory structure:
~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
(locale directory under go-gettext holds test data, could be removed for deployment.)
If all goes well, a visit to appname should display "Oui."
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With