181 lines
7.6 KiB
Markdown
181 lines
7.6 KiB
Markdown
# 10.3 国際化サイト
|
||
前の節でどのようにしてローカライズリソースを処理するかご紹介しました。Localeに対応した設定ファイルです。ではもし複数のローカライズリソースを処理する場合は?いくつかの我々が通常使用する例は:簡単なテキスト翻訳、時間や日時、数字といったものはどのように処理するのでしょうか?この節では一つ一つこれらの問題を解決していきます。
|
||
## 複数のロケールパッケージの管理
|
||
アプリケーションをひとつ開発する時、まず決めなければならないのは、一つの言語だけをサポートすればよいのか、それとも多言語をサポートするのかということです。もし複数の言語のサポートする必要があれば、ある組織構成を作成することで、将来より多くの言語を追加できるようにしなければなりません。ここでは以下のように設計します:Localeに関係のあるファイルをconfig/localesの下に配置し、もし日本語と英語をサポートしなければならない場合は、このディレクトリの下にen.jsonとja.jsonを配置する必要があります。だいたいの内容は以下の通り:
|
||
|
||
# ja.json
|
||
|
||
{
|
||
"ja": {
|
||
"submit": "送信",
|
||
"create": "作成"
|
||
}
|
||
}
|
||
|
||
#en.json
|
||
|
||
{
|
||
"en": {
|
||
"submit": "Submit",
|
||
"create": "Create"
|
||
}
|
||
}
|
||
|
||
国際化をサポートするにあたって、ここでは国際化に関連したパッケージを使用することにします- - [go-i18n](https://github.com/astaxie/go-i18n)です。まずgo-i18nパッケージにconfig/localesのディレクトリを登録することで、すべてのlocaleファイルをロードします。
|
||
|
||
Tr:=i18n.NewLocale()
|
||
Tr.LoadPath("config/locales")
|
||
|
||
このパッケージは非常に使いやすく、以下の方法によって試すことができます:
|
||
|
||
fmt.Println(Tr.Translate("submit"))
|
||
//Submitを出力
|
||
Tr.SetLocale("ja")
|
||
fmt.Println(Tr.Translate("submit"))
|
||
//"送信"を出力
|
||
|
||
## 自動的にロケールパッケージをロード
|
||
上ではどのようにして自動的にカスタムな言語パッケージをロードするかご紹介しました。実はgo-i18nライブラリはすでに多くのデフォルトのフォーマット情報をロードしています。たとえば時間フォーマット、通貨フォーマットです。ユーザはカスタムな設定を行う場合これらのデフォルトの設定を修正することができます。以下の処理プロセスをご覧ください:
|
||
|
||
|
||
//デフォルトの設定ファイルをロードします。これらのファイルはすべてgo-i18n/localesの下にあります。
|
||
|
||
//ファイルはそれぞれzh.json、en-json、en-US.json等と名前をつけます。より多くの言語を続けて拡張することができます。
|
||
|
||
func (il *IL) loadDefaultTranslations(dirPath string) error {
|
||
dir, err := os.Open(dirPath)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
defer dir.Close()
|
||
|
||
names, err := dir.Readdirnames(-1)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
|
||
for _, name := range names {
|
||
fullPath := path.Join(dirPath, name)
|
||
|
||
fi, err := os.Stat(fullPath)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
|
||
if fi.IsDir() {
|
||
if err := il.loadTranslations(fullPath); err != nil {
|
||
return err
|
||
}
|
||
} else if locale := il.matchingLocaleFromFileName(name); locale != "" {
|
||
file, err := os.Open(fullPath)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
defer file.Close()
|
||
|
||
if err := il.loadTranslation(file, locale); err != nil {
|
||
return err
|
||
}
|
||
}
|
||
}
|
||
|
||
return nil
|
||
}
|
||
|
||
上の方法で設定ファイルをデフォルトのファイルにロードします。このようにカスタムな時間情報がない場合でも以下のようなコードで対応する情報を取得することができます:
|
||
|
||
//locale=zhの状況で、以下のコードを実行:
|
||
|
||
fmt.Println(Tr.Time(time.Now()))
|
||
//出力:2009年1月08日 星期四 20:37:58 CST
|
||
|
||
fmt.Println(Tr.Time(time.Now(),"long"))
|
||
//出力:2009年1月08日
|
||
|
||
fmt.Println(Tr.Money(11.11))
|
||
//出力:¥11.11
|
||
|
||
## template mapfunc
|
||
上では複数の言語パッケージの管理とロードを実装しました。いくつかの関数の実装はロジックレイヤに基いています。例えば:"Tr.Translate"、"Tr.Time"、"Tr.Money"等です。ロジックレイヤではこのような関数を利用して必要なパラメータに対し置換を行った後テンプレートレイヤに適用する際直接出力することができます。しかしもしテンプレートレイヤでこれらの関数を直接使いたい場合はどのように実現するのでしょうか?覚えていらっしゃいますか、前にテンプレートをご紹介した時に:Go言語のテンプレートはカスタムなテンプレート関数をサポートしています。以下では操作に便利なmapfuncを実装します:
|
||
|
||
1. テキスト情報
|
||
|
||
テキスト情報は`Tr.Translate`をコールすることで対応するデータを置換します。mapFuncの実装は以下のとおり:
|
||
|
||
func I18nT(args ...interface{}) string {
|
||
ok := false
|
||
var s string
|
||
if len(args) == 1 {
|
||
s, ok = args[0].(string)
|
||
}
|
||
if !ok {
|
||
s = fmt.Sprint(args...)
|
||
}
|
||
return Tr.Translate(s)
|
||
}
|
||
|
||
関数の登録は以下のとおり:
|
||
|
||
t.Funcs(template.FuncMap{"T": I18nT})
|
||
|
||
テンプレートでの使用は以下のとおり:
|
||
|
||
{{.V.Submit | T}}
|
||
|
||
|
||
2. 時間と日時
|
||
|
||
時間と日時は`Tr.Time`関数をコールすることで対応する時間を置換します。mapFuncの実装は以下のとおり:
|
||
|
||
func I18nTimeDate(args ...interface{}) string {
|
||
ok := false
|
||
var s string
|
||
if len(args) == 1 {
|
||
s, ok = args[0].(string)
|
||
}
|
||
if !ok {
|
||
s = fmt.Sprint(args...)
|
||
}
|
||
return Tr.Time(s)
|
||
}
|
||
|
||
関数の登録は以下のとおり:
|
||
|
||
t.Funcs(template.FuncMap{"TD": I18nTimeDate})
|
||
|
||
テンプレートでの使用は以下のとおり:
|
||
|
||
{{.V.Now | TD}}
|
||
|
||
3. 通貨情報
|
||
|
||
通貨`Tr.Money`関数をコールすることで対応する時間を置換します。mapFuncの実装は以下のとおり:
|
||
|
||
func I18nMoney(args ...interface{}) string {
|
||
ok := false
|
||
var s string
|
||
if len(args) == 1 {
|
||
s, ok = args[0].(string)
|
||
}
|
||
if !ok {
|
||
s = fmt.Sprint(args...)
|
||
}
|
||
return Tr.Money(s)
|
||
}
|
||
|
||
関数の登録は以下のとおり:
|
||
|
||
t.Funcs(template.FuncMap{"M": I18nMoney})
|
||
|
||
テンプレートでの使用は以下のとおり:
|
||
|
||
{{.V.Money | M}}
|
||
|
||
## まとめ
|
||
この節を通して多言語パッケージのWebアプリケーションをどのようにして実現するかわかりました。カスタム言語パッケージでは便利に多言語を実装することができます。また、設定ファイルによって非常に簡単に複数の言語を拡張することもできます。デフォルトではgo-i18nはパブリックな設定ファイルをロードします。例えば時間、通貨等です。非常に簡単に使用することができ、同時にテンプレートにおいてこれらの関数をサポートするため、対応するテンプレート関数も実装しました。このようにしてWebアプリケーションを開発する際直接テンプレートにおいてpipelineの方法で多言語パッケージを操作することができます。
|
||
|
||
## links
|
||
* [目次](<preface.md>)
|
||
* 前へ: [ローカライズリソース](<10.2.md>)
|
||
* 次へ: [まとめ](<10.4.md>)
|