diff --git a/ja/ebook/10.1.md b/ja/ebook/10.1.md new file mode 100644 index 00000000..273d8bbf --- /dev/null +++ b/ja/ebook/10.1.md @@ -0,0 +1,85 @@ +# 10.1 デフォルトロケールの設定 +## Localeとは何か +Localeとは世界中のある特定の地域を表現したテキスト形式と言語習慣の設定のセットです。locale名は通常3つの部分から構成されます:第一部分は強制的なもので、言語の省略を表します。例えば"en"は英文を表し、"zh"は中文を表します。第二部分はアンダースコアを一つ置いてオプションとなる国の説明記号が入ります。同じ言語の異なる国を区別するために用いられます。例えば"en_US"はアメリカ英語を表し、"en_UK"はイギリス英語を表します。最後の部分はピリオドを挟んでオプションとなる文字符号化方式の説明記号となります。例えば"zh_CN.gb2312"は中国で使用されるgb2312符号化方式を表します。 + +GO言語はデフォルトで"UTF-8"符号化方式を採用しています。ですので、i18nを実装する際3つ目の部分は考慮しません。以降ではlocaleが表現する前の2つの部分でもってi18n標準のlocale名とします。 + + +>LinuxとSolarisシステムでは`locale -a`コマンドを使ってサポートされるすべての地域名をリストアップすることができます。読者はこれらの地域名の命名規則を見ることができます。BSDといったシステムではlocaleコマンドはありません。しかし地域情報は/usr/share/localeに保存されています。 + +## Localeを設定 +上のlocaleに対する定義で、ユーザの情報(アクセス情報、個人情報、アクセスしたドメイン名等)に従ってこれに対応するlocaleを設定する必要があります。以下のいくつかの方法を使ってユーザのlocaleを設定することができます。 + +### ドメイン名によってLocaleを設定 +Localeの設定にはアプリケーションが実行される際のドメインによって区別する方法があります。例えば、www.asta.comを我々の英語のサイト(デフォルトサイト)として、www.asta.cnというドメイン名を中国語のサイトとしたとします。この場合アプリケーションではドメイン名と対応するlocaleの対応関係を設定することで地域を設定sるうことができます。このような処理にはいくつかのメリットがあります: + +- URLを見るだけで簡単に識別できる +- ユーザはドメイン名を通して直感的にどの言語のサイトに訪問するか知ることができる。 +- Goプログラムでは実装が非常に簡単で便利。mapを一つ使うだけで実現できる。 +- サーチエンジンのクローリングに有利。サイトのSEOを高めることができる。 + +下のコードによってドメイン名の対応するlocaleを実現できます: + + if r.Host == "www.asta.com" { + i18n.SetLocale("en") + } else if r.Host == "www.asta.cn" { + i18n.SetLocale("zh-CN") + } else if r.Host == "www.asta.tw" { + i18n.SetLocale("zh-TW") + } + +当然全体のドメイン名で地域を設定する以外に、サブドメインによって地域を設定することもできます。例えば"en.asta.com"が英語のサイトを表し、"cn.asta.com"が中文のサイトを表します。実装するコードは以下の通り: + + prefix := strings.Split(r.Host,".") + + if prefix[0] == "en" { + i18n.SetLocale("en") + } else if prefix[0] == "cn" { + i18n.SetLocale("zh-CN") + } else if prefix[0] == "tw" { + i18n.SetLocale("zh-TW") + } + +ドメイン名によるLocaleの設定は上で示したようなメリットがあります。しかし一般的にWebアプリケーションを開発する場合このような方法は採用されません。なぜならまずドメインはコストが比較的高く、Localeを一つ開発するのに一つドメイン名を必要とするからです。また、往々にして統一されたドメイン名を申請できるかどうか分かりません。次に各サイトに対してローカライズというひとつの設定を行いたくなく、urlの後にパラメータを追加する方法が採用されがちです。下のご紹介をご覧ください。 + +### ドメインのパラメータからLocaleを設定 +現在最もよく使われるLocaleの設定方法はURLにパラメータを追加することです。例えばwww.asta.com/hello?locale=zhまたはwww.asta.com/zh/helloといった具合に。このようにすることで地域を設定することができます:`i18n.SetLocale(params["locale"])`。 + +このような設定方法は前に述べたドメインによるLocaleの設定のすべてのメリットをほとんど持ちあわせています。これはRESTfulな方法を採用しており、余計な方法を追加することで処理する必要がありません。しかしこのような方法では各linkにおいて対応するパラメータlocaleを追加する必要があり、すこし複雑でかなりめんどくさい場合もあります。しかし共通の関数urlを書くことですべてのlinkアドレスをこの関数を通して生成することができます。この関数では`locale=params["locale"]`パラメータを追加することでめんどくささを和らげます。 + +URLアドレスをもっとRESTfulな見た目にしたいと思うかもしれません。例えば:www.asta.com/en/books(英語のサイト)とwww.asta.com/zh/books(中国語のサイト)。このような方法のURLはさらにSEOに効果的です。またユーザビリティもよく、URLから直感的にアクセスしているサイトを知ることができます。このようなURLアドレスはrouterを使ってlocaleを取得します(RESTの節でご紹介したrouterプラグインの実装をご参考ください): + + mux.Get("/:locale/books", listbook) + +### クライアントからロケールを設定 +ある特殊な状況下では、URLによってではなくクライアントの情報からLocaleを設定する必要があります。これらの情報はクライアントで設定された言語(ブラウザで設定されています)やユーザのIPアドレス、ユーザが登録した時に入力した所在地情報などからきているかもしれません。これらの方法はWebを基礎とするアプリケーションに比較的合っています。 + +- Accept-Language + +クライアントがリクエストした時HTTPヘッダ情報には`Accept-Language`があります。一般のクライアントはこの情報を設定しています。以下はGo言語で実装した`Accept-Languge`にしたがってロケールを設定する簡単なコードです: + + AL := r.Header.Get("Accept-Language") + if AL == "en" { + i18n.SetLocale("en") + } else if AL == "zh-CN" { + i18n.SetLocale("zh-CN") + } else if AL == "zh-TW" { + i18n.SetLocale("zh-TW") + } + +当然実際のアプリケーションでは、より厳格に判断することでロケールの設定を行う必要があるかもしれません +- IPアドレス + + もうひとつクライアントからロケールを設定する方法はユーザアクセスのIPです。対応するIPライブラリによって対応するアクセスIPをロケールにします。現在世界中で比較的よく使われているのはGeoIP Lite Countryというライブラリです。このようなロケール設定のメカニズムは非常に簡単で、IPデータベースでユーザのIPを検索するだけで国と地域が返ってきます。返された結果にしたがって対応するロケールを設定します。 + +- ユーザprofile + + 当然ユーザにあなたが提供するセレクトボックスや他の何らかの方法で対応するlocaleを設定させることもできます。ユーザの入力した情報を、このアカウントに関連するprofileに保存し、ユーザが再度ログインした時にこの設定をlocale設定にコピーします。これによってこのユーザの毎回のアクセスで自分が以前に設定したlocaleをもとにページを取得するよう保証することができます。 + +## サマリー +上のご紹介から、Localeの設定にはいくつもの方法があるとわかりました。要求の違いによって異なるLocaleの設定方法を選択する必要があります。ユーザが最もよく知る方法で我々が提供するサービスを得る事で、アプリケーションのユーザビリティを高めます。 + +## links + * [目次]() + * 前へ: [国際化とローカライズ](<10.0.md>) + * 次へ: [ローカライズリソース](<10.2.md>)